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