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