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