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