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