github.com/d4l3k/go@v0.0.0-20151015000803-65fc379daeda/src/cmd/link/internal/ld/lib.go (about) 1 // Inferno utils/8l/asm.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/8l/asm.c 3 // 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 6 // Portions Copyright © 1997-1999 Vita Nuova Limited 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 8 // Portions Copyright © 2004,2006 Bruce Ellis 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 11 // Portions Copyright © 2009 The Go Authors. All rights reserved. 12 // 13 // Permission is hereby granted, free of charge, to any person obtaining a copy 14 // of this software and associated documentation files (the "Software"), to deal 15 // in the Software without restriction, including without limitation the rights 16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 // copies of the Software, and to permit persons to whom the Software is 18 // furnished to do so, subject to the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be included in 21 // all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 // THE SOFTWARE. 30 31 package ld 32 33 import ( 34 "bufio" 35 "bytes" 36 "cmd/internal/obj" 37 "crypto/sha1" 38 "debug/elf" 39 "encoding/binary" 40 "fmt" 41 "io" 42 "io/ioutil" 43 "log" 44 "os" 45 "os/exec" 46 "path/filepath" 47 "runtime" 48 "strings" 49 ) 50 51 // Data layout and relocation. 52 53 // Derived from Inferno utils/6l/l.h 54 // http://code.google.com/p/inferno-os/source/browse/utils/6l/l.h 55 // 56 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 57 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 58 // Portions Copyright © 1997-1999 Vita Nuova Limited 59 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 60 // Portions Copyright © 2004,2006 Bruce Ellis 61 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 62 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 63 // Portions Copyright © 2009 The Go Authors. All rights reserved. 64 // 65 // Permission is hereby granted, free of charge, to any person obtaining a copy 66 // of this software and associated documentation files (the "Software"), to deal 67 // in the Software without restriction, including without limitation the rights 68 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 69 // copies of the Software, and to permit persons to whom the Software is 70 // furnished to do so, subject to the following conditions: 71 // 72 // The above copyright notice and this permission notice shall be included in 73 // all copies or substantial portions of the Software. 74 // 75 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 76 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 77 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 78 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 79 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 80 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 81 // THE SOFTWARE. 82 83 type Arch struct { 84 Thechar int 85 Ptrsize int 86 Intsize int 87 Regsize int 88 Funcalign int 89 Maxalign int 90 Minlc int 91 Dwarfregsp int 92 Dwarfreglr int 93 Linuxdynld string 94 Freebsddynld string 95 Netbsddynld string 96 Openbsddynld string 97 Dragonflydynld string 98 Solarisdynld string 99 Adddynrel func(*LSym, *Reloc) 100 Archinit func() 101 Archreloc func(*Reloc, *LSym, *int64) int 102 Archrelocvariant func(*Reloc, *LSym, int64) int64 103 Asmb func() 104 Elfreloc1 func(*Reloc, int64) int 105 Elfsetupplt func() 106 Gentext func() 107 Machoreloc1 func(*Reloc, int64) int 108 PEreloc1 func(*Reloc, int64) bool 109 Lput func(uint32) 110 Wput func(uint16) 111 Vput func(uint64) 112 } 113 114 type Rpath struct { 115 set bool 116 val string 117 } 118 119 func (r *Rpath) Set(val string) error { 120 r.set = true 121 r.val = val 122 return nil 123 } 124 125 func (r *Rpath) String() string { 126 return r.val 127 } 128 129 var ( 130 Thearch Arch 131 datap *LSym 132 Debug [128]int 133 Lcsize int32 134 rpath Rpath 135 Spsize int32 136 Symsize int32 137 ) 138 139 // Terrible but standard terminology. 140 // A segment describes a block of file to load into memory. 141 // A section further describes the pieces of that block for 142 // use in debuggers and such. 143 144 const ( 145 MINFUNC = 16 // minimum size for a function 146 ) 147 148 type Segment struct { 149 Rwx uint8 // permission as usual unix bits (5 = r-x etc) 150 Vaddr uint64 // virtual address 151 Length uint64 // length in memory 152 Fileoff uint64 // file offset 153 Filelen uint64 // length on disk 154 Sect *Section 155 } 156 157 type Section struct { 158 Rwx uint8 159 Extnum int16 160 Align int32 161 Name string 162 Vaddr uint64 163 Length uint64 164 Next *Section 165 Seg *Segment 166 Elfsect *ElfShdr 167 Reloff uint64 168 Rellen uint64 169 } 170 171 // DynlinkingGo returns whether we are producing Go code that can live 172 // in separate shared libraries linked together at runtime. 173 func DynlinkingGo() bool { 174 return Buildmode == BuildmodeShared || Linkshared 175 } 176 177 // UseRelro returns whether to make use of "read only relocations" aka 178 // relro. 179 func UseRelro() bool { 180 return (Buildmode == BuildmodeCShared || Buildmode == BuildmodeShared) && Iself 181 } 182 183 var ( 184 Thestring string 185 Thelinkarch *LinkArch 186 outfile string 187 dynexp []*LSym 188 dynlib []string 189 ldflag []string 190 havedynamic int 191 Funcalign int 192 iscgo bool 193 elfglobalsymndx int 194 flag_installsuffix string 195 flag_race int 196 Buildmode BuildMode 197 Linkshared bool 198 tracksym string 199 interpreter string 200 tmpdir string 201 extld string 202 extldflags string 203 debug_s int // backup old value of debug['s'] 204 Ctxt *Link 205 HEADR int32 206 HEADTYPE int32 207 INITRND int32 208 INITTEXT int64 209 INITDAT int64 210 INITENTRY string /* entry point */ 211 nerrors int 212 Linkmode int 213 liveness int64 214 ) 215 216 // for dynexport field of LSym 217 const ( 218 CgoExportDynamic = 1 << 0 219 CgoExportStatic = 1 << 1 220 ) 221 222 var ( 223 Segtext Segment 224 Segrodata Segment 225 Segdata Segment 226 Segdwarf Segment 227 ) 228 229 /* set by call to mywhatsys() */ 230 231 /* whence for ldpkg */ 232 const ( 233 FileObj = 0 + iota 234 ArchiveObj 235 Pkgdef 236 ) 237 238 var ( 239 headstring string 240 // buffered output 241 Bso obj.Biobuf 242 ) 243 244 var coutbuf struct { 245 *bufio.Writer 246 f *os.File 247 } 248 249 const ( 250 symname = "__.GOSYMDEF" 251 pkgname = "__.PKGDEF" 252 ) 253 254 var ( 255 // Set if we see an object compiled by the host compiler that is not 256 // from a package that is known to support internal linking mode. 257 externalobj = false 258 goroot string 259 goarch string 260 goos string 261 theline string 262 ) 263 264 func Lflag(arg string) { 265 Ctxt.Libdir = append(Ctxt.Libdir, arg) 266 } 267 268 // A BuildMode indicates the sort of object we are building: 269 // "exe": build a main package and everything it imports into an executable. 270 // "c-shared": build a main package, plus all packages that it imports, into a 271 // single C shared library. The only callable symbols will be those functions 272 // marked as exported. 273 // "shared": combine all packages passed on the command line, and their 274 // dependencies, into a single shared library that will be used when 275 // building with the -linkshared option. 276 type BuildMode uint8 277 278 const ( 279 BuildmodeUnset BuildMode = iota 280 BuildmodeExe 281 BuildmodeCArchive 282 BuildmodeCShared 283 BuildmodeShared 284 ) 285 286 func (mode *BuildMode) Set(s string) error { 287 goos := obj.Getgoos() 288 goarch := obj.Getgoarch() 289 badmode := func() error { 290 return fmt.Errorf("buildmode %s not supported on %s/%s", s, goos, goarch) 291 } 292 switch s { 293 default: 294 return fmt.Errorf("invalid buildmode: %q", s) 295 case "exe": 296 *mode = BuildmodeExe 297 case "c-archive": 298 switch goos { 299 case "darwin", "linux": 300 default: 301 return badmode() 302 } 303 *mode = BuildmodeCArchive 304 case "c-shared": 305 if goarch != "amd64" && goarch != "arm" { 306 return badmode() 307 } 308 *mode = BuildmodeCShared 309 case "shared": 310 if goos != "linux" || (goarch != "amd64" && goarch != "arm") { 311 return badmode() 312 } 313 *mode = BuildmodeShared 314 } 315 return nil 316 } 317 318 func (mode *BuildMode) String() string { 319 switch *mode { 320 case BuildmodeUnset: 321 return "" // avoid showing a default in usage message 322 case BuildmodeExe: 323 return "exe" 324 case BuildmodeCArchive: 325 return "c-archive" 326 case BuildmodeCShared: 327 return "c-shared" 328 case BuildmodeShared: 329 return "shared" 330 } 331 return fmt.Sprintf("BuildMode(%d)", uint8(*mode)) 332 } 333 334 /* 335 * Unix doesn't like it when we write to a running (or, sometimes, 336 * recently run) binary, so remove the output file before writing it. 337 * On Windows 7, remove() can force a subsequent create() to fail. 338 * S_ISREG() does not exist on Plan 9. 339 */ 340 func mayberemoveoutfile() { 341 if fi, err := os.Lstat(outfile); err == nil && !fi.Mode().IsRegular() { 342 return 343 } 344 os.Remove(outfile) 345 } 346 347 func libinit() { 348 Funcalign = Thearch.Funcalign 349 mywhatsys() // get goroot, goarch, goos 350 351 // add goroot to the end of the libdir list. 352 suffix := "" 353 354 suffixsep := "" 355 if flag_installsuffix != "" { 356 suffixsep = "_" 357 suffix = flag_installsuffix 358 } else if flag_race != 0 { 359 suffixsep = "_" 360 suffix = "race" 361 } 362 363 Lflag(fmt.Sprintf("%s/pkg/%s_%s%s%s", goroot, goos, goarch, suffixsep, suffix)) 364 365 mayberemoveoutfile() 366 f, err := os.OpenFile(outfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775) 367 if err != nil { 368 Exitf("cannot create %s: %v", outfile, err) 369 } 370 371 coutbuf.Writer = bufio.NewWriter(f) 372 coutbuf.f = f 373 374 if INITENTRY == "" { 375 switch Buildmode { 376 case BuildmodeCShared, BuildmodeCArchive: 377 INITENTRY = fmt.Sprintf("_rt0_%s_%s_lib", goarch, goos) 378 case BuildmodeExe: 379 INITENTRY = fmt.Sprintf("_rt0_%s_%s", goarch, goos) 380 case BuildmodeShared: 381 // No INITENTRY for -buildmode=shared 382 default: 383 Diag("unknown INITENTRY for buildmode %v", Buildmode) 384 } 385 } 386 387 if !DynlinkingGo() { 388 Linklookup(Ctxt, INITENTRY, 0).Type = obj.SXREF 389 } 390 } 391 392 func Exitf(format string, a ...interface{}) { 393 fmt.Fprintf(os.Stderr, os.Args[0]+": "+format+"\n", a...) 394 if coutbuf.f != nil { 395 coutbuf.f.Close() 396 mayberemoveoutfile() 397 } 398 Exit(2) 399 } 400 401 func errorexit() { 402 if coutbuf.f != nil { 403 if nerrors != 0 { 404 Cflush() 405 } 406 // For rmtemp run at atexit time on Windows. 407 if err := coutbuf.f.Close(); err != nil { 408 Exitf("close: %v", err) 409 } 410 } 411 412 if nerrors != 0 { 413 if coutbuf.f != nil { 414 mayberemoveoutfile() 415 } 416 Exit(2) 417 } 418 419 Exit(0) 420 } 421 422 func loadinternal(name string) { 423 found := 0 424 for i := 0; i < len(Ctxt.Libdir); i++ { 425 if Linkshared { 426 shlibname := fmt.Sprintf("%s/%s.shlibname", Ctxt.Libdir[i], name) 427 if Debug['v'] != 0 { 428 fmt.Fprintf(&Bso, "searching for %s.a in %s\n", name, shlibname) 429 } 430 if _, err := os.Stat(shlibname); err == nil { 431 addlibpath(Ctxt, "internal", "internal", "", name, shlibname) 432 found = 1 433 break 434 } 435 } 436 pname := fmt.Sprintf("%s/%s.a", Ctxt.Libdir[i], name) 437 if Debug['v'] != 0 { 438 fmt.Fprintf(&Bso, "searching for %s.a in %s\n", name, pname) 439 } 440 if _, err := os.Stat(pname); err == nil { 441 addlibpath(Ctxt, "internal", "internal", pname, name, "") 442 found = 1 443 break 444 } 445 } 446 447 if found == 0 { 448 fmt.Fprintf(&Bso, "warning: unable to find %s.a\n", name) 449 } 450 } 451 452 func loadlib() { 453 switch Buildmode { 454 case BuildmodeCShared: 455 s := Linklookup(Ctxt, "runtime.islibrary", 0) 456 s.Dupok = 1 457 Adduint8(Ctxt, s, 1) 458 case BuildmodeCArchive: 459 s := Linklookup(Ctxt, "runtime.isarchive", 0) 460 s.Dupok = 1 461 Adduint8(Ctxt, s, 1) 462 } 463 464 loadinternal("runtime") 465 if Thearch.Thechar == '5' { 466 loadinternal("math") 467 } 468 if flag_race != 0 { 469 loadinternal("runtime/race") 470 } 471 472 var i int 473 for i = 0; i < len(Ctxt.Library); i++ { 474 if Debug['v'] > 1 { 475 fmt.Fprintf(&Bso, "%5.2f autolib: %s (from %s)\n", obj.Cputime(), Ctxt.Library[i].File, Ctxt.Library[i].Objref) 476 } 477 iscgo = iscgo || Ctxt.Library[i].Pkg == "runtime/cgo" 478 if Ctxt.Library[i].Shlib != "" { 479 ldshlibsyms(Ctxt.Library[i].Shlib) 480 } else { 481 objfile(Ctxt.Library[i]) 482 } 483 } 484 485 if Linkmode == LinkAuto { 486 if iscgo && externalobj { 487 Linkmode = LinkExternal 488 } else { 489 Linkmode = LinkInternal 490 } 491 492 // Force external linking for android. 493 if goos == "android" { 494 Linkmode = LinkExternal 495 } 496 497 // cgo on Darwin must use external linking 498 // we can always use external linking, but then there will be circular 499 // dependency problems when compiling natively (external linking requires 500 // runtime/cgo, runtime/cgo requires cmd/cgo, but cmd/cgo needs to be 501 // compiled using external linking.) 502 if (Thearch.Thechar == '5' || Thearch.Thechar == '7') && HEADTYPE == obj.Hdarwin && iscgo { 503 Linkmode = LinkExternal 504 } 505 } 506 507 // cmd/7l doesn't support cgo internal linking 508 // This is https://golang.org/issue/10373. 509 if iscgo && goarch == "arm64" { 510 Linkmode = LinkExternal 511 } 512 513 if Linkmode == LinkExternal && !iscgo { 514 // This indicates a user requested -linkmode=external. 515 // The startup code uses an import of runtime/cgo to decide 516 // whether to initialize the TLS. So give it one. This could 517 // be handled differently but it's an unusual case. 518 loadinternal("runtime/cgo") 519 520 if i < len(Ctxt.Library) { 521 if Ctxt.Library[i].Shlib != "" { 522 ldshlibsyms(Ctxt.Library[i].Shlib) 523 } else { 524 if DynlinkingGo() { 525 Exitf("cannot implicitly include runtime/cgo in a shared library") 526 } 527 objfile(Ctxt.Library[i]) 528 } 529 } 530 } 531 532 if Linkmode == LinkInternal { 533 // Drop all the cgo_import_static declarations. 534 // Turns out we won't be needing them. 535 for s := Ctxt.Allsym; s != nil; s = s.Allsym { 536 if s.Type == obj.SHOSTOBJ { 537 // If a symbol was marked both 538 // cgo_import_static and cgo_import_dynamic, 539 // then we want to make it cgo_import_dynamic 540 // now. 541 if s.Extname != "" && s.Dynimplib != "" && s.Cgoexport == 0 { 542 s.Type = obj.SDYNIMPORT 543 } else { 544 s.Type = 0 545 } 546 } 547 } 548 } 549 550 tlsg := Linklookup(Ctxt, "runtime.tlsg", 0) 551 552 // runtime.tlsg is used for external linking on platforms that do not define 553 // a variable to hold g in assembly (currently only intel). 554 if tlsg.Type == 0 { 555 tlsg.Type = obj.STLSBSS 556 tlsg.Size = int64(Thearch.Ptrsize) 557 } else if tlsg.Type != obj.SDYNIMPORT { 558 Diag("internal error: runtime declared tlsg variable %d", tlsg.Type) 559 } 560 tlsg.Reachable = true 561 Ctxt.Tlsg = tlsg 562 563 moduledata := Linklookup(Ctxt, "runtime.firstmoduledata", 0) 564 if moduledata.Type != 0 && moduledata.Type != obj.SDYNIMPORT { 565 // If the module (toolchain-speak for "executable or shared 566 // library") we are linking contains the runtime package, it 567 // will define the runtime.firstmoduledata symbol and we 568 // truncate it back to 0 bytes so we can define its entire 569 // contents in symtab.go:symtab(). 570 moduledata.Size = 0 571 572 // In addition, on ARM, the runtime depends on the linker 573 // recording the value of GOARM. 574 if Thearch.Thechar == '5' { 575 s := Linklookup(Ctxt, "runtime.goarm", 0) 576 577 s.Type = obj.SRODATA 578 s.Size = 0 579 Adduint8(Ctxt, s, uint8(Ctxt.Goarm)) 580 } 581 } else { 582 // If OTOH the module does not contain the runtime package, 583 // create a local symbol for the moduledata. 584 moduledata = Linklookup(Ctxt, "local.moduledata", 0) 585 moduledata.Local = true 586 } 587 // In all cases way we mark the moduledata as noptrdata to hide it from 588 // the GC. 589 moduledata.Type = obj.SNOPTRDATA 590 moduledata.Reachable = true 591 Ctxt.Moduledata = moduledata 592 593 // Now that we know the link mode, trim the dynexp list. 594 x := CgoExportDynamic 595 596 if Linkmode == LinkExternal { 597 x = CgoExportStatic 598 } 599 w := 0 600 for i := 0; i < len(dynexp); i++ { 601 if int(dynexp[i].Cgoexport)&x != 0 { 602 dynexp[w] = dynexp[i] 603 w++ 604 } 605 } 606 dynexp = dynexp[:w] 607 608 // In internal link mode, read the host object files. 609 if Linkmode == LinkInternal { 610 hostobjs() 611 } else { 612 hostlinksetup() 613 } 614 615 // We've loaded all the code now. 616 // If there are no dynamic libraries needed, gcc disables dynamic linking. 617 // Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13) 618 // assumes that a dynamic binary always refers to at least one dynamic library. 619 // Rather than be a source of test cases for glibc, disable dynamic linking 620 // the same way that gcc would. 621 // 622 // Exception: on OS X, programs such as Shark only work with dynamic 623 // binaries, so leave it enabled on OS X (Mach-O) binaries. 624 // Also leave it enabled on Solaris which doesn't support 625 // statically linked binaries. 626 if Buildmode == BuildmodeExe && havedynamic == 0 && HEADTYPE != obj.Hdarwin && HEADTYPE != obj.Hsolaris { 627 Debug['d'] = 1 628 } 629 630 importcycles() 631 } 632 633 /* 634 * look for the next file in an archive. 635 * adapted from libmach. 636 */ 637 func nextar(bp *obj.Biobuf, off int64, a *ArHdr) int64 { 638 if off&1 != 0 { 639 off++ 640 } 641 obj.Bseek(bp, off, 0) 642 buf := make([]byte, SAR_HDR) 643 if n := obj.Bread(bp, buf); n < len(buf) { 644 if n >= 0 { 645 return 0 646 } 647 return -1 648 } 649 650 a.name = artrim(buf[0:16]) 651 a.date = artrim(buf[16:28]) 652 a.uid = artrim(buf[28:34]) 653 a.gid = artrim(buf[34:40]) 654 a.mode = artrim(buf[40:48]) 655 a.size = artrim(buf[48:58]) 656 a.fmag = artrim(buf[58:60]) 657 658 arsize := atolwhex(a.size) 659 if arsize&1 != 0 { 660 arsize++ 661 } 662 return int64(arsize) + SAR_HDR 663 } 664 665 func objfile(lib *Library) { 666 pkg := pathtoprefix(lib.Pkg) 667 668 if Debug['v'] > 1 { 669 fmt.Fprintf(&Bso, "%5.2f ldobj: %s (%s)\n", obj.Cputime(), lib.File, pkg) 670 } 671 Bso.Flush() 672 var err error 673 var f *obj.Biobuf 674 f, err = obj.Bopenr(lib.File) 675 if err != nil { 676 Exitf("cannot open file %s: %v", lib.File, err) 677 } 678 679 magbuf := make([]byte, len(ARMAG)) 680 if obj.Bread(f, magbuf) != len(magbuf) || !strings.HasPrefix(string(magbuf), ARMAG) { 681 /* load it as a regular file */ 682 l := obj.Bseek(f, 0, 2) 683 684 obj.Bseek(f, 0, 0) 685 ldobj(f, pkg, l, lib.File, lib.File, FileObj) 686 obj.Bterm(f) 687 688 return 689 } 690 691 /* skip over optional __.GOSYMDEF and process __.PKGDEF */ 692 off := obj.Boffset(f) 693 694 var arhdr ArHdr 695 l := nextar(f, off, &arhdr) 696 var pname string 697 if l <= 0 { 698 Diag("%s: short read on archive file symbol header", lib.File) 699 goto out 700 } 701 702 if strings.HasPrefix(arhdr.name, symname) { 703 off += l 704 l = nextar(f, off, &arhdr) 705 if l <= 0 { 706 Diag("%s: short read on archive file symbol header", lib.File) 707 goto out 708 } 709 } 710 711 if !strings.HasPrefix(arhdr.name, pkgname) { 712 Diag("%s: cannot find package header", lib.File) 713 goto out 714 } 715 716 if Buildmode == BuildmodeShared { 717 before := obj.Boffset(f) 718 pkgdefBytes := make([]byte, atolwhex(arhdr.size)) 719 obj.Bread(f, pkgdefBytes) 720 hash := sha1.Sum(pkgdefBytes) 721 lib.hash = hash[:] 722 obj.Bseek(f, before, 0) 723 } 724 725 off += l 726 727 if Debug['u'] != 0 { 728 ldpkg(f, pkg, atolwhex(arhdr.size), lib.File, Pkgdef) 729 } 730 731 /* 732 * load all the object files from the archive now. 733 * this gives us sequential file access and keeps us 734 * from needing to come back later to pick up more 735 * objects. it breaks the usual C archive model, but 736 * this is Go, not C. the common case in Go is that 737 * we need to load all the objects, and then we throw away 738 * the individual symbols that are unused. 739 * 740 * loading every object will also make it possible to 741 * load foreign objects not referenced by __.GOSYMDEF. 742 */ 743 for { 744 l = nextar(f, off, &arhdr) 745 if l == 0 { 746 break 747 } 748 if l < 0 { 749 Exitf("%s: malformed archive", lib.File) 750 } 751 752 off += l 753 754 pname = fmt.Sprintf("%s(%s)", lib.File, arhdr.name) 755 l = atolwhex(arhdr.size) 756 ldobj(f, pkg, l, pname, lib.File, ArchiveObj) 757 } 758 759 out: 760 obj.Bterm(f) 761 } 762 763 type Hostobj struct { 764 ld func(*obj.Biobuf, string, int64, string) 765 pkg string 766 pn string 767 file string 768 off int64 769 length int64 770 } 771 772 var hostobj []Hostobj 773 774 // These packages can use internal linking mode. 775 // Others trigger external mode. 776 var internalpkg = []string{ 777 "crypto/x509", 778 "net", 779 "os/user", 780 "runtime/cgo", 781 "runtime/race", 782 } 783 784 func ldhostobj(ld func(*obj.Biobuf, string, int64, string), f *obj.Biobuf, pkg string, length int64, pn string, file string) { 785 isinternal := false 786 for i := 0; i < len(internalpkg); i++ { 787 if pkg == internalpkg[i] { 788 isinternal = true 789 break 790 } 791 } 792 793 // DragonFly declares errno with __thread, which results in a symbol 794 // type of R_386_TLS_GD or R_X86_64_TLSGD. The Go linker does not 795 // currently know how to handle TLS relocations, hence we have to 796 // force external linking for any libraries that link in code that 797 // uses errno. This can be removed if the Go linker ever supports 798 // these relocation types. 799 if HEADTYPE == obj.Hdragonfly { 800 if pkg == "net" || pkg == "os/user" { 801 isinternal = false 802 } 803 } 804 805 if !isinternal { 806 externalobj = true 807 } 808 809 hostobj = append(hostobj, Hostobj{}) 810 h := &hostobj[len(hostobj)-1] 811 h.ld = ld 812 h.pkg = pkg 813 h.pn = pn 814 h.file = file 815 h.off = obj.Boffset(f) 816 h.length = length 817 } 818 819 func hostobjs() { 820 var f *obj.Biobuf 821 var h *Hostobj 822 823 for i := 0; i < len(hostobj); i++ { 824 h = &hostobj[i] 825 var err error 826 f, err = obj.Bopenr(h.file) 827 if f == nil { 828 Exitf("cannot reopen %s: %v", h.pn, err) 829 } 830 831 obj.Bseek(f, h.off, 0) 832 h.ld(f, h.pkg, h.length, h.pn) 833 obj.Bterm(f) 834 } 835 } 836 837 // provided by lib9 838 839 func rmtemp() { 840 os.RemoveAll(tmpdir) 841 } 842 843 func hostlinksetup() { 844 if Linkmode != LinkExternal { 845 return 846 } 847 848 // For external link, record that we need to tell the external linker -s, 849 // and turn off -s internally: the external linker needs the symbol 850 // information for its final link. 851 debug_s = Debug['s'] 852 Debug['s'] = 0 853 854 // create temporary directory and arrange cleanup 855 if tmpdir == "" { 856 dir, err := ioutil.TempDir("", "go-link-") 857 if err != nil { 858 log.Fatal(err) 859 } 860 tmpdir = dir 861 AtExit(rmtemp) 862 } 863 864 // change our output to temporary object file 865 coutbuf.f.Close() 866 mayberemoveoutfile() 867 868 p := fmt.Sprintf("%s/go.o", tmpdir) 869 var err error 870 f, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775) 871 if err != nil { 872 Exitf("cannot create %s: %v", p, err) 873 } 874 875 coutbuf.Writer = bufio.NewWriter(f) 876 coutbuf.f = f 877 } 878 879 // hostobjCopy creates a copy of the object files in hostobj in a 880 // temporary directory. 881 func hostobjCopy() (paths []string) { 882 for i, h := range hostobj { 883 f, err := os.Open(h.file) 884 if err != nil { 885 Exitf("cannot reopen %s: %v", h.pn, err) 886 } 887 if _, err := f.Seek(h.off, 0); err != nil { 888 Exitf("cannot seek %s: %v", h.pn, err) 889 } 890 891 p := fmt.Sprintf("%s/%06d.o", tmpdir, i) 892 paths = append(paths, p) 893 w, err := os.Create(p) 894 if err != nil { 895 Exitf("cannot create %s: %v", p, err) 896 } 897 if _, err := io.CopyN(w, f, h.length); err != nil { 898 Exitf("cannot write %s: %v", p, err) 899 } 900 if err := w.Close(); err != nil { 901 Exitf("cannot close %s: %v", p, err) 902 } 903 } 904 return paths 905 } 906 907 // archive builds a .a archive from the hostobj object files. 908 func archive() { 909 if Buildmode != BuildmodeCArchive { 910 return 911 } 912 913 mayberemoveoutfile() 914 argv := []string{"ar", "-q", "-c", "-s", outfile} 915 argv = append(argv, hostobjCopy()...) 916 argv = append(argv, fmt.Sprintf("%s/go.o", tmpdir)) 917 918 if Debug['v'] != 0 { 919 fmt.Fprintf(&Bso, "archive: %s\n", strings.Join(argv, " ")) 920 Bso.Flush() 921 } 922 923 if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil { 924 Exitf("running %s failed: %v\n%s", argv[0], err, out) 925 } 926 } 927 928 func hostlink() { 929 if Linkmode != LinkExternal || nerrors > 0 { 930 return 931 } 932 if Buildmode == BuildmodeCArchive { 933 return 934 } 935 936 if extld == "" { 937 extld = "gcc" 938 } 939 940 var argv []string 941 argv = append(argv, extld) 942 switch Thearch.Thechar { 943 case '8': 944 argv = append(argv, "-m32") 945 946 case '6', '9': 947 argv = append(argv, "-m64") 948 949 case '5': 950 argv = append(argv, "-marm") 951 952 case '7': 953 // nothing needed 954 } 955 956 if Debug['s'] == 0 && debug_s == 0 { 957 argv = append(argv, "-gdwarf-2") 958 } else { 959 argv = append(argv, "-s") 960 } 961 962 if HEADTYPE == obj.Hdarwin { 963 argv = append(argv, "-Wl,-no_pie,-headerpad,1144") 964 } 965 if HEADTYPE == obj.Hopenbsd { 966 argv = append(argv, "-Wl,-nopie") 967 } 968 if HEADTYPE == obj.Hwindows { 969 if headstring == "windowsgui" { 970 argv = append(argv, "-mwindows") 971 } else { 972 argv = append(argv, "-mconsole") 973 } 974 } 975 976 switch Buildmode { 977 case BuildmodeExe: 978 if HEADTYPE == obj.Hdarwin { 979 argv = append(argv, "-Wl,-pagezero_size,4000000") 980 } 981 case BuildmodeCShared: 982 if HEADTYPE == obj.Hdarwin { 983 argv = append(argv, "-dynamiclib") 984 } else { 985 // ELF. 986 argv = append(argv, "-Wl,-Bsymbolic") 987 if UseRelro() { 988 argv = append(argv, "-Wl,-z,relro") 989 } 990 // Pass -z nodelete to mark the shared library as 991 // non-closeable: a dlclose will do nothing. 992 argv = append(argv, "-shared", "-Wl,-z,nodelete") 993 } 994 case BuildmodeShared: 995 // TODO(mwhudson): unless you do this, dynamic relocations fill 996 // out the findfunctab table and for some reason shared libraries 997 // and the executable both define a main function and putting the 998 // address of executable's main into the shared libraries 999 // findfunctab violates the assumptions of the runtime. TBH, I 1000 // think we may well end up wanting to use -Bsymbolic here 1001 // anyway. 1002 argv = append(argv, "-Wl,-Bsymbolic-functions") 1003 if UseRelro() { 1004 argv = append(argv, "-Wl,-z,relro") 1005 } 1006 argv = append(argv, "-shared") 1007 } 1008 1009 if Linkshared && Iself { 1010 // We force all symbol resolution to be done at program startup 1011 // because lazy PLT resolution can use large amounts of stack at 1012 // times we cannot allow it to do so. 1013 argv = append(argv, "-Wl,-znow") 1014 } 1015 1016 if Iself && len(buildinfo) > 0 { 1017 argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo)) 1018 } 1019 1020 // On Windows, given -o foo, GCC will append ".exe" to produce 1021 // "foo.exe". We have decided that we want to honor the -o 1022 // option. To make this work, we append a '.' so that GCC 1023 // will decide that the file already has an extension. We 1024 // only want to do this when producing a Windows output file 1025 // on a Windows host. 1026 outopt := outfile 1027 if goos == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" { 1028 outopt += "." 1029 } 1030 argv = append(argv, "-o") 1031 argv = append(argv, outopt) 1032 1033 if rpath.val != "" { 1034 argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val)) 1035 } 1036 1037 // Force global symbols to be exported for dlopen, etc. 1038 if Iself { 1039 argv = append(argv, "-rdynamic") 1040 } 1041 1042 if strings.Contains(argv[0], "clang") { 1043 argv = append(argv, "-Qunused-arguments") 1044 } 1045 1046 argv = append(argv, hostobjCopy()...) 1047 argv = append(argv, fmt.Sprintf("%s/go.o", tmpdir)) 1048 1049 if Linkshared { 1050 seenDirs := make(map[string]bool) 1051 seenLibs := make(map[string]bool) 1052 addshlib := func(path string) { 1053 dir, base := filepath.Split(path) 1054 if !seenDirs[dir] { 1055 argv = append(argv, "-L"+dir) 1056 if !rpath.set { 1057 argv = append(argv, "-Wl,-rpath="+dir) 1058 } 1059 seenDirs[dir] = true 1060 } 1061 base = strings.TrimSuffix(base, ".so") 1062 base = strings.TrimPrefix(base, "lib") 1063 if !seenLibs[base] { 1064 argv = append(argv, "-l"+base) 1065 seenLibs[base] = true 1066 } 1067 } 1068 for _, shlib := range Ctxt.Shlibs { 1069 addshlib(shlib.Path) 1070 for _, dep := range shlib.Deps { 1071 if dep == "" { 1072 continue 1073 } 1074 libpath := findshlib(dep) 1075 if libpath != "" { 1076 addshlib(libpath) 1077 } 1078 } 1079 } 1080 } 1081 1082 argv = append(argv, ldflag...) 1083 1084 for _, p := range strings.Fields(extldflags) { 1085 argv = append(argv, p) 1086 1087 // clang, unlike GCC, passes -rdynamic to the linker 1088 // even when linking with -static, causing a linker 1089 // error when using GNU ld. So take out -rdynamic if 1090 // we added it. We do it in this order, rather than 1091 // only adding -rdynamic later, so that -extldflags 1092 // can override -rdynamic without using -static. 1093 if Iself && p == "-static" { 1094 for i := range argv { 1095 if argv[i] == "-rdynamic" { 1096 argv[i] = "-static" 1097 } 1098 } 1099 } 1100 } 1101 if HEADTYPE == obj.Hwindows { 1102 argv = append(argv, peimporteddlls()...) 1103 } 1104 1105 if Debug['v'] != 0 { 1106 fmt.Fprintf(&Bso, "host link:") 1107 for _, v := range argv { 1108 fmt.Fprintf(&Bso, " %q", v) 1109 } 1110 fmt.Fprintf(&Bso, "\n") 1111 Bso.Flush() 1112 } 1113 1114 if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil { 1115 Exitf("running %s failed: %v\n%s", argv[0], err, out) 1116 } else if Debug['v'] != 0 && len(out) > 0 { 1117 fmt.Fprintf(&Bso, "%s", out) 1118 Bso.Flush() 1119 } 1120 1121 if Debug['s'] == 0 && debug_s == 0 && HEADTYPE == obj.Hdarwin { 1122 // Skip combining dwarf on arm. 1123 if Thearch.Thechar != '5' && Thearch.Thechar != '7' { 1124 dsym := fmt.Sprintf("%s/go.dwarf", tmpdir) 1125 if out, err := exec.Command("dsymutil", "-f", outfile, "-o", dsym).CombinedOutput(); err != nil { 1126 Ctxt.Cursym = nil 1127 Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out) 1128 } 1129 // For os.Rename to work reliably, must be in same directory as outfile. 1130 combinedOutput := outfile + "~" 1131 if err := machoCombineDwarf(outfile, dsym, combinedOutput); err != nil { 1132 Ctxt.Cursym = nil 1133 Exitf("%s: combining dwarf failed: %v", os.Args[0], err) 1134 } 1135 os.Remove(outfile) 1136 if err := os.Rename(combinedOutput, outfile); err != nil { 1137 Ctxt.Cursym = nil 1138 Exitf("%s: %v", os.Args[0], err) 1139 } 1140 } 1141 } 1142 } 1143 1144 func ldobj(f *obj.Biobuf, pkg string, length int64, pn string, file string, whence int) { 1145 eof := obj.Boffset(f) + length 1146 1147 start := obj.Boffset(f) 1148 c1 := obj.Bgetc(f) 1149 c2 := obj.Bgetc(f) 1150 c3 := obj.Bgetc(f) 1151 c4 := obj.Bgetc(f) 1152 obj.Bseek(f, start, 0) 1153 1154 magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4) 1155 if magic == 0x7f454c46 { // \x7F E L F 1156 ldhostobj(ldelf, f, pkg, length, pn, file) 1157 return 1158 } 1159 1160 if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe { 1161 ldhostobj(ldmacho, f, pkg, length, pn, file) 1162 return 1163 } 1164 1165 if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 { 1166 ldhostobj(ldpe, f, pkg, length, pn, file) 1167 return 1168 } 1169 1170 /* check the header */ 1171 line := obj.Brdline(f, '\n') 1172 if line == "" { 1173 if obj.Blinelen(f) > 0 { 1174 Diag("%s: not an object file", pn) 1175 return 1176 } 1177 Diag("truncated object file: %s", pn) 1178 return 1179 } 1180 1181 if !strings.HasPrefix(line, "go object ") { 1182 if strings.HasSuffix(pn, ".go") { 1183 Exitf("%cl: input %s is not .%c file (use %cg to compile .go files)", Thearch.Thechar, pn, Thearch.Thechar, Thearch.Thechar) 1184 } 1185 1186 if line == Thestring { 1187 // old header format: just $GOOS 1188 Diag("%s: stale object file", pn) 1189 return 1190 } 1191 1192 Diag("%s: not an object file", pn) 1193 return 1194 } 1195 1196 // First, check that the basic goos, goarch, and version match. 1197 t := fmt.Sprintf("%s %s %s ", goos, obj.Getgoarch(), obj.Getgoversion()) 1198 1199 line = strings.TrimRight(line, "\n") 1200 if !strings.HasPrefix(line[10:]+" ", t) && Debug['f'] == 0 { 1201 Diag("%s: object is [%s] expected [%s]", pn, line[10:], t) 1202 return 1203 } 1204 1205 // Second, check that longer lines match each other exactly, 1206 // so that the Go compiler and write additional information 1207 // that must be the same from run to run. 1208 if len(line) >= len(t)+10 { 1209 if theline == "" { 1210 theline = line[10:] 1211 } else if theline != line[10:] { 1212 Diag("%s: object is [%s] expected [%s]", pn, line[10:], theline) 1213 return 1214 } 1215 } 1216 1217 /* skip over exports and other info -- ends with \n!\n */ 1218 import0 := obj.Boffset(f) 1219 1220 c1 = '\n' // the last line ended in \n 1221 c2 = obj.Bgetc(f) 1222 c3 = obj.Bgetc(f) 1223 for c1 != '\n' || c2 != '!' || c3 != '\n' { 1224 c1 = c2 1225 c2 = c3 1226 c3 = obj.Bgetc(f) 1227 if c3 == obj.Beof { 1228 Diag("truncated object file: %s", pn) 1229 return 1230 } 1231 } 1232 1233 import1 := obj.Boffset(f) 1234 1235 obj.Bseek(f, import0, 0) 1236 ldpkg(f, pkg, import1-import0-2, pn, whence) // -2 for !\n 1237 obj.Bseek(f, import1, 0) 1238 1239 ldobjfile(Ctxt, f, pkg, eof-obj.Boffset(f), pn) 1240 } 1241 1242 func readelfsymboldata(f *elf.File, sym *elf.Symbol) []byte { 1243 data := make([]byte, sym.Size) 1244 sect := f.Sections[sym.Section] 1245 if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE { 1246 Diag("reading %s from non-data section", sym.Name) 1247 } 1248 n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr)) 1249 if uint64(n) != sym.Size { 1250 Diag("reading contents of %s: %v", sym.Name, err) 1251 } 1252 return data 1253 } 1254 1255 func readwithpad(r io.Reader, sz int32) ([]byte, error) { 1256 data := make([]byte, Rnd(int64(sz), 4)) 1257 _, err := io.ReadFull(r, data) 1258 if err != nil { 1259 return nil, err 1260 } 1261 data = data[:sz] 1262 return data, nil 1263 } 1264 1265 func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) { 1266 for _, sect := range f.Sections { 1267 if sect.Type != elf.SHT_NOTE { 1268 continue 1269 } 1270 r := sect.Open() 1271 for { 1272 var namesize, descsize, noteType int32 1273 err := binary.Read(r, f.ByteOrder, &namesize) 1274 if err != nil { 1275 if err == io.EOF { 1276 break 1277 } 1278 return nil, fmt.Errorf("read namesize failed:", err) 1279 } 1280 err = binary.Read(r, f.ByteOrder, &descsize) 1281 if err != nil { 1282 return nil, fmt.Errorf("read descsize failed:", err) 1283 } 1284 err = binary.Read(r, f.ByteOrder, ¬eType) 1285 if err != nil { 1286 return nil, fmt.Errorf("read type failed:", err) 1287 } 1288 noteName, err := readwithpad(r, namesize) 1289 if err != nil { 1290 return nil, fmt.Errorf("read name failed:", err) 1291 } 1292 desc, err := readwithpad(r, descsize) 1293 if err != nil { 1294 return nil, fmt.Errorf("read desc failed:", err) 1295 } 1296 if string(name) == string(noteName) && typ == noteType { 1297 return desc, nil 1298 } 1299 } 1300 } 1301 return nil, nil 1302 } 1303 1304 func findshlib(shlib string) string { 1305 for _, libdir := range Ctxt.Libdir { 1306 libpath := filepath.Join(libdir, shlib) 1307 if _, err := os.Stat(libpath); err == nil { 1308 return libpath 1309 } 1310 } 1311 Diag("cannot find shared library: %s", shlib) 1312 return "" 1313 } 1314 1315 func ldshlibsyms(shlib string) { 1316 libpath := findshlib(shlib) 1317 if libpath == "" { 1318 return 1319 } 1320 for _, processedlib := range Ctxt.Shlibs { 1321 if processedlib.Path == libpath { 1322 return 1323 } 1324 } 1325 if Ctxt.Debugvlog > 1 && Ctxt.Bso != nil { 1326 fmt.Fprintf(Ctxt.Bso, "%5.2f ldshlibsyms: found library with name %s at %s\n", obj.Cputime(), shlib, libpath) 1327 Ctxt.Bso.Flush() 1328 } 1329 1330 f, err := elf.Open(libpath) 1331 if err != nil { 1332 Diag("cannot open shared library: %s", libpath) 1333 return 1334 } 1335 1336 hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG) 1337 if err != nil { 1338 Diag("cannot read ABI hash from shared library %s: %v", libpath, err) 1339 return 1340 } 1341 1342 depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG) 1343 if err != nil { 1344 Diag("cannot read dep list from shared library %s: %v", libpath, err) 1345 return 1346 } 1347 deps := strings.Split(string(depsbytes), "\n") 1348 1349 syms, err := f.DynamicSymbols() 1350 if err != nil { 1351 Diag("cannot read symbols from shared library: %s", libpath) 1352 return 1353 } 1354 for _, elfsym := range syms { 1355 if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION { 1356 continue 1357 } 1358 lsym := Linklookup(Ctxt, elfsym.Name, 0) 1359 if lsym.Type != 0 && lsym.Type != obj.SDYNIMPORT && lsym.Dupok == 0 { 1360 if (lsym.Type != obj.SBSS && lsym.Type != obj.SNOPTRBSS) || len(lsym.R) != 0 || len(lsym.P) != 0 || f.Sections[elfsym.Section].Type != elf.SHT_NOBITS { 1361 Diag("Found duplicate symbol %s reading from %s, first found in %s", elfsym.Name, shlib, lsym.File) 1362 } 1363 if lsym.Size > int64(elfsym.Size) { 1364 // If the existing symbol is a BSS value that is 1365 // larger than the one read from the shared library, 1366 // keep references to that. Conversely, if the 1367 // version from the shared libray is larger, we want 1368 // to make all references be to that. 1369 continue 1370 } 1371 } 1372 lsym.Type = obj.SDYNIMPORT 1373 lsym.ElfType = elf.ST_TYPE(elfsym.Info) 1374 lsym.Size = int64(elfsym.Size) 1375 if elfsym.Section != elf.SHN_UNDEF { 1376 // Set .File for the library that actually defines the symbol. 1377 lsym.File = libpath 1378 // The decodetype_* functions in decodetype.go need access to 1379 // the type data. 1380 if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") { 1381 lsym.P = readelfsymboldata(f, &elfsym) 1382 } 1383 } 1384 } 1385 1386 // We might have overwritten some functions above (this tends to happen for the 1387 // autogenerated type equality/hashing functions) and we don't want to generated 1388 // pcln table entries for these any more so unstitch them from the Textp linked 1389 // list. 1390 var last *LSym 1391 1392 for s := Ctxt.Textp; s != nil; s = s.Next { 1393 if s.Type == obj.SDYNIMPORT { 1394 continue 1395 } 1396 1397 if last == nil { 1398 Ctxt.Textp = s 1399 } else { 1400 last.Next = s 1401 } 1402 last = s 1403 } 1404 1405 if last == nil { 1406 Ctxt.Textp = nil 1407 Ctxt.Etextp = nil 1408 } else { 1409 last.Next = nil 1410 Ctxt.Etextp = last 1411 } 1412 1413 Ctxt.Shlibs = append(Ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f}) 1414 } 1415 1416 func mywhatsys() { 1417 goroot = obj.Getgoroot() 1418 goos = obj.Getgoos() 1419 goarch = obj.Getgoarch() 1420 1421 if !strings.HasPrefix(goarch, Thestring) { 1422 log.Fatalf("cannot use %cc with GOARCH=%s", Thearch.Thechar, goarch) 1423 } 1424 } 1425 1426 // Copied from ../gc/subr.c:/^pathtoprefix; must stay in sync. 1427 /* 1428 * Convert raw string to the prefix that will be used in the symbol table. 1429 * Invalid bytes turn into %xx. Right now the only bytes that need 1430 * escaping are %, ., and ", but we escape all control characters too. 1431 * 1432 * If you edit this, edit ../gc/subr.c:/^pathtoprefix too. 1433 * If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too. 1434 */ 1435 func pathtoprefix(s string) string { 1436 slash := strings.LastIndex(s, "/") 1437 for i := 0; i < len(s); i++ { 1438 c := s[i] 1439 if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { 1440 var buf bytes.Buffer 1441 for i := 0; i < len(s); i++ { 1442 c := s[i] 1443 if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { 1444 fmt.Fprintf(&buf, "%%%02x", c) 1445 continue 1446 } 1447 buf.WriteByte(c) 1448 } 1449 return buf.String() 1450 } 1451 } 1452 return s 1453 } 1454 1455 func addsection(seg *Segment, name string, rwx int) *Section { 1456 var l **Section 1457 1458 for l = &seg.Sect; *l != nil; l = &(*l).Next { 1459 } 1460 sect := new(Section) 1461 sect.Rwx = uint8(rwx) 1462 sect.Name = name 1463 sect.Seg = seg 1464 sect.Align = int32(Thearch.Ptrsize) // everything is at least pointer-aligned 1465 *l = sect 1466 return sect 1467 } 1468 1469 func Le16(b []byte) uint16 { 1470 return uint16(b[0]) | uint16(b[1])<<8 1471 } 1472 1473 func Le32(b []byte) uint32 { 1474 return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 1475 } 1476 1477 func Le64(b []byte) uint64 { 1478 return uint64(Le32(b)) | uint64(Le32(b[4:]))<<32 1479 } 1480 1481 func Be16(b []byte) uint16 { 1482 return uint16(b[0])<<8 | uint16(b[1]) 1483 } 1484 1485 func Be32(b []byte) uint32 { 1486 return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]) 1487 } 1488 1489 type Chain struct { 1490 sym *LSym 1491 up *Chain 1492 limit int // limit on entry to sym 1493 } 1494 1495 var morestack *LSym 1496 1497 // TODO: Record enough information in new object files to 1498 // allow stack checks here. 1499 1500 func haslinkregister() bool { 1501 return Thearch.Thechar == '5' || Thearch.Thechar == '9' || Thearch.Thechar == '7' 1502 } 1503 1504 func callsize() int { 1505 if haslinkregister() { 1506 return 0 1507 } 1508 return Thearch.Regsize 1509 } 1510 1511 func dostkcheck() { 1512 var ch Chain 1513 1514 morestack = Linklookup(Ctxt, "runtime.morestack", 0) 1515 1516 // Every splitting function ensures that there are at least StackLimit 1517 // bytes available below SP when the splitting prologue finishes. 1518 // If the splitting function calls F, then F begins execution with 1519 // at least StackLimit - callsize() bytes available. 1520 // Check that every function behaves correctly with this amount 1521 // of stack, following direct calls in order to piece together chains 1522 // of non-splitting functions. 1523 ch.up = nil 1524 1525 ch.limit = obj.StackLimit - callsize() 1526 1527 // Check every function, but do the nosplit functions in a first pass, 1528 // to make the printed failure chains as short as possible. 1529 for s := Ctxt.Textp; s != nil; s = s.Next { 1530 // runtime.racesymbolizethunk is called from gcc-compiled C 1531 // code running on the operating system thread stack. 1532 // It uses more than the usual amount of stack but that's okay. 1533 if s.Name == "runtime.racesymbolizethunk" { 1534 continue 1535 } 1536 1537 if s.Nosplit != 0 { 1538 Ctxt.Cursym = s 1539 ch.sym = s 1540 stkcheck(&ch, 0) 1541 } 1542 } 1543 1544 for s := Ctxt.Textp; s != nil; s = s.Next { 1545 if s.Nosplit == 0 { 1546 Ctxt.Cursym = s 1547 ch.sym = s 1548 stkcheck(&ch, 0) 1549 } 1550 } 1551 } 1552 1553 func stkcheck(up *Chain, depth int) int { 1554 limit := up.limit 1555 s := up.sym 1556 1557 // Don't duplicate work: only need to consider each 1558 // function at top of safe zone once. 1559 top := limit == obj.StackLimit-callsize() 1560 if top { 1561 if s.Stkcheck != 0 { 1562 return 0 1563 } 1564 s.Stkcheck = 1 1565 } 1566 1567 if depth > 100 { 1568 Diag("nosplit stack check too deep") 1569 stkbroke(up, 0) 1570 return -1 1571 } 1572 1573 if s.External != 0 || s.Pcln == nil { 1574 // external function. 1575 // should never be called directly. 1576 // only diagnose the direct caller. 1577 // TODO(mwhudson): actually think about this. 1578 if depth == 1 && s.Type != obj.SXREF && !DynlinkingGo() { 1579 Diag("call to external function %s", s.Name) 1580 } 1581 return -1 1582 } 1583 1584 if limit < 0 { 1585 stkbroke(up, limit) 1586 return -1 1587 } 1588 1589 // morestack looks like it calls functions, 1590 // but it switches the stack pointer first. 1591 if s == morestack { 1592 return 0 1593 } 1594 1595 var ch Chain 1596 ch.up = up 1597 1598 if s.Nosplit == 0 { 1599 // Ensure we have enough stack to call morestack. 1600 ch.limit = limit - callsize() 1601 ch.sym = morestack 1602 if stkcheck(&ch, depth+1) < 0 { 1603 return -1 1604 } 1605 if !top { 1606 return 0 1607 } 1608 // Raise limit to allow frame. 1609 limit = int(obj.StackLimit + s.Locals) 1610 if haslinkregister() { 1611 limit += Thearch.Regsize 1612 } 1613 } 1614 1615 // Walk through sp adjustments in function, consuming relocs. 1616 ri := 0 1617 1618 endr := len(s.R) 1619 var ch1 Chain 1620 var pcsp Pciter 1621 var r *Reloc 1622 for pciterinit(Ctxt, &pcsp, &s.Pcln.Pcsp); pcsp.done == 0; pciternext(&pcsp) { 1623 // pcsp.value is in effect for [pcsp.pc, pcsp.nextpc). 1624 1625 // Check stack size in effect for this span. 1626 if int32(limit)-pcsp.value < 0 { 1627 stkbroke(up, int(int32(limit)-pcsp.value)) 1628 return -1 1629 } 1630 1631 // Process calls in this span. 1632 for ; ri < endr && uint32(s.R[ri].Off) < pcsp.nextpc; ri++ { 1633 r = &s.R[ri] 1634 switch r.Type { 1635 // Direct call. 1636 case obj.R_CALL, obj.R_CALLARM, obj.R_CALLARM64, obj.R_CALLPOWER: 1637 ch.limit = int(int32(limit) - pcsp.value - int32(callsize())) 1638 ch.sym = r.Sym 1639 if stkcheck(&ch, depth+1) < 0 { 1640 return -1 1641 } 1642 1643 // Indirect call. Assume it is a call to a splitting function, 1644 // so we have to make sure it can call morestack. 1645 // Arrange the data structures to report both calls, so that 1646 // if there is an error, stkprint shows all the steps involved. 1647 case obj.R_CALLIND: 1648 ch.limit = int(int32(limit) - pcsp.value - int32(callsize())) 1649 1650 ch.sym = nil 1651 ch1.limit = ch.limit - callsize() // for morestack in called prologue 1652 ch1.up = &ch 1653 ch1.sym = morestack 1654 if stkcheck(&ch1, depth+2) < 0 { 1655 return -1 1656 } 1657 } 1658 } 1659 } 1660 1661 return 0 1662 } 1663 1664 func stkbroke(ch *Chain, limit int) { 1665 Diag("nosplit stack overflow") 1666 stkprint(ch, limit) 1667 } 1668 1669 func stkprint(ch *Chain, limit int) { 1670 var name string 1671 1672 if ch.sym != nil { 1673 name = ch.sym.Name 1674 if ch.sym.Nosplit != 0 { 1675 name += " (nosplit)" 1676 } 1677 } else { 1678 name = "function pointer" 1679 } 1680 1681 if ch.up == nil { 1682 // top of chain. ch->sym != nil. 1683 if ch.sym.Nosplit != 0 { 1684 fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name) 1685 } else { 1686 fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name) 1687 } 1688 } else { 1689 stkprint(ch.up, ch.limit+callsize()) 1690 if !haslinkregister() { 1691 fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name) 1692 } 1693 } 1694 1695 if ch.limit != limit { 1696 fmt.Printf("\t%d\tafter %s uses %d\n", limit, name, ch.limit-limit) 1697 } 1698 } 1699 1700 func Cflush() { 1701 if err := coutbuf.Writer.Flush(); err != nil { 1702 Exitf("flushing %s: %v", coutbuf.f.Name(), err) 1703 } 1704 } 1705 1706 func Cpos() int64 { 1707 off, err := coutbuf.f.Seek(0, 1) 1708 if err != nil { 1709 Exitf("seeking in output [0, 1]: %v", err) 1710 } 1711 return off + int64(coutbuf.Buffered()) 1712 } 1713 1714 func Cseek(p int64) { 1715 Cflush() 1716 if _, err := coutbuf.f.Seek(p, 0); err != nil { 1717 Exitf("seeking in output [0, 1]: %v", err) 1718 } 1719 } 1720 1721 func Cwrite(p []byte) { 1722 coutbuf.Write(p) 1723 } 1724 1725 func Cput(c uint8) { 1726 coutbuf.WriteByte(c) 1727 } 1728 1729 func usage() { 1730 fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n") 1731 obj.Flagprint(2) 1732 Exit(2) 1733 } 1734 1735 func setheadtype(s string) { 1736 h := headtype(s) 1737 if h < 0 { 1738 Exitf("unknown header type -H %s", s) 1739 } 1740 1741 headstring = s 1742 HEADTYPE = int32(headtype(s)) 1743 } 1744 1745 func setinterp(s string) { 1746 Debug['I'] = 1 // denote cmdline interpreter override 1747 interpreter = s 1748 } 1749 1750 func doversion() { 1751 Exitf("version %s", obj.Getgoversion()) 1752 } 1753 1754 func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) { 1755 // These symbols won't show up in the first loop below because we 1756 // skip STEXT symbols. Normal STEXT symbols are emitted by walking textp. 1757 s := Linklookup(Ctxt, "runtime.text", 0) 1758 1759 if s.Type == obj.STEXT { 1760 put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil) 1761 } 1762 s = Linklookup(Ctxt, "runtime.etext", 0) 1763 if s.Type == obj.STEXT { 1764 put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil) 1765 } 1766 1767 for s := Ctxt.Allsym; s != nil; s = s.Allsym { 1768 if s.Hide != 0 || (s.Name[0] == '.' && s.Version == 0 && s.Name != ".rathole") { 1769 continue 1770 } 1771 switch s.Type & obj.SMASK { 1772 case obj.SCONST, 1773 obj.SRODATA, 1774 obj.SSYMTAB, 1775 obj.SPCLNTAB, 1776 obj.SINITARR, 1777 obj.SDATA, 1778 obj.SNOPTRDATA, 1779 obj.SELFROSECT, 1780 obj.SMACHOGOT, 1781 obj.STYPE, 1782 obj.SSTRING, 1783 obj.SGOSTRING, 1784 obj.SGOFUNC, 1785 obj.SGCBITS, 1786 obj.STYPERELRO, 1787 obj.SSTRINGRELRO, 1788 obj.SGOSTRINGRELRO, 1789 obj.SGOFUNCRELRO, 1790 obj.SGCBITSRELRO, 1791 obj.SRODATARELRO, 1792 obj.STYPELINK, 1793 obj.SWINDOWS: 1794 if !s.Reachable { 1795 continue 1796 } 1797 put(s, s.Name, 'D', Symaddr(s), s.Size, int(s.Version), s.Gotype) 1798 1799 case obj.SBSS, obj.SNOPTRBSS: 1800 if !s.Reachable { 1801 continue 1802 } 1803 if len(s.P) > 0 { 1804 Diag("%s should not be bss (size=%d type=%d special=%d)", s.Name, int(len(s.P)), s.Type, s.Special) 1805 } 1806 put(s, s.Name, 'B', Symaddr(s), s.Size, int(s.Version), s.Gotype) 1807 1808 case obj.SFILE: 1809 put(nil, s.Name, 'f', s.Value, 0, int(s.Version), nil) 1810 1811 case obj.SHOSTOBJ: 1812 if HEADTYPE == obj.Hwindows || Iself { 1813 put(s, s.Name, 'U', s.Value, 0, int(s.Version), nil) 1814 } 1815 1816 case obj.SDYNIMPORT: 1817 if !s.Reachable { 1818 continue 1819 } 1820 put(s, s.Extname, 'U', 0, 0, int(s.Version), nil) 1821 1822 case obj.STLSBSS: 1823 if Linkmode == LinkExternal && HEADTYPE != obj.Hopenbsd { 1824 put(s, s.Name, 't', Symaddr(s), s.Size, int(s.Version), s.Gotype) 1825 } 1826 } 1827 } 1828 1829 var a *Auto 1830 var off int32 1831 for s := Ctxt.Textp; s != nil; s = s.Next { 1832 put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), s.Gotype) 1833 1834 // NOTE(ality): acid can't produce a stack trace without .frame symbols 1835 put(nil, ".frame", 'm', int64(s.Locals)+int64(Thearch.Ptrsize), 0, 0, nil) 1836 1837 for a = s.Autom; a != nil; a = a.Link { 1838 // Emit a or p according to actual offset, even if label is wrong. 1839 // This avoids negative offsets, which cannot be encoded. 1840 if a.Name != obj.A_AUTO && a.Name != obj.A_PARAM { 1841 continue 1842 } 1843 1844 // compute offset relative to FP 1845 if a.Name == obj.A_PARAM { 1846 off = a.Aoffset 1847 } else { 1848 off = a.Aoffset - int32(Thearch.Ptrsize) 1849 } 1850 1851 // FP 1852 if off >= 0 { 1853 put(nil, a.Asym.Name, 'p', int64(off), 0, 0, a.Gotype) 1854 continue 1855 } 1856 1857 // SP 1858 if off <= int32(-Thearch.Ptrsize) { 1859 put(nil, a.Asym.Name, 'a', -(int64(off) + int64(Thearch.Ptrsize)), 0, 0, a.Gotype) 1860 continue 1861 } 1862 } 1863 } 1864 1865 // Otherwise, off is addressing the saved program counter. 1866 // Something underhanded is going on. Say nothing. 1867 if Debug['v'] != 0 || Debug['n'] != 0 { 1868 fmt.Fprintf(&Bso, "%5.2f symsize = %d\n", obj.Cputime(), uint32(Symsize)) 1869 } 1870 Bso.Flush() 1871 } 1872 1873 func Symaddr(s *LSym) int64 { 1874 if !s.Reachable { 1875 Diag("unreachable symbol in symaddr - %s", s.Name) 1876 } 1877 return s.Value 1878 } 1879 1880 func xdefine(p string, t int, v int64) { 1881 s := Linklookup(Ctxt, p, 0) 1882 s.Type = int16(t) 1883 s.Value = v 1884 s.Reachable = true 1885 s.Special = 1 1886 s.Local = true 1887 } 1888 1889 func datoff(addr int64) int64 { 1890 if uint64(addr) >= Segdata.Vaddr { 1891 return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff) 1892 } 1893 if uint64(addr) >= Segtext.Vaddr { 1894 return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff) 1895 } 1896 Diag("datoff %#x", addr) 1897 return 0 1898 } 1899 1900 func Entryvalue() int64 { 1901 a := INITENTRY 1902 if a[0] >= '0' && a[0] <= '9' { 1903 return atolwhex(a) 1904 } 1905 s := Linklookup(Ctxt, a, 0) 1906 if s.Type == 0 { 1907 return INITTEXT 1908 } 1909 if s.Type != obj.STEXT { 1910 Diag("entry not text: %s", s.Name) 1911 } 1912 return s.Value 1913 } 1914 1915 func undefsym(s *LSym) { 1916 var r *Reloc 1917 1918 Ctxt.Cursym = s 1919 for i := 0; i < len(s.R); i++ { 1920 r = &s.R[i] 1921 if r.Sym == nil { // happens for some external ARM relocs 1922 continue 1923 } 1924 if r.Sym.Type == obj.Sxxx || r.Sym.Type == obj.SXREF { 1925 Diag("undefined: %s", r.Sym.Name) 1926 } 1927 if !r.Sym.Reachable { 1928 Diag("use of unreachable symbol: %s", r.Sym.Name) 1929 } 1930 } 1931 } 1932 1933 func undef() { 1934 for s := Ctxt.Textp; s != nil; s = s.Next { 1935 undefsym(s) 1936 } 1937 for s := datap; s != nil; s = s.Next { 1938 undefsym(s) 1939 } 1940 if nerrors > 0 { 1941 errorexit() 1942 } 1943 } 1944 1945 func callgraph() { 1946 if Debug['c'] == 0 { 1947 return 1948 } 1949 1950 var i int 1951 var r *Reloc 1952 for s := Ctxt.Textp; s != nil; s = s.Next { 1953 for i = 0; i < len(s.R); i++ { 1954 r = &s.R[i] 1955 if r.Sym == nil { 1956 continue 1957 } 1958 if (r.Type == obj.R_CALL || r.Type == obj.R_CALLARM || r.Type == obj.R_CALLPOWER) && r.Sym.Type == obj.STEXT { 1959 fmt.Fprintf(&Bso, "%s calls %s\n", s.Name, r.Sym.Name) 1960 } 1961 } 1962 } 1963 } 1964 1965 func Diag(format string, args ...interface{}) { 1966 tn := "" 1967 sep := "" 1968 if Ctxt.Cursym != nil { 1969 tn = Ctxt.Cursym.Name 1970 sep = ": " 1971 } 1972 fmt.Printf("%s%s%s\n", tn, sep, fmt.Sprintf(format, args...)) 1973 nerrors++ 1974 if Debug['h'] != 0 { 1975 panic("error") 1976 } 1977 if nerrors > 20 { 1978 Exitf("too many errors") 1979 } 1980 } 1981 1982 func checkgo() { 1983 if Debug['C'] == 0 { 1984 return 1985 } 1986 1987 // TODO(rsc,khr): Eventually we want to get to no Go-called C functions at all, 1988 // which would simplify this logic quite a bit. 1989 1990 // Mark every Go-called C function with cfunc=2, recursively. 1991 var changed int 1992 var i int 1993 var r *Reloc 1994 var s *LSym 1995 for { 1996 changed = 0 1997 for s = Ctxt.Textp; s != nil; s = s.Next { 1998 if s.Cfunc == 0 || (s.Cfunc == 2 && s.Nosplit != 0) { 1999 for i = 0; i < len(s.R); i++ { 2000 r = &s.R[i] 2001 if r.Sym == nil { 2002 continue 2003 } 2004 if (r.Type == obj.R_CALL || r.Type == obj.R_CALLARM) && r.Sym.Type == obj.STEXT { 2005 if r.Sym.Cfunc == 1 { 2006 changed = 1 2007 r.Sym.Cfunc = 2 2008 } 2009 } 2010 } 2011 } 2012 } 2013 if changed == 0 { 2014 break 2015 } 2016 } 2017 2018 // Complain about Go-called C functions that can split the stack 2019 // (that can be preempted for garbage collection or trigger a stack copy). 2020 for s := Ctxt.Textp; s != nil; s = s.Next { 2021 if s.Cfunc == 0 || (s.Cfunc == 2 && s.Nosplit != 0) { 2022 for i = 0; i < len(s.R); i++ { 2023 r = &s.R[i] 2024 if r.Sym == nil { 2025 continue 2026 } 2027 if (r.Type == obj.R_CALL || r.Type == obj.R_CALLARM) && r.Sym.Type == obj.STEXT { 2028 if s.Cfunc == 0 && r.Sym.Cfunc == 2 && r.Sym.Nosplit == 0 { 2029 fmt.Printf("Go %s calls C %s\n", s.Name, r.Sym.Name) 2030 } else if s.Cfunc == 2 && s.Nosplit != 0 && r.Sym.Nosplit == 0 { 2031 fmt.Printf("Go calls C %s calls %s\n", s.Name, r.Sym.Name) 2032 } 2033 } 2034 } 2035 } 2036 } 2037 } 2038 2039 func Rnd(v int64, r int64) int64 { 2040 if r <= 0 { 2041 return v 2042 } 2043 v += r - 1 2044 c := v % r 2045 if c < 0 { 2046 c += r 2047 } 2048 v -= c 2049 return v 2050 }