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