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