github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/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 #include "../../pkg/runtime/funcdata.h" 37 38 #include <ar.h> 39 40 enum 41 { 42 // Whether to assume that the external linker is "gold" 43 // (http://sourceware.org/ml/binutils/2008-03/msg00162.html). 44 AssumeGoldLinker = 0, 45 }; 46 47 int iconv(Fmt*); 48 49 char symname[] = SYMDEF; 50 char pkgname[] = "__.PKGDEF"; 51 char** libdir; 52 int nlibdir = 0; 53 static int maxlibdir = 0; 54 static int cout = -1; 55 56 // symbol version, incremented each time a file is loaded. 57 // version==1 is reserved for savehist. 58 enum 59 { 60 HistVersion = 1, 61 }; 62 int version = HistVersion; 63 64 // Set if we see an object compiled by the host compiler that is not 65 // from a package that is known to support internal linking mode. 66 static int externalobj = 0; 67 68 static void hostlinksetup(void); 69 70 char* goroot; 71 char* goarch; 72 char* goos; 73 char* theline; 74 75 void 76 Lflag(char *arg) 77 { 78 char **p; 79 80 if(nlibdir >= maxlibdir) { 81 if (maxlibdir == 0) 82 maxlibdir = 8; 83 else 84 maxlibdir *= 2; 85 p = erealloc(libdir, maxlibdir * sizeof(*p)); 86 libdir = p; 87 } 88 libdir[nlibdir++] = arg; 89 } 90 91 void 92 libinit(void) 93 { 94 char *race; 95 96 fmtinstall('i', iconv); 97 fmtinstall('Y', Yconv); 98 fmtinstall('Z', Zconv); 99 mywhatsys(); // get goroot, goarch, goos 100 if(strcmp(goarch, thestring) != 0) 101 print("goarch is not known: %s\n", goarch); 102 103 // add goroot to the end of the libdir list. 104 race = ""; 105 if(flag_race) 106 race = "_race"; 107 Lflag(smprint("%s/pkg/%s_%s%s", goroot, goos, goarch, race)); 108 109 // Unix doesn't like it when we write to a running (or, sometimes, 110 // recently run) binary, so remove the output file before writing it. 111 // On Windows 7, remove() can force the following create() to fail. 112 #ifndef _WIN32 113 remove(outfile); 114 #endif 115 cout = create(outfile, 1, 0775); 116 if(cout < 0) { 117 diag("cannot create %s: %r", outfile); 118 errorexit(); 119 } 120 121 if(INITENTRY == nil) { 122 INITENTRY = mal(strlen(goarch)+strlen(goos)+20); 123 if(!flag_shared) { 124 sprint(INITENTRY, "_rt0_%s_%s", goarch, goos); 125 } else { 126 sprint(INITENTRY, "_rt0_%s_%s_lib", goarch, goos); 127 } 128 } 129 lookup(INITENTRY, 0)->type = SXREF; 130 } 131 132 void 133 errorexit(void) 134 { 135 if(nerrors) { 136 if(cout >= 0) 137 remove(outfile); 138 exits("error"); 139 } 140 exits(0); 141 } 142 143 void 144 addlib(char *src, char *obj) 145 { 146 char name[1024], pname[1024], comp[256], *p; 147 int i, search; 148 149 if(histfrogp <= 0) 150 return; 151 152 search = 0; 153 if(histfrog[0]->name[1] == '/') { 154 sprint(name, ""); 155 i = 1; 156 } else 157 if(isalpha((uchar)histfrog[0]->name[1]) && histfrog[0]->name[2] == ':') { 158 strcpy(name, histfrog[0]->name+1); 159 i = 1; 160 } else 161 if(histfrog[0]->name[1] == '.') { 162 sprint(name, "."); 163 i = 0; 164 } else { 165 sprint(name, ""); 166 i = 0; 167 search = 1; 168 } 169 170 for(; i<histfrogp; i++) { 171 snprint(comp, sizeof comp, "%s", histfrog[i]->name+1); 172 for(;;) { 173 p = strstr(comp, "$O"); 174 if(p == 0) 175 break; 176 memmove(p+1, p+2, strlen(p+2)+1); 177 p[0] = thechar; 178 } 179 for(;;) { 180 p = strstr(comp, "$M"); 181 if(p == 0) 182 break; 183 if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) { 184 diag("library component too long"); 185 return; 186 } 187 memmove(p+strlen(thestring), p+2, strlen(p+2)+1); 188 memmove(p, thestring, strlen(thestring)); 189 } 190 if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) { 191 diag("library component too long"); 192 return; 193 } 194 if(i > 0 || !search) 195 strcat(name, "/"); 196 strcat(name, comp); 197 } 198 cleanname(name); 199 200 // runtime.a -> runtime 201 p = nil; 202 if(strlen(name) > 2 && name[strlen(name)-2] == '.') { 203 p = name+strlen(name)-2; 204 *p = '\0'; 205 } 206 207 // already loaded? 208 for(i=0; i<libraryp; i++) 209 if(strcmp(library[i].pkg, name) == 0) 210 return; 211 212 // runtime -> runtime.a for search 213 if(p != nil) 214 *p = '.'; 215 216 if(search) { 217 // try dot, -L "libdir", and then goroot. 218 for(i=0; i<nlibdir; i++) { 219 snprint(pname, sizeof pname, "%s/%s", libdir[i], name); 220 if(access(pname, AEXIST) >= 0) 221 break; 222 } 223 }else 224 strcpy(pname, name); 225 cleanname(pname); 226 227 /* runtime.a -> runtime */ 228 if(p != nil) 229 *p = '\0'; 230 231 if(debug['v'] > 1) 232 Bprint(&bso, "%5.2f addlib: %s %s pulls in %s\n", cputime(), obj, src, pname); 233 234 addlibpath(src, obj, pname, name); 235 } 236 237 /* 238 * add library to library list. 239 * srcref: src file referring to package 240 * objref: object file referring to package 241 * file: object file, e.g., /home/rsc/go/pkg/container/vector.a 242 * pkg: package import path, e.g. container/vector 243 */ 244 void 245 addlibpath(char *srcref, char *objref, char *file, char *pkg) 246 { 247 int i; 248 Library *l; 249 char *p; 250 251 for(i=0; i<libraryp; i++) 252 if(strcmp(file, library[i].file) == 0) 253 return; 254 255 if(debug['v'] > 1) 256 Bprint(&bso, "%5.2f addlibpath: srcref: %s objref: %s file: %s pkg: %s\n", 257 cputime(), srcref, objref, file, pkg); 258 259 if(libraryp == nlibrary){ 260 nlibrary = 50 + 2*libraryp; 261 library = erealloc(library, sizeof library[0] * nlibrary); 262 } 263 264 l = &library[libraryp++]; 265 266 p = mal(strlen(objref) + 1); 267 strcpy(p, objref); 268 l->objref = p; 269 270 p = mal(strlen(srcref) + 1); 271 strcpy(p, srcref); 272 l->srcref = p; 273 274 p = mal(strlen(file) + 1); 275 strcpy(p, file); 276 l->file = p; 277 278 p = mal(strlen(pkg) + 1); 279 strcpy(p, pkg); 280 l->pkg = p; 281 } 282 283 void 284 loadinternal(char *name) 285 { 286 char pname[1024]; 287 int i, found; 288 289 found = 0; 290 for(i=0; i<nlibdir; i++) { 291 snprint(pname, sizeof pname, "%s/%s.a", libdir[i], name); 292 if(debug['v']) 293 Bprint(&bso, "searching for %s.a in %s\n", name, pname); 294 if(access(pname, AEXIST) >= 0) { 295 addlibpath("internal", "internal", pname, name); 296 found = 1; 297 break; 298 } 299 } 300 if(!found) 301 Bprint(&bso, "warning: unable to find %s.a\n", name); 302 } 303 304 void 305 loadlib(void) 306 { 307 int i, w, x; 308 Sym *s, *gmsym; 309 310 if(flag_shared) { 311 s = lookup("runtime.islibrary", 0); 312 s->dupok = 1; 313 adduint8(s, 1); 314 } 315 316 loadinternal("runtime"); 317 if(thechar == '5') 318 loadinternal("math"); 319 if(flag_race) 320 loadinternal("runtime/race"); 321 if(linkmode == LinkExternal) { 322 // This indicates a user requested -linkmode=external. 323 // The startup code uses an import of runtime/cgo to decide 324 // whether to initialize the TLS. So give it one. This could 325 // be handled differently but it's an unusual case. 326 loadinternal("runtime/cgo"); 327 // Pretend that we really imported the package. 328 // This will do no harm if we did in fact import it. 329 s = lookup("go.importpath.runtime/cgo.", 0); 330 s->type = SDATA; 331 s->dupok = 1; 332 s->reachable = 1; 333 } 334 335 for(i=0; i<libraryp; i++) { 336 if(debug['v'] > 1) 337 Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i].file, library[i].objref); 338 iscgo |= strcmp(library[i].pkg, "runtime/cgo") == 0; 339 objfile(library[i].file, library[i].pkg); 340 } 341 342 if(linkmode == LinkAuto) { 343 if(iscgo && externalobj) 344 linkmode = LinkExternal; 345 else 346 linkmode = LinkInternal; 347 } 348 349 if(linkmode == LinkInternal) { 350 // Drop all the cgo_import_static declarations. 351 // Turns out we won't be needing them. 352 for(s = allsym; s != S; s = s->allsym) 353 if(s->type == SHOSTOBJ) { 354 // If a symbol was marked both 355 // cgo_import_static and cgo_import_dynamic, 356 // then we want to make it cgo_import_dynamic 357 // now. 358 if(s->extname != nil && s->dynimplib != nil && s->cgoexport == 0) { 359 s->type = SDYNIMPORT; 360 } else 361 s->type = 0; 362 } 363 } 364 365 gmsym = lookup("runtime.tlsgm", 0); 366 gmsym->type = STLSBSS; 367 gmsym->size = 2*PtrSize; 368 gmsym->hide = 1; 369 if(linkmode == LinkExternal && iself && HEADTYPE != Hopenbsd) 370 gmsym->reachable = 1; 371 else 372 gmsym->reachable = 0; 373 374 // Now that we know the link mode, trim the dynexp list. 375 x = CgoExportDynamic; 376 if(linkmode == LinkExternal) 377 x = CgoExportStatic; 378 w = 0; 379 for(i=0; i<ndynexp; i++) 380 if(dynexp[i]->cgoexport & x) 381 dynexp[w++] = dynexp[i]; 382 ndynexp = w; 383 384 // In internal link mode, read the host object files. 385 if(linkmode == LinkInternal) 386 hostobjs(); 387 else 388 hostlinksetup(); 389 390 // We've loaded all the code now. 391 // If there are no dynamic libraries needed, gcc disables dynamic linking. 392 // Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13) 393 // assumes that a dynamic binary always refers to at least one dynamic library. 394 // Rather than be a source of test cases for glibc, disable dynamic linking 395 // the same way that gcc would. 396 // 397 // Exception: on OS X, programs such as Shark only work with dynamic 398 // binaries, so leave it enabled on OS X (Mach-O) binaries. 399 if(!flag_shared && !havedynamic && HEADTYPE != Hdarwin) 400 debug['d'] = 1; 401 402 importcycles(); 403 } 404 405 /* 406 * look for the next file in an archive. 407 * adapted from libmach. 408 */ 409 int 410 nextar(Biobuf *bp, int off, struct ar_hdr *a) 411 { 412 int r; 413 int32 arsize; 414 char *buf; 415 416 if (off&01) 417 off++; 418 Bseek(bp, off, 0); 419 buf = Brdline(bp, '\n'); 420 r = Blinelen(bp); 421 if(buf == nil) { 422 if(r == 0) 423 return 0; 424 return -1; 425 } 426 if(r != SAR_HDR) 427 return -1; 428 memmove(a, buf, SAR_HDR); 429 if(strncmp(a->fmag, ARFMAG, sizeof a->fmag)) 430 return -1; 431 arsize = strtol(a->size, 0, 0); 432 if (arsize&1) 433 arsize++; 434 return arsize + r; 435 } 436 437 void 438 objfile(char *file, char *pkg) 439 { 440 int32 off, l; 441 Biobuf *f; 442 char magbuf[SARMAG]; 443 char pname[150]; 444 struct ar_hdr arhdr; 445 446 pkg = smprint("%i", pkg); 447 448 if(debug['v'] > 1) 449 Bprint(&bso, "%5.2f ldobj: %s (%s)\n", cputime(), file, pkg); 450 Bflush(&bso); 451 f = Bopen(file, 0); 452 if(f == nil) { 453 diag("cannot open file: %s", file); 454 errorexit(); 455 } 456 l = Bread(f, magbuf, SARMAG); 457 if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){ 458 /* load it as a regular file */ 459 l = Bseek(f, 0L, 2); 460 Bseek(f, 0L, 0); 461 ldobj(f, pkg, l, file, file, FileObj); 462 Bterm(f); 463 free(pkg); 464 return; 465 } 466 467 /* skip over __.GOSYMDEF */ 468 off = Boffset(f); 469 if((l = nextar(f, off, &arhdr)) <= 0) { 470 diag("%s: short read on archive file symbol header", file); 471 goto out; 472 } 473 if(strncmp(arhdr.name, symname, strlen(symname))) { 474 diag("%s: first entry not symbol header", file); 475 goto out; 476 } 477 off += l; 478 479 /* skip over (or process) __.PKGDEF */ 480 if((l = nextar(f, off, &arhdr)) <= 0) { 481 diag("%s: short read on archive file symbol header", file); 482 goto out; 483 } 484 if(strncmp(arhdr.name, pkgname, strlen(pkgname))) { 485 diag("%s: second entry not package header", file); 486 goto out; 487 } 488 off += l; 489 490 if(debug['u']) 491 ldpkg(f, pkg, atolwhex(arhdr.size), file, Pkgdef); 492 493 /* 494 * load all the object files from the archive now. 495 * this gives us sequential file access and keeps us 496 * from needing to come back later to pick up more 497 * objects. it breaks the usual C archive model, but 498 * this is Go, not C. the common case in Go is that 499 * we need to load all the objects, and then we throw away 500 * the individual symbols that are unused. 501 * 502 * loading every object will also make it possible to 503 * load foreign objects not referenced by __.GOSYMDEF. 504 */ 505 for(;;) { 506 l = nextar(f, off, &arhdr); 507 if(l == 0) 508 break; 509 if(l < 0) { 510 diag("%s: malformed archive", file); 511 goto out; 512 } 513 off += l; 514 515 l = SARNAME; 516 while(l > 0 && arhdr.name[l-1] == ' ') 517 l--; 518 snprint(pname, sizeof pname, "%s(%.*s)", file, utfnlen(arhdr.name, l), arhdr.name); 519 l = atolwhex(arhdr.size); 520 ldobj(f, pkg, l, pname, file, ArchiveObj); 521 } 522 523 out: 524 Bterm(f); 525 free(pkg); 526 } 527 528 static void 529 dowrite(int fd, char *p, int n) 530 { 531 int m; 532 533 while(n > 0) { 534 m = write(fd, p, n); 535 if(m <= 0) { 536 cursym = S; 537 diag("write error: %r"); 538 errorexit(); 539 } 540 n -= m; 541 p += m; 542 } 543 } 544 545 typedef struct Hostobj Hostobj; 546 547 struct Hostobj 548 { 549 void (*ld)(Biobuf*, char*, int64, char*); 550 char *pkg; 551 char *pn; 552 char *file; 553 int64 off; 554 int64 len; 555 }; 556 557 Hostobj *hostobj; 558 int nhostobj; 559 int mhostobj; 560 561 // These packages can use internal linking mode. 562 // Others trigger external mode. 563 const char *internalpkg[] = { 564 "crypto/x509", 565 "net", 566 "os/user", 567 "runtime/cgo", 568 "runtime/race" 569 }; 570 571 void 572 ldhostobj(void (*ld)(Biobuf*, char*, int64, char*), Biobuf *f, char *pkg, int64 len, char *pn, char *file) 573 { 574 int i, isinternal; 575 Hostobj *h; 576 577 isinternal = 0; 578 for(i=0; i<nelem(internalpkg); i++) { 579 if(strcmp(pkg, internalpkg[i]) == 0) { 580 isinternal = 1; 581 break; 582 } 583 } 584 585 if(!isinternal) 586 externalobj = 1; 587 588 if(nhostobj >= mhostobj) { 589 if(mhostobj == 0) 590 mhostobj = 16; 591 else 592 mhostobj *= 2; 593 hostobj = erealloc(hostobj, mhostobj*sizeof hostobj[0]); 594 } 595 h = &hostobj[nhostobj++]; 596 h->ld = ld; 597 h->pkg = estrdup(pkg); 598 h->pn = estrdup(pn); 599 h->file = estrdup(file); 600 h->off = Boffset(f); 601 h->len = len; 602 } 603 604 void 605 hostobjs(void) 606 { 607 int i; 608 Biobuf *f; 609 Hostobj *h; 610 611 for(i=0; i<nhostobj; i++) { 612 h = &hostobj[i]; 613 f = Bopen(h->file, OREAD); 614 if(f == nil) { 615 cursym = S; 616 diag("cannot reopen %s: %r", h->pn); 617 errorexit(); 618 } 619 Bseek(f, h->off, 0); 620 h->ld(f, h->pkg, h->len, h->pn); 621 Bterm(f); 622 } 623 } 624 625 // provided by lib9 626 int runcmd(char**); 627 char* mktempdir(void); 628 void removeall(char*); 629 630 static void 631 rmtemp(void) 632 { 633 removeall(tmpdir); 634 } 635 636 static void 637 hostlinksetup(void) 638 { 639 char *p; 640 641 if(linkmode != LinkExternal) 642 return; 643 644 // create temporary directory and arrange cleanup 645 if(tmpdir == nil) { 646 tmpdir = mktempdir(); 647 atexit(rmtemp); 648 } 649 650 // change our output to temporary object file 651 close(cout); 652 p = smprint("%s/go.o", tmpdir); 653 cout = create(p, 1, 0775); 654 if(cout < 0) { 655 diag("cannot create %s: %r", p); 656 errorexit(); 657 } 658 free(p); 659 } 660 661 void 662 hostlink(void) 663 { 664 char *p, **argv; 665 int c, i, w, n, argc, len; 666 Hostobj *h; 667 Biobuf *f; 668 static char buf[64<<10]; 669 670 if(linkmode != LinkExternal || nerrors > 0) 671 return; 672 673 c = 0; 674 p = extldflags; 675 while(p != nil) { 676 while(*p == ' ') 677 p++; 678 if(*p == '\0') 679 break; 680 c++; 681 p = strchr(p + 1, ' '); 682 } 683 684 argv = malloc((13+nhostobj+nldflag+c)*sizeof argv[0]); 685 argc = 0; 686 if(extld == nil) 687 extld = "gcc"; 688 argv[argc++] = extld; 689 switch(thechar){ 690 case '8': 691 argv[argc++] = "-m32"; 692 break; 693 case '6': 694 argv[argc++] = "-m64"; 695 break; 696 case '5': 697 argv[argc++] = "-marm"; 698 break; 699 } 700 if(!debug['s'] && !debug_s) { 701 argv[argc++] = "-gdwarf-2"; 702 } else { 703 argv[argc++] = "-s"; 704 } 705 if(HEADTYPE == Hdarwin) 706 argv[argc++] = "-Wl,-no_pie,-pagezero_size,4000000"; 707 708 if(iself && AssumeGoldLinker) 709 argv[argc++] = "-Wl,--rosegment"; 710 711 if(flag_shared) { 712 argv[argc++] = "-Wl,-Bsymbolic"; 713 argv[argc++] = "-shared"; 714 } 715 argv[argc++] = "-o"; 716 argv[argc++] = outfile; 717 718 if(rpath) 719 argv[argc++] = smprint("-Wl,-rpath,%s", rpath); 720 721 // Force global symbols to be exported for dlopen, etc. 722 if(iself) 723 argv[argc++] = "-rdynamic"; 724 725 // already wrote main object file 726 // copy host objects to temporary directory 727 for(i=0; i<nhostobj; i++) { 728 h = &hostobj[i]; 729 f = Bopen(h->file, OREAD); 730 if(f == nil) { 731 cursym = S; 732 diag("cannot reopen %s: %r", h->pn); 733 errorexit(); 734 } 735 Bseek(f, h->off, 0); 736 p = smprint("%s/%06d.o", tmpdir, i); 737 argv[argc++] = p; 738 w = create(p, 1, 0775); 739 if(w < 0) { 740 cursym = S; 741 diag("cannot create %s: %r", p); 742 errorexit(); 743 } 744 len = h->len; 745 while(len > 0 && (n = Bread(f, buf, sizeof buf)) > 0){ 746 if(n > len) 747 n = len; 748 dowrite(w, buf, n); 749 len -= n; 750 } 751 if(close(w) < 0) { 752 cursym = S; 753 diag("cannot write %s: %r", p); 754 errorexit(); 755 } 756 Bterm(f); 757 } 758 759 argv[argc++] = smprint("%s/go.o", tmpdir); 760 for(i=0; i<nldflag; i++) 761 argv[argc++] = ldflag[i]; 762 763 p = extldflags; 764 while(p != nil) { 765 while(*p == ' ') 766 *p++ = '\0'; 767 if(*p == '\0') 768 break; 769 argv[argc++] = p; 770 p = strchr(p + 1, ' '); 771 } 772 773 argv[argc] = nil; 774 775 quotefmtinstall(); 776 if(debug['v']) { 777 Bprint(&bso, "host link:"); 778 for(i=0; i<argc; i++) 779 Bprint(&bso, " %q", argv[i]); 780 Bprint(&bso, "\n"); 781 Bflush(&bso); 782 } 783 784 if(runcmd(argv) < 0) { 785 cursym = S; 786 diag("%s: running %s failed: %r", argv0, argv[0]); 787 errorexit(); 788 } 789 } 790 791 void 792 ldobj(Biobuf *f, char *pkg, int64 len, char *pn, char *file, int whence) 793 { 794 char *line; 795 int n, c1, c2, c3, c4; 796 uint32 magic; 797 vlong import0, import1, eof; 798 char *t; 799 800 eof = Boffset(f) + len; 801 802 pn = estrdup(pn); 803 804 c1 = BGETC(f); 805 c2 = BGETC(f); 806 c3 = BGETC(f); 807 c4 = BGETC(f); 808 Bungetc(f); 809 Bungetc(f); 810 Bungetc(f); 811 Bungetc(f); 812 813 magic = c1<<24 | c2<<16 | c3<<8 | c4; 814 if(magic == 0x7f454c46) { // \x7F E L F 815 ldhostobj(ldelf, f, pkg, len, pn, file); 816 return; 817 } 818 if((magic&~1) == 0xfeedface || (magic&~0x01000000) == 0xcefaedfe) { 819 ldhostobj(ldmacho, f, pkg, len, pn, file); 820 return; 821 } 822 if(c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86) { 823 ldhostobj(ldpe, f, pkg, len, pn, file); 824 return; 825 } 826 827 /* check the header */ 828 line = Brdline(f, '\n'); 829 if(line == nil) { 830 if(Blinelen(f) > 0) { 831 diag("%s: not an object file", pn); 832 return; 833 } 834 goto eof; 835 } 836 n = Blinelen(f) - 1; 837 line[n] = '\0'; 838 if(strncmp(line, "go object ", 10) != 0) { 839 if(strlen(pn) > 3 && strcmp(pn+strlen(pn)-3, ".go") == 0) { 840 print("%cl: input %s is not .%c file (use %cg to compile .go files)\n", thechar, pn, thechar, thechar); 841 errorexit(); 842 } 843 if(strcmp(line, thestring) == 0) { 844 // old header format: just $GOOS 845 diag("%s: stale object file", pn); 846 return; 847 } 848 diag("%s: not an object file", pn); 849 free(pn); 850 return; 851 } 852 853 // First, check that the basic goos, string, and version match. 854 t = smprint("%s %s %s ", goos, thestring, getgoversion()); 855 line[n] = ' '; 856 if(strncmp(line+10, t, strlen(t)) != 0 && !debug['f']) { 857 line[n] = '\0'; 858 diag("%s: object is [%s] expected [%s]", pn, line+10, t); 859 free(t); 860 free(pn); 861 return; 862 } 863 864 // Second, check that longer lines match each other exactly, 865 // so that the Go compiler and write additional information 866 // that must be the same from run to run. 867 line[n] = '\0'; 868 if(n-10 > strlen(t)) { 869 if(theline == nil) 870 theline = estrdup(line+10); 871 else if(strcmp(theline, line+10) != 0) { 872 line[n] = '\0'; 873 diag("%s: object is [%s] expected [%s]", pn, line+10, theline); 874 free(t); 875 free(pn); 876 return; 877 } 878 } 879 free(t); 880 line[n] = '\n'; 881 882 /* skip over exports and other info -- ends with \n!\n */ 883 import0 = Boffset(f); 884 c1 = '\n'; // the last line ended in \n 885 c2 = BGETC(f); 886 c3 = BGETC(f); 887 while(c1 != '\n' || c2 != '!' || c3 != '\n') { 888 c1 = c2; 889 c2 = c3; 890 c3 = BGETC(f); 891 if(c3 == Beof) 892 goto eof; 893 } 894 import1 = Boffset(f); 895 896 Bseek(f, import0, 0); 897 ldpkg(f, pkg, import1 - import0 - 2, pn, whence); // -2 for !\n 898 Bseek(f, import1, 0); 899 900 ldobj1(f, pkg, eof - Boffset(f), pn); 901 free(pn); 902 return; 903 904 eof: 905 diag("truncated object file: %s", pn); 906 free(pn); 907 } 908 909 Sym* 910 newsym(char *symb, int v) 911 { 912 Sym *s; 913 int l; 914 915 l = strlen(symb) + 1; 916 s = mal(sizeof(*s)); 917 if(debug['v'] > 1) 918 Bprint(&bso, "newsym %s\n", symb); 919 920 s->dynid = -1; 921 s->plt = -1; 922 s->got = -1; 923 s->name = mal(l + 1); 924 memmove(s->name, symb, l); 925 926 s->type = 0; 927 s->version = v; 928 s->value = 0; 929 s->sig = 0; 930 s->size = 0; 931 nsymbol++; 932 933 s->allsym = allsym; 934 allsym = s; 935 936 return s; 937 } 938 939 static Sym* 940 _lookup(char *symb, int v, int creat) 941 { 942 Sym *s; 943 char *p; 944 int32 h; 945 int c; 946 947 h = v; 948 for(p=symb; c = *p; p++) 949 h = h+h+h + c; 950 // not if(h < 0) h = ~h, because gcc 4.3 -O2 miscompiles it. 951 h &= 0xffffff; 952 h %= NHASH; 953 for(s = hash[h]; s != S; s = s->hash) 954 if(strcmp(s->name, symb) == 0) 955 return s; 956 if(!creat) 957 return nil; 958 959 s = newsym(symb, v); 960 s->extname = s->name; 961 s->hash = hash[h]; 962 hash[h] = s; 963 964 return s; 965 } 966 967 Sym* 968 lookup(char *name, int v) 969 { 970 return _lookup(name, v, 1); 971 } 972 973 // read-only lookup 974 Sym* 975 rlookup(char *name, int v) 976 { 977 return _lookup(name, v, 0); 978 } 979 980 void 981 copyhistfrog(char *buf, int nbuf) 982 { 983 char *p, *ep; 984 int i; 985 986 p = buf; 987 ep = buf + nbuf; 988 for(i=0; i<histfrogp; i++) { 989 p = seprint(p, ep, "%s", histfrog[i]->name+1); 990 if(i+1<histfrogp && (p == buf || p[-1] != '/')) 991 p = seprint(p, ep, "/"); 992 } 993 } 994 995 void 996 addhist(int32 line, int type) 997 { 998 Auto *u; 999 Sym *s; 1000 int i, j, k; 1001 1002 u = mal(sizeof(Auto)); 1003 s = mal(sizeof(Sym)); 1004 s->name = mal(2*(histfrogp+1) + 1); 1005 1006 u->asym = s; 1007 u->type = type; 1008 u->aoffset = line; 1009 u->link = curhist; 1010 curhist = u; 1011 1012 s->name[0] = 0; 1013 j = 1; 1014 for(i=0; i<histfrogp; i++) { 1015 k = histfrog[i]->value; 1016 s->name[j+0] = k>>8; 1017 s->name[j+1] = k; 1018 j += 2; 1019 } 1020 s->name[j] = 0; 1021 s->name[j+1] = 0; 1022 } 1023 1024 void 1025 histtoauto(void) 1026 { 1027 Auto *l; 1028 1029 while(l = curhist) { 1030 curhist = l->link; 1031 l->link = curauto; 1032 curauto = l; 1033 } 1034 } 1035 1036 void 1037 collapsefrog(Sym *s) 1038 { 1039 int i; 1040 1041 /* 1042 * bad encoding of path components only allows 1043 * MAXHIST components. if there is an overflow, 1044 * first try to collapse xxx/.. 1045 */ 1046 for(i=1; i<histfrogp; i++) 1047 if(strcmp(histfrog[i]->name+1, "..") == 0) { 1048 memmove(histfrog+i-1, histfrog+i+1, 1049 (histfrogp-i-1)*sizeof(histfrog[0])); 1050 histfrogp--; 1051 goto out; 1052 } 1053 1054 /* 1055 * next try to collapse . 1056 */ 1057 for(i=0; i<histfrogp; i++) 1058 if(strcmp(histfrog[i]->name+1, ".") == 0) { 1059 memmove(histfrog+i, histfrog+i+1, 1060 (histfrogp-i-1)*sizeof(histfrog[0])); 1061 goto out; 1062 } 1063 1064 /* 1065 * last chance, just truncate from front 1066 */ 1067 memmove(histfrog+0, histfrog+1, 1068 (histfrogp-1)*sizeof(histfrog[0])); 1069 1070 out: 1071 histfrog[histfrogp-1] = s; 1072 } 1073 1074 void 1075 nuxiinit(void) 1076 { 1077 int i, c; 1078 1079 for(i=0; i<4; i++) { 1080 c = find1(0x04030201L, i+1); 1081 if(i < 2) 1082 inuxi2[i] = c; 1083 if(i < 1) 1084 inuxi1[i] = c; 1085 inuxi4[i] = c; 1086 if(c == i) { 1087 inuxi8[i] = c; 1088 inuxi8[i+4] = c+4; 1089 } else { 1090 inuxi8[i] = c+4; 1091 inuxi8[i+4] = c; 1092 } 1093 fnuxi4[i] = c; 1094 fnuxi8[i] = c; 1095 fnuxi8[i+4] = c+4; 1096 } 1097 if(debug['v']) { 1098 Bprint(&bso, "inuxi = "); 1099 for(i=0; i<1; i++) 1100 Bprint(&bso, "%d", inuxi1[i]); 1101 Bprint(&bso, " "); 1102 for(i=0; i<2; i++) 1103 Bprint(&bso, "%d", inuxi2[i]); 1104 Bprint(&bso, " "); 1105 for(i=0; i<4; i++) 1106 Bprint(&bso, "%d", inuxi4[i]); 1107 Bprint(&bso, " "); 1108 for(i=0; i<8; i++) 1109 Bprint(&bso, "%d", inuxi8[i]); 1110 Bprint(&bso, "\nfnuxi = "); 1111 for(i=0; i<4; i++) 1112 Bprint(&bso, "%d", fnuxi4[i]); 1113 Bprint(&bso, " "); 1114 for(i=0; i<8; i++) 1115 Bprint(&bso, "%d", fnuxi8[i]); 1116 Bprint(&bso, "\n"); 1117 } 1118 Bflush(&bso); 1119 } 1120 1121 int 1122 find1(int32 l, int c) 1123 { 1124 char *p; 1125 int i; 1126 1127 p = (char*)&l; 1128 for(i=0; i<4; i++) 1129 if(*p++ == c) 1130 return i; 1131 return 0; 1132 } 1133 1134 int 1135 find2(int32 l, int c) 1136 { 1137 union { 1138 int32 l; 1139 short p[2]; 1140 } u; 1141 short *p; 1142 int i; 1143 1144 u.l = l; 1145 p = u.p; 1146 for(i=0; i<4; i+=2) { 1147 if(((*p >> 8) & 0xff) == c) 1148 return i; 1149 if((*p++ & 0xff) == c) 1150 return i+1; 1151 } 1152 return 0; 1153 } 1154 1155 int32 1156 ieeedtof(Ieee *e) 1157 { 1158 int exp; 1159 int32 v; 1160 1161 if(e->h == 0) 1162 return 0; 1163 exp = (e->h>>20) & ((1L<<11)-1L); 1164 exp -= (1L<<10) - 2L; 1165 v = (e->h & 0xfffffL) << 3; 1166 v |= (e->l >> 29) & 0x7L; 1167 if((e->l >> 28) & 1) { 1168 v++; 1169 if(v & 0x800000L) { 1170 v = (v & 0x7fffffL) >> 1; 1171 exp++; 1172 } 1173 } 1174 if(-148 <= exp && exp <= -126) { 1175 v |= 1<<23; 1176 v >>= -125 - exp; 1177 exp = -126; 1178 } 1179 else if(exp < -148 || exp >= 130) 1180 diag("double fp to single fp overflow: %.17g", ieeedtod(e)); 1181 v |= ((exp + 126) & 0xffL) << 23; 1182 v |= e->h & 0x80000000L; 1183 return v; 1184 } 1185 1186 double 1187 ieeedtod(Ieee *ieeep) 1188 { 1189 Ieee e; 1190 double fr; 1191 int exp; 1192 1193 if(ieeep->h & (1L<<31)) { 1194 e.h = ieeep->h & ~(1L<<31); 1195 e.l = ieeep->l; 1196 return -ieeedtod(&e); 1197 } 1198 if(ieeep->l == 0 && ieeep->h == 0) 1199 return 0; 1200 exp = (ieeep->h>>20) & ((1L<<11)-1L); 1201 exp -= (1L<<10) - 2L; 1202 fr = ieeep->l & ((1L<<16)-1L); 1203 fr /= 1L<<16; 1204 fr += (ieeep->l>>16) & ((1L<<16)-1L); 1205 fr /= 1L<<16; 1206 if(exp == -(1L<<10) - 2L) { 1207 fr += (ieeep->h & (1L<<20)-1L); 1208 exp++; 1209 } else 1210 fr += (ieeep->h & (1L<<20)-1L) | (1L<<20); 1211 fr /= 1L<<21; 1212 return ldexp(fr, exp); 1213 } 1214 1215 void 1216 zerosig(char *sp) 1217 { 1218 Sym *s; 1219 1220 s = lookup(sp, 0); 1221 s->sig = 0; 1222 } 1223 1224 void 1225 mywhatsys(void) 1226 { 1227 goroot = getgoroot(); 1228 goos = getgoos(); 1229 goarch = thestring; // ignore $GOARCH - we know who we are 1230 } 1231 1232 int 1233 pathchar(void) 1234 { 1235 return '/'; 1236 } 1237 1238 static uchar* hunk; 1239 static uint32 nhunk; 1240 #define NHUNK (10UL<<20) 1241 1242 void* 1243 mal(uint32 n) 1244 { 1245 void *v; 1246 1247 n = (n+7)&~7; 1248 if(n > NHUNK) { 1249 v = malloc(n); 1250 if(v == nil) { 1251 diag("out of memory"); 1252 errorexit(); 1253 } 1254 memset(v, 0, n); 1255 return v; 1256 } 1257 if(n > nhunk) { 1258 hunk = malloc(NHUNK); 1259 if(hunk == nil) { 1260 diag("out of memory"); 1261 errorexit(); 1262 } 1263 nhunk = NHUNK; 1264 } 1265 1266 v = hunk; 1267 nhunk -= n; 1268 hunk += n; 1269 1270 memset(v, 0, n); 1271 return v; 1272 } 1273 1274 void 1275 unmal(void *v, uint32 n) 1276 { 1277 n = (n+7)&~7; 1278 if(hunk - n == v) { 1279 hunk -= n; 1280 nhunk += n; 1281 } 1282 } 1283 1284 // Copied from ../gc/subr.c:/^pathtoprefix; must stay in sync. 1285 /* 1286 * Convert raw string to the prefix that will be used in the symbol table. 1287 * Invalid bytes turn into %xx. Right now the only bytes that need 1288 * escaping are %, ., and ", but we escape all control characters too. 1289 * 1290 * Must be same as ../gc/subr.c:/^pathtoprefix. 1291 */ 1292 static char* 1293 pathtoprefix(char *s) 1294 { 1295 static char hex[] = "0123456789abcdef"; 1296 char *p, *r, *w, *l; 1297 int n; 1298 1299 // find first character past the last slash, if any. 1300 l = s; 1301 for(r=s; *r; r++) 1302 if(*r == '/') 1303 l = r+1; 1304 1305 // check for chars that need escaping 1306 n = 0; 1307 for(r=s; *r; r++) 1308 if(*r <= ' ' || (*r == '.' && r >= l) || *r == '%' || *r == '"' || *r >= 0x7f) 1309 n++; 1310 1311 // quick exit 1312 if(n == 0) 1313 return s; 1314 1315 // escape 1316 p = mal((r-s)+1+2*n); 1317 for(r=s, w=p; *r; r++) { 1318 if(*r <= ' ' || (*r == '.' && r >= l) || *r == '%' || *r == '"' || *r >= 0x7f) { 1319 *w++ = '%'; 1320 *w++ = hex[(*r>>4)&0xF]; 1321 *w++ = hex[*r&0xF]; 1322 } else 1323 *w++ = *r; 1324 } 1325 *w = '\0'; 1326 return p; 1327 } 1328 1329 int 1330 iconv(Fmt *fp) 1331 { 1332 char *p; 1333 1334 p = va_arg(fp->args, char*); 1335 if(p == nil) { 1336 fmtstrcpy(fp, "<nil>"); 1337 return 0; 1338 } 1339 p = pathtoprefix(p); 1340 fmtstrcpy(fp, p); 1341 return 0; 1342 } 1343 1344 void 1345 mangle(char *file) 1346 { 1347 fprint(2, "%s: mangled input file\n", file); 1348 errorexit(); 1349 } 1350 1351 Section* 1352 addsection(Segment *seg, char *name, int rwx) 1353 { 1354 Section **l; 1355 Section *sect; 1356 1357 for(l=&seg->sect; *l; l=&(*l)->next) 1358 ; 1359 sect = mal(sizeof *sect); 1360 sect->rwx = rwx; 1361 sect->name = name; 1362 sect->seg = seg; 1363 sect->align = PtrSize; // everything is at least pointer-aligned 1364 *l = sect; 1365 return sect; 1366 } 1367 1368 void 1369 addvarint(Sym *s, uint32 val) 1370 { 1371 int32 n; 1372 uint32 v; 1373 uchar *p; 1374 1375 n = 0; 1376 for(v = val; v >= 0x80; v >>= 7) 1377 n++; 1378 n++; 1379 1380 symgrow(s, s->np+n); 1381 1382 p = s->p + s->np - n; 1383 for(v = val; v >= 0x80; v >>= 7) 1384 *p++ = v | 0x80; 1385 *p = v; 1386 } 1387 1388 // funcpctab appends to dst a pc-value table mapping the code in func to the values 1389 // returned by valfunc parameterized by arg. The invocation of valfunc to update the 1390 // current value is, for each p, 1391 // 1392 // val = valfunc(func, val, p, 0, arg); 1393 // record val as value at p->pc; 1394 // val = valfunc(func, val, p, 1, arg); 1395 // 1396 // where func is the function, val is the current value, p is the instruction being 1397 // considered, and arg can be used to further parameterize valfunc. 1398 void 1399 funcpctab(Sym *dst, Sym *func, char *desc, int32 (*valfunc)(Sym*, int32, Prog*, int32, int32), int32 arg) 1400 { 1401 int dbg, i, start; 1402 int32 oldval, val, started; 1403 uint32 delta; 1404 vlong pc; 1405 Prog *p; 1406 1407 // To debug a specific function, uncomment second line and change name. 1408 dbg = 0; 1409 //dbg = strcmp(func->name, "main.main") == 0; 1410 1411 debug['O'] += dbg; 1412 1413 start = dst->np; 1414 1415 if(debug['O']) 1416 Bprint(&bso, "funcpctab %s -> %s [valfunc=%s]\n", func->name, dst->name, desc); 1417 1418 val = -1; 1419 oldval = val; 1420 pc = func->value; 1421 1422 if(debug['O']) 1423 Bprint(&bso, "%6llux %6d %P\n", pc, val, func->text); 1424 1425 started = 0; 1426 for(p=func->text; p != P; p = p->link) { 1427 // Update val. If it's not changing, keep going. 1428 val = valfunc(func, val, p, 0, arg); 1429 if(val == oldval && started) { 1430 val = valfunc(func, val, p, 1, arg); 1431 if(debug['O']) 1432 Bprint(&bso, "%6llux %6s %P\n", (vlong)p->pc, "", p); 1433 continue; 1434 } 1435 1436 // If the pc of the next instruction is the same as the 1437 // pc of this instruction, this instruction is not a real 1438 // instruction. Keep going, so that we only emit a delta 1439 // for a true instruction boundary in the program. 1440 if(p->link && p->link->pc == p->pc) { 1441 val = valfunc(func, val, p, 1, arg); 1442 if(debug['O']) 1443 Bprint(&bso, "%6llux %6s %P\n", (vlong)p->pc, "", p); 1444 continue; 1445 } 1446 1447 // The table is a sequence of (value, pc) pairs, where each 1448 // pair states that the given value is in effect from the current position 1449 // up to the given pc, which becomes the new current position. 1450 // To generate the table as we scan over the program instructions, 1451 // we emit a "(value" when pc == func->value, and then 1452 // each time we observe a change in value we emit ", pc) (value". 1453 // When the scan is over, we emit the closing ", pc)". 1454 // 1455 // The table is delta-encoded. The value deltas are signed and 1456 // transmitted in zig-zag form, where a complement bit is placed in bit 0, 1457 // and the pc deltas are unsigned. Both kinds of deltas are sent 1458 // as variable-length little-endian base-128 integers, 1459 // where the 0x80 bit indicates that the integer continues. 1460 1461 if(debug['O']) 1462 Bprint(&bso, "%6llux %6d %P\n", (vlong)p->pc, val, p); 1463 1464 if(started) { 1465 addvarint(dst, (p->pc - pc) / MINLC); 1466 pc = p->pc; 1467 } 1468 delta = val - oldval; 1469 if(delta>>31) 1470 delta = 1 | ~(delta<<1); 1471 else 1472 delta <<= 1; 1473 addvarint(dst, delta); 1474 oldval = val; 1475 started = 1; 1476 val = valfunc(func, val, p, 1, arg); 1477 } 1478 1479 if(started) { 1480 if(debug['O']) 1481 Bprint(&bso, "%6llux done\n", (vlong)func->value+func->size); 1482 addvarint(dst, (func->value+func->size - pc) / MINLC); 1483 addvarint(dst, 0); // terminator 1484 } 1485 1486 if(debug['O']) { 1487 Bprint(&bso, "wrote %d bytes\n", dst->np - start); 1488 for(i=start; i<dst->np; i++) 1489 Bprint(&bso, " %02ux", dst->p[i]); 1490 Bprint(&bso, "\n"); 1491 } 1492 1493 debug['O'] -= dbg; 1494 } 1495 1496 // pctofileline computes either the file number (arg == 0) 1497 // or the line number (arg == 1) to use at p. 1498 // Because p->lineno applies to p, phase == 0 (before p) 1499 // takes care of the update. 1500 static int32 1501 pctofileline(Sym *sym, int32 oldval, Prog *p, int32 phase, int32 arg) 1502 { 1503 int32 f, l; 1504 1505 if(p->as == ATEXT || p->as == ANOP || p->as == AUSEFIELD || p->line == 0 || phase == 1) 1506 return oldval; 1507 getline(sym->hist, p->line, &f, &l); 1508 if(f == 0) { 1509 // print("getline failed for %s %P\n", cursym->name, p); 1510 return oldval; 1511 } 1512 if(arg == 0) 1513 return f; 1514 return l; 1515 } 1516 1517 // pctospadj computes the sp adjustment in effect. 1518 // It is oldval plus any adjustment made by p itself. 1519 // The adjustment by p takes effect only after p, so we 1520 // apply the change during phase == 1. 1521 static int32 1522 pctospadj(Sym *sym, int32 oldval, Prog *p, int32 phase, int32 arg) 1523 { 1524 USED(arg); 1525 USED(sym); 1526 1527 if(oldval == -1) // starting 1528 oldval = 0; 1529 if(phase == 0) 1530 return oldval; 1531 if(oldval + p->spadj < -10000 || oldval + p->spadj > 1100000000) { 1532 diag("overflow in spadj: %d + %d = %d", oldval, p->spadj, oldval + p->spadj); 1533 errorexit(); 1534 } 1535 return oldval + p->spadj; 1536 } 1537 1538 // pctopcdata computes the pcdata value in effect at p. 1539 // A PCDATA instruction sets the value in effect at future 1540 // non-PCDATA instructions. 1541 // Since PCDATA instructions have no width in the final code, 1542 // it does not matter which phase we use for the update. 1543 static int32 1544 pctopcdata(Sym *sym, int32 oldval, Prog *p, int32 phase, int32 arg) 1545 { 1546 USED(sym); 1547 1548 if(phase == 0 || p->as != APCDATA || p->from.offset != arg) 1549 return oldval; 1550 if((int32)p->to.offset != p->to.offset) { 1551 diag("overflow in PCDATA instruction: %P", p); 1552 errorexit(); 1553 } 1554 return p->to.offset; 1555 } 1556 1557 #define LOG 5 1558 void 1559 mkfwd(void) 1560 { 1561 Prog *p; 1562 int i; 1563 int32 dwn[LOG], cnt[LOG]; 1564 Prog *lst[LOG]; 1565 1566 for(i=0; i<LOG; i++) { 1567 if(i == 0) 1568 cnt[i] = 1; 1569 else 1570 cnt[i] = LOG * cnt[i-1]; 1571 dwn[i] = 1; 1572 lst[i] = P; 1573 } 1574 i = 0; 1575 for(cursym = textp; cursym != nil; cursym = cursym->next) { 1576 for(p = cursym->text; p != P; p = p->link) { 1577 if(p->link == P) { 1578 if(cursym->next) 1579 p->forwd = cursym->next->text; 1580 break; 1581 } 1582 i--; 1583 if(i < 0) 1584 i = LOG-1; 1585 p->forwd = P; 1586 dwn[i]--; 1587 if(dwn[i] <= 0) { 1588 dwn[i] = cnt[i]; 1589 if(lst[i] != P) 1590 lst[i]->forwd = p; 1591 lst[i] = p; 1592 } 1593 } 1594 } 1595 } 1596 1597 uint16 1598 le16(uchar *b) 1599 { 1600 return b[0] | b[1]<<8; 1601 } 1602 1603 uint32 1604 le32(uchar *b) 1605 { 1606 return b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24; 1607 } 1608 1609 uint64 1610 le64(uchar *b) 1611 { 1612 return le32(b) | (uint64)le32(b+4)<<32; 1613 } 1614 1615 uint16 1616 be16(uchar *b) 1617 { 1618 return b[0]<<8 | b[1]; 1619 } 1620 1621 uint32 1622 be32(uchar *b) 1623 { 1624 return b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3]; 1625 } 1626 1627 uint64 1628 be64(uchar *b) 1629 { 1630 return (uvlong)be32(b)<<32 | be32(b+4); 1631 } 1632 1633 Endian be = { be16, be32, be64 }; 1634 Endian le = { le16, le32, le64 }; 1635 1636 typedef struct Chain Chain; 1637 struct Chain 1638 { 1639 Sym *sym; 1640 Chain *up; 1641 int limit; // limit on entry to sym 1642 }; 1643 1644 static int stkcheck(Chain*, int); 1645 static void stkprint(Chain*, int); 1646 static void stkbroke(Chain*, int); 1647 static Sym *morestack; 1648 static Sym *newstack; 1649 1650 enum 1651 { 1652 HasLinkRegister = (thechar == '5'), 1653 CallSize = (!HasLinkRegister)*PtrSize, // bytes of stack required for a call 1654 }; 1655 1656 void 1657 dostkcheck(void) 1658 { 1659 Chain ch; 1660 Sym *s; 1661 1662 morestack = lookup("runtime.morestack", 0); 1663 newstack = lookup("runtime.newstack", 0); 1664 1665 // First the nosplits on their own. 1666 for(s = textp; s != nil; s = s->next) { 1667 if(s->text == nil || s->text->link == nil || (s->text->textflag & NOSPLIT) == 0) 1668 continue; 1669 cursym = s; 1670 ch.up = nil; 1671 ch.sym = s; 1672 ch.limit = StackLimit - CallSize; 1673 stkcheck(&ch, 0); 1674 s->stkcheck = 1; 1675 } 1676 1677 // Check calling contexts. 1678 // Some nosplits get called a little further down, 1679 // like newproc and deferproc. We could hard-code 1680 // that knowledge but it's more robust to look at 1681 // the actual call sites. 1682 for(s = textp; s != nil; s = s->next) { 1683 if(s->text == nil || s->text->link == nil || (s->text->textflag & NOSPLIT) != 0) 1684 continue; 1685 cursym = s; 1686 ch.up = nil; 1687 ch.sym = s; 1688 ch.limit = StackLimit - CallSize; 1689 stkcheck(&ch, 0); 1690 } 1691 } 1692 1693 static int 1694 stkcheck(Chain *up, int depth) 1695 { 1696 Chain ch, ch1; 1697 Prog *p; 1698 Sym *s; 1699 int limit, prolog; 1700 1701 limit = up->limit; 1702 s = up->sym; 1703 p = s->text; 1704 1705 // Small optimization: don't repeat work at top. 1706 if(s->stkcheck && limit == StackLimit-CallSize) 1707 return 0; 1708 1709 if(depth > 100) { 1710 diag("nosplit stack check too deep"); 1711 stkbroke(up, 0); 1712 return -1; 1713 } 1714 1715 if(p == nil || p->link == nil) { 1716 // external function. 1717 // should never be called directly. 1718 // only diagnose the direct caller. 1719 if(depth == 1) 1720 diag("call to external function %s", s->name); 1721 return -1; 1722 } 1723 1724 if(limit < 0) { 1725 stkbroke(up, limit); 1726 return -1; 1727 } 1728 1729 // morestack looks like it calls functions, 1730 // but it switches the stack pointer first. 1731 if(s == morestack) 1732 return 0; 1733 1734 ch.up = up; 1735 prolog = (s->text->textflag & NOSPLIT) == 0; 1736 for(p = s->text; p != P; p = p->link) { 1737 limit -= p->spadj; 1738 if(prolog && p->spadj != 0) { 1739 // The first stack adjustment in a function with a 1740 // split-checking prologue marks the end of the 1741 // prologue. Assuming the split check is correct, 1742 // after the adjustment there should still be at least 1743 // StackLimit bytes available below the stack pointer. 1744 // If this is not the top call in the chain, no need 1745 // to duplicate effort, so just stop. 1746 if(depth > 0) 1747 return 0; 1748 prolog = 0; 1749 limit = StackLimit; 1750 } 1751 if(limit < 0) { 1752 stkbroke(up, limit); 1753 return -1; 1754 } 1755 if(iscall(p)) { 1756 limit -= CallSize; 1757 ch.limit = limit; 1758 if(p->to.type == D_BRANCH) { 1759 // Direct call. 1760 ch.sym = p->to.sym; 1761 if(stkcheck(&ch, depth+1) < 0) 1762 return -1; 1763 } else { 1764 // Indirect call. Assume it is a splitting function, 1765 // so we have to make sure it can call morestack. 1766 limit -= CallSize; 1767 ch.sym = nil; 1768 ch1.limit = limit; 1769 ch1.up = &ch; 1770 ch1.sym = morestack; 1771 if(stkcheck(&ch1, depth+2) < 0) 1772 return -1; 1773 limit += CallSize; 1774 } 1775 limit += CallSize; 1776 } 1777 1778 } 1779 return 0; 1780 } 1781 1782 static void 1783 stkbroke(Chain *ch, int limit) 1784 { 1785 diag("nosplit stack overflow"); 1786 stkprint(ch, limit); 1787 } 1788 1789 static void 1790 stkprint(Chain *ch, int limit) 1791 { 1792 char *name; 1793 1794 if(ch->sym) 1795 name = ch->sym->name; 1796 else 1797 name = "function pointer"; 1798 1799 if(ch->up == nil) { 1800 // top of chain. ch->sym != nil. 1801 if(ch->sym->text->textflag & NOSPLIT) 1802 print("\t%d\tassumed on entry to %s\n", ch->limit, name); 1803 else 1804 print("\t%d\tguaranteed after split check in %s\n", ch->limit, name); 1805 } else { 1806 stkprint(ch->up, ch->limit + (!HasLinkRegister)*PtrSize); 1807 if(!HasLinkRegister) 1808 print("\t%d\ton entry to %s\n", ch->limit, name); 1809 } 1810 if(ch->limit != limit) 1811 print("\t%d\tafter %s uses %d\n", limit, name, ch->limit - limit); 1812 } 1813 1814 int 1815 headtype(char *name) 1816 { 1817 int i; 1818 1819 for(i=0; headers[i].name; i++) 1820 if(strcmp(name, headers[i].name) == 0) { 1821 headstring = headers[i].name; 1822 return headers[i].val; 1823 } 1824 fprint(2, "unknown header type -H %s\n", name); 1825 errorexit(); 1826 return -1; // not reached 1827 } 1828 1829 char* 1830 headstr(int v) 1831 { 1832 static char buf[20]; 1833 int i; 1834 1835 for(i=0; headers[i].name; i++) 1836 if(v == headers[i].val) 1837 return headers[i].name; 1838 snprint(buf, sizeof buf, "%d", v); 1839 return buf; 1840 } 1841 1842 void 1843 undef(void) 1844 { 1845 Sym *s; 1846 1847 for(s = allsym; s != S; s = s->allsym) 1848 if(s->type == SXREF) 1849 diag("%s(%d): not defined", s->name, s->version); 1850 } 1851 1852 int 1853 Yconv(Fmt *fp) 1854 { 1855 Sym *s; 1856 Fmt fmt; 1857 int i; 1858 char *str; 1859 1860 s = va_arg(fp->args, Sym*); 1861 if (s == S) { 1862 fmtprint(fp, "<nil>"); 1863 } else { 1864 fmtstrinit(&fmt); 1865 fmtprint(&fmt, "%s @0x%08llx [%lld]", s->name, (vlong)s->value, (vlong)s->size); 1866 for (i = 0; i < s->size; i++) { 1867 if (!(i%8)) fmtprint(&fmt, "\n\t0x%04x ", i); 1868 fmtprint(&fmt, "%02x ", s->p[i]); 1869 } 1870 fmtprint(&fmt, "\n"); 1871 for (i = 0; i < s->nr; i++) { 1872 fmtprint(&fmt, "\t0x%04x[%x] %d %s[%llx]\n", 1873 s->r[i].off, 1874 s->r[i].siz, 1875 s->r[i].type, 1876 s->r[i].sym->name, 1877 (vlong)s->r[i].add); 1878 } 1879 str = fmtstrflush(&fmt); 1880 fmtstrcpy(fp, str); 1881 free(str); 1882 } 1883 1884 return 0; 1885 } 1886 1887 vlong coutpos; 1888 1889 void 1890 cflush(void) 1891 { 1892 int n; 1893 1894 if(cbpmax < cbp) 1895 cbpmax = cbp; 1896 n = cbpmax - buf.cbuf; 1897 dowrite(cout, buf.cbuf, n); 1898 coutpos += n; 1899 cbp = buf.cbuf; 1900 cbc = sizeof(buf.cbuf); 1901 cbpmax = cbp; 1902 } 1903 1904 vlong 1905 cpos(void) 1906 { 1907 return coutpos + cbp - buf.cbuf; 1908 } 1909 1910 void 1911 cseek(vlong p) 1912 { 1913 vlong start; 1914 int delta; 1915 1916 if(cbpmax < cbp) 1917 cbpmax = cbp; 1918 start = coutpos; 1919 if(start <= p && p <= start+(cbpmax - buf.cbuf)) { 1920 //print("cseek %lld in [%lld,%lld] (%lld)\n", p, start, start+sizeof(buf.cbuf), cpos()); 1921 delta = p - (start + cbp - buf.cbuf); 1922 cbp += delta; 1923 cbc -= delta; 1924 //print("now at %lld\n", cpos()); 1925 return; 1926 } 1927 1928 cflush(); 1929 seek(cout, p, 0); 1930 coutpos = p; 1931 } 1932 1933 void 1934 cwrite(void *buf, int n) 1935 { 1936 cflush(); 1937 if(n <= 0) 1938 return; 1939 dowrite(cout, buf, n); 1940 coutpos += n; 1941 } 1942 1943 void 1944 usage(void) 1945 { 1946 fprint(2, "usage: %cl [options] main.%c\n", thechar, thechar); 1947 flagprint(2); 1948 exits("usage"); 1949 } 1950 1951 void 1952 setheadtype(char *s) 1953 { 1954 HEADTYPE = headtype(s); 1955 } 1956 1957 void 1958 setinterp(char *s) 1959 { 1960 debug['I'] = 1; // denote cmdline interpreter override 1961 interpreter = s; 1962 } 1963 1964 void 1965 doversion(void) 1966 { 1967 print("%cl version %s\n", thechar, getgoversion()); 1968 errorexit(); 1969 } 1970 1971 void 1972 genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*)) 1973 { 1974 Auto *a; 1975 Sym *s; 1976 int32 off; 1977 1978 // These symbols won't show up in the first loop below because we 1979 // skip STEXT symbols. Normal STEXT symbols are emitted by walking textp. 1980 s = lookup("text", 0); 1981 if(s->type == STEXT) 1982 put(s, s->name, 'T', s->value, s->size, s->version, 0); 1983 s = lookup("etext", 0); 1984 if(s->type == STEXT) 1985 put(s, s->name, 'T', s->value, s->size, s->version, 0); 1986 1987 for(s=allsym; s!=S; s=s->allsym) { 1988 if(s->hide || (s->name[0] == '.' && s->version == 0 && strcmp(s->name, ".rathole") != 0)) 1989 continue; 1990 switch(s->type&SMASK) { 1991 case SCONST: 1992 case SRODATA: 1993 case SSYMTAB: 1994 case SPCLNTAB: 1995 case SDATA: 1996 case SNOPTRDATA: 1997 case SELFROSECT: 1998 case SMACHOGOT: 1999 case STYPE: 2000 case SSTRING: 2001 case SGOSTRING: 2002 case SWINDOWS: 2003 if(!s->reachable) 2004 continue; 2005 put(s, s->name, 'D', symaddr(s), s->size, s->version, s->gotype); 2006 continue; 2007 2008 case SBSS: 2009 case SNOPTRBSS: 2010 if(!s->reachable) 2011 continue; 2012 if(s->np > 0) 2013 diag("%s should not be bss (size=%d type=%d special=%d)", s->name, (int)s->np, s->type, s->special); 2014 put(s, s->name, 'B', symaddr(s), s->size, s->version, s->gotype); 2015 continue; 2016 2017 case SFILE: 2018 put(nil, s->name, 'f', s->value, 0, s->version, 0); 2019 continue; 2020 } 2021 } 2022 2023 for(s = textp; s != nil; s = s->next) { 2024 if(s->text == nil) 2025 continue; 2026 2027 put(s, s->name, 'T', s->value, s->size, s->version, s->gotype); 2028 2029 for(a=s->autom; a; a=a->link) { 2030 // Emit a or p according to actual offset, even if label is wrong. 2031 // This avoids negative offsets, which cannot be encoded. 2032 if(a->type != D_AUTO && a->type != D_PARAM) 2033 continue; 2034 2035 // compute offset relative to FP 2036 if(a->type == D_PARAM) 2037 off = a->aoffset; 2038 else 2039 off = a->aoffset - PtrSize; 2040 2041 // FP 2042 if(off >= 0) { 2043 put(nil, a->asym->name, 'p', off, 0, 0, a->gotype); 2044 continue; 2045 } 2046 2047 // SP 2048 if(off <= -PtrSize) { 2049 put(nil, a->asym->name, 'a', -(off+PtrSize), 0, 0, a->gotype); 2050 continue; 2051 } 2052 2053 // Otherwise, off is addressing the saved program counter. 2054 // Something underhanded is going on. Say nothing. 2055 } 2056 } 2057 if(debug['v'] || debug['n']) 2058 Bprint(&bso, "%5.2f symsize = %ud\n", cputime(), symsize); 2059 Bflush(&bso); 2060 } 2061 2062 char* 2063 estrdup(char *p) 2064 { 2065 p = strdup(p); 2066 if(p == nil) { 2067 cursym = S; 2068 diag("out of memory"); 2069 errorexit(); 2070 } 2071 return p; 2072 } 2073 2074 void* 2075 erealloc(void *p, long n) 2076 { 2077 p = realloc(p, n); 2078 if(p == nil) { 2079 cursym = S; 2080 diag("out of memory"); 2081 errorexit(); 2082 } 2083 return p; 2084 } 2085 2086 // Saved history stacks encountered while reading archives. 2087 // Keeping them allows us to answer virtual lineno -> file:line 2088 // queries. 2089 // 2090 // The history stack is a complex data structure, described best at the 2091 // bottom of http://plan9.bell-labs.com/magic/man2html/6/a.out. 2092 // One of the key benefits of interpreting it here is that the runtime 2093 // does not have to. Perhaps some day the compilers could generate 2094 // a simpler linker input too. 2095 2096 struct Hist 2097 { 2098 int32 line; 2099 int32 off; 2100 Sym *file; 2101 }; 2102 2103 static Hist *histcopy; 2104 static Hist *hist; 2105 static int32 nhist; 2106 static int32 maxhist; 2107 static int32 histdepth; 2108 static int32 nhistfile; 2109 static Sym *filesyms; 2110 2111 // savehist processes a single line, off history directive 2112 // found in the input object file. 2113 void 2114 savehist(int32 line, int32 off) 2115 { 2116 char tmp[1024]; 2117 Sym *file; 2118 Hist *h; 2119 2120 // NOTE(rsc): We used to do the copyhistfrog first and this 2121 // condition was if(tmp[0] != '\0') to check for an empty string, 2122 // implying that histfrogp == 0, implying that this is a history pop. 2123 // However, on Windows in the misc/cgo test, the linker is 2124 // presented with an ANAME corresponding to an empty string, 2125 // that ANAME ends up being the only histfrog, and thus we have 2126 // a situation where histfrogp > 0 (not a pop) but the path we find 2127 // is the empty string. Really that shouldn't happen, but it doesn't 2128 // seem to be bothering anyone yet, and it's easier to fix the condition 2129 // to test histfrogp than to track down where that empty string is 2130 // coming from. Probably it is coming from go tool pack's P command. 2131 if(histfrogp > 0) { 2132 tmp[0] = '\0'; 2133 copyhistfrog(tmp, sizeof tmp); 2134 file = lookup(tmp, HistVersion); 2135 if(file->type != SFILEPATH) { 2136 file->value = ++nhistfile; 2137 file->type = SFILEPATH; 2138 file->next = filesyms; 2139 filesyms = file; 2140 } 2141 } else 2142 file = nil; 2143 2144 if(file != nil && line == 1 && off == 0) { 2145 // start of new stack 2146 if(histdepth != 0) { 2147 diag("history stack phase error: unexpected start of new stack depth=%d file=%s", histdepth, tmp); 2148 errorexit(); 2149 } 2150 nhist = 0; 2151 histcopy = nil; 2152 } 2153 2154 if(nhist >= maxhist) { 2155 if(maxhist == 0) 2156 maxhist = 1; 2157 maxhist *= 2; 2158 hist = erealloc(hist, maxhist*sizeof hist[0]); 2159 } 2160 h = &hist[nhist++]; 2161 h->line = line; 2162 h->off = off; 2163 h->file = file; 2164 2165 if(file != nil) { 2166 if(off == 0) 2167 histdepth++; 2168 } else { 2169 if(off != 0) { 2170 diag("history stack phase error: bad offset in pop"); 2171 errorexit(); 2172 } 2173 histdepth--; 2174 } 2175 } 2176 2177 // gethist returns the history stack currently in effect. 2178 // The result is valid indefinitely. 2179 Hist* 2180 gethist(void) 2181 { 2182 if(histcopy == nil) { 2183 if(nhist == 0) 2184 return nil; 2185 histcopy = mal((nhist+1)*sizeof hist[0]); 2186 memmove(histcopy, hist, nhist*sizeof hist[0]); 2187 histcopy[nhist].line = -1; 2188 } 2189 return histcopy; 2190 } 2191 2192 typedef struct Hstack Hstack; 2193 struct Hstack 2194 { 2195 Hist *h; 2196 int delta; 2197 }; 2198 2199 // getline sets *f to the file number and *l to the line number 2200 // of the virtual line number line according to the history stack h. 2201 void 2202 getline(Hist *h, int32 line, int32 *f, int32 *l) 2203 { 2204 Hstack stk[100]; 2205 int nstk, start; 2206 Hist *top, *h0; 2207 static Hist *lasth; 2208 static int32 laststart, lastend, lastdelta, lastfile; 2209 2210 h0 = h; 2211 *f = 0; 2212 *l = 0; 2213 start = 0; 2214 if(h == nil || line == 0) { 2215 print("%s: getline: h=%p line=%d\n", cursym->name, h, line); 2216 return; 2217 } 2218 2219 // Cache span used during last lookup, so that sequential 2220 // translation of line numbers in compiled code is efficient. 2221 if(!debug['O'] && lasth == h && laststart <= line && line < lastend) { 2222 *f = lastfile; 2223 *l = line - lastdelta; 2224 return; 2225 } 2226 2227 if(debug['O']) 2228 print("getline %d laststart=%d lastend=%d\n", line, laststart, lastend); 2229 2230 nstk = 0; 2231 for(; h->line != -1; h++) { 2232 if(debug['O']) 2233 print("\t%s %d %d\n", h->file ? h->file->name : "?", h->line, h->off); 2234 2235 if(h->line > line) { 2236 if(nstk == 0) { 2237 diag("history stack phase error: empty stack at line %d", (int)line); 2238 errorexit(); 2239 } 2240 top = stk[nstk-1].h; 2241 lasth = h; 2242 lastfile = top->file->value; 2243 laststart = start; 2244 lastend = h->line; 2245 lastdelta = stk[nstk-1].delta; 2246 *f = lastfile; 2247 *l = line - lastdelta; 2248 if(debug['O']) 2249 print("\tgot %d %d [%d %d %d]\n", *f, *l, laststart, lastend, lastdelta); 2250 return; 2251 } 2252 if(h->file == nil) { 2253 // pop included file 2254 if(nstk == 0) { 2255 diag("history stack phase error: stack underflow"); 2256 errorexit(); 2257 } 2258 nstk--; 2259 if(nstk > 0) 2260 stk[nstk-1].delta += h->line - stk[nstk].h->line; 2261 start = h->line; 2262 } else if(h->off == 0) { 2263 // push included file 2264 if(nstk >= nelem(stk)) { 2265 diag("history stack phase error: stack overflow"); 2266 errorexit(); 2267 } 2268 start = h->line; 2269 stk[nstk].h = h; 2270 stk[nstk].delta = h->line - 1; 2271 nstk++; 2272 } else { 2273 // #line directive 2274 if(nstk == 0) { 2275 diag("history stack phase error: stack underflow"); 2276 errorexit(); 2277 } 2278 stk[nstk-1].h = h; 2279 stk[nstk-1].delta = h->line - h->off; 2280 start = h->line; 2281 } 2282 if(debug['O']) 2283 print("\t\tnstk=%d delta=%d\n", nstk, stk[nstk].delta); 2284 } 2285 2286 diag("history stack phase error: cannot find line for %d", line); 2287 nstk = 0; 2288 for(h = h0; h->line != -1; h++) { 2289 print("\t%d %d %s\n", h->line, h->off, h->file ? h->file->name : ""); 2290 if(h->file == nil) 2291 nstk--; 2292 else if(h->off == 0) 2293 nstk++; 2294 } 2295 } 2296 2297 // defgostring returns a symbol for the Go string containing text. 2298 Sym* 2299 defgostring(char *text) 2300 { 2301 char *p; 2302 Sym *s; 2303 int32 n; 2304 2305 n = strlen(text); 2306 p = smprint("go.string.\"%Z\"", text); 2307 s = lookup(p, 0); 2308 if(s->size == 0) { 2309 s->type = SGOSTRING; 2310 s->reachable = 1; 2311 s->size = 2*PtrSize+n; 2312 symgrow(s, 2*PtrSize+n); 2313 setaddrplus(s, 0, s, 2*PtrSize); 2314 setuintxx(s, PtrSize, n, PtrSize); 2315 memmove(s->p+2*PtrSize, text, n); 2316 } 2317 s->reachable = 1; 2318 return s; 2319 } 2320 2321 // addpctab appends to f a pc-value table, storing its offset at off. 2322 // The pc-value table is for func and reports the value of valfunc 2323 // parameterized by arg. 2324 static int32 2325 addpctab(Sym *f, int32 off, Sym *func, char *desc, int32 (*valfunc)(Sym*, int32, Prog*, int32, int32), int32 arg) 2326 { 2327 int32 start; 2328 2329 start = f->np; 2330 funcpctab(f, func, desc, valfunc, arg); 2331 if(start == f->np) { 2332 // no table 2333 return setuint32(f, off, 0); 2334 } 2335 if((int32)start > (int32)f->np) { 2336 diag("overflow adding pc-table: symbol too large"); 2337 errorexit(); 2338 } 2339 return setuint32(f, off, start); 2340 } 2341 2342 static int32 2343 ftabaddstring(Sym *ftab, char *s) 2344 { 2345 int32 n, start; 2346 2347 n = strlen(s)+1; 2348 start = ftab->np; 2349 symgrow(ftab, start+n+1); 2350 strcpy((char*)ftab->p + start, s); 2351 ftab->np += n+1; 2352 return start; 2353 } 2354 2355 // pclntab initializes the pclntab symbol with 2356 // runtime function and file name information. 2357 void 2358 pclntab(void) 2359 { 2360 Prog *p; 2361 int32 i, n, nfunc, start, funcstart; 2362 uint32 *havepc, *havefunc; 2363 Sym *ftab, *s; 2364 int32 npcdata, nfuncdata, off, end; 2365 int64 funcdata_bytes; 2366 2367 funcdata_bytes = 0; 2368 ftab = lookup("pclntab", 0); 2369 ftab->type = SPCLNTAB; 2370 ftab->reachable = 1; 2371 2372 if(debug['s']) 2373 return; 2374 2375 // See golang.org/s/go12symtab for the format. Briefly: 2376 // 8-byte header 2377 // nfunc [PtrSize bytes] 2378 // function table, alternating PC and offset to func struct [each entry PtrSize bytes] 2379 // end PC [PtrSize bytes] 2380 // offset to file table [4 bytes] 2381 nfunc = 0; 2382 for(cursym = textp; cursym != nil; cursym = cursym->next) 2383 nfunc++; 2384 symgrow(ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize+4); 2385 setuint32(ftab, 0, 0xfffffffb); 2386 setuint8(ftab, 6, MINLC); 2387 setuint8(ftab, 7, PtrSize); 2388 setuintxx(ftab, 8, nfunc, PtrSize); 2389 2390 nfunc = 0; 2391 for(cursym = textp; cursym != nil; cursym = cursym->next, nfunc++) { 2392 funcstart = ftab->np; 2393 funcstart += -ftab->np & (PtrSize-1); 2394 2395 setaddr(ftab, 8+PtrSize+nfunc*2*PtrSize, cursym); 2396 setuintxx(ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize, funcstart, PtrSize); 2397 2398 npcdata = 0; 2399 nfuncdata = 0; 2400 for(p = cursym->text; p != P; p = p->link) { 2401 if(p->as == APCDATA && p->from.offset >= npcdata) 2402 npcdata = p->from.offset+1; 2403 if(p->as == AFUNCDATA && p->from.offset >= nfuncdata) 2404 nfuncdata = p->from.offset+1; 2405 } 2406 2407 // fixed size of struct, checked below 2408 off = funcstart; 2409 end = funcstart + PtrSize + 3*4 + 5*4 + npcdata*4 + nfuncdata*PtrSize; 2410 if(nfuncdata > 0 && (end&(PtrSize-1))) 2411 end += 4; 2412 symgrow(ftab, end); 2413 2414 // entry uintptr 2415 off = setaddr(ftab, off, cursym); 2416 2417 // name int32 2418 off = setuint32(ftab, off, ftabaddstring(ftab, cursym->name)); 2419 2420 // args int32 2421 // TODO: Move into funcinfo. 2422 if(cursym->text == nil) 2423 off = setuint32(ftab, off, ArgsSizeUnknown); 2424 else 2425 off = setuint32(ftab, off, cursym->args); 2426 2427 // frame int32 2428 // TODO: Remove entirely. The pcsp table is more precise. 2429 // This is only used by a fallback case during stack walking 2430 // when a called function doesn't have argument information. 2431 // We need to make sure everything has argument information 2432 // and then remove this. 2433 if(cursym->text == nil) 2434 off = setuint32(ftab, off, 0); 2435 else 2436 off = setuint32(ftab, off, (uint32)cursym->text->to.offset+PtrSize); 2437 2438 // pcsp table (offset int32) 2439 off = addpctab(ftab, off, cursym, "pctospadj", pctospadj, 0); 2440 2441 // pcfile table (offset int32) 2442 off = addpctab(ftab, off, cursym, "pctofileline file", pctofileline, 0); 2443 2444 // pcln table (offset int32) 2445 off = addpctab(ftab, off, cursym, "pctofileline line", pctofileline, 1); 2446 2447 // npcdata int32 2448 off = setuint32(ftab, off, npcdata); 2449 2450 // nfuncdata int32 2451 off = setuint32(ftab, off, nfuncdata); 2452 2453 // tabulate which pc and func data we have. 2454 n = ((npcdata+31)/32 + (nfuncdata+31)/32)*4; 2455 havepc = mal(n); 2456 havefunc = havepc + (npcdata+31)/32; 2457 for(p = cursym->text; p != P; p = p->link) { 2458 if(p->as == AFUNCDATA) { 2459 if((havefunc[p->from.offset/32]>>(p->from.offset%32))&1) 2460 diag("multiple definitions for FUNCDATA $%d", p->from.offset); 2461 havefunc[p->from.offset/32] |= 1<<(p->from.offset%32); 2462 } 2463 if(p->as == APCDATA) 2464 havepc[p->from.offset/32] |= 1<<(p->from.offset%32); 2465 } 2466 2467 // pcdata. 2468 for(i=0; i<npcdata; i++) { 2469 if(!(havepc[i/32]>>(i%32))&1) { 2470 off = setuint32(ftab, off, 0); 2471 continue; 2472 } 2473 off = addpctab(ftab, off, cursym, "pctopcdata", pctopcdata, i); 2474 } 2475 2476 unmal(havepc, n); 2477 2478 // funcdata, must be pointer-aligned and we're only int32-aligned. 2479 // Unlike pcdata, can gather in a single pass. 2480 // Missing funcdata will be 0 (nil pointer). 2481 if(nfuncdata > 0) { 2482 if(off&(PtrSize-1)) 2483 off += 4; 2484 for(p = cursym->text; p != P; p = p->link) { 2485 if(p->as == AFUNCDATA) { 2486 i = p->from.offset; 2487 if(p->to.type == D_CONST) 2488 setuintxx(ftab, off+PtrSize*i, p->to.offset, PtrSize); 2489 else { 2490 // TODO: Dedup. 2491 funcdata_bytes += p->to.sym->size; 2492 setaddrplus(ftab, off+PtrSize*i, p->to.sym, p->to.offset); 2493 } 2494 } 2495 } 2496 off += nfuncdata*PtrSize; 2497 } 2498 2499 if(off != end) { 2500 diag("bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d)", funcstart, off, end, npcdata, nfuncdata); 2501 errorexit(); 2502 } 2503 2504 // Final entry of table is just end pc. 2505 if(cursym->next == nil) 2506 setaddrplus(ftab, 8+PtrSize+(nfunc+1)*2*PtrSize, cursym, cursym->size); 2507 } 2508 2509 // Start file table. 2510 start = ftab->np; 2511 start += -ftab->np & (PtrSize-1); 2512 setuint32(ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize, start); 2513 2514 symgrow(ftab, start+(nhistfile+1)*4); 2515 setuint32(ftab, start, nhistfile); 2516 for(s = filesyms; s != S; s = s->next) 2517 setuint32(ftab, start + s->value*4, ftabaddstring(ftab, s->name)); 2518 2519 ftab->size = ftab->np; 2520 2521 if(debug['v']) 2522 Bprint(&bso, "%5.2f pclntab=%lld bytes, funcdata total %lld bytes\n", cputime(), (vlong)ftab->size, (vlong)funcdata_bytes); 2523 }