github.com/goproxy0/go@v0.0.0-20171111080102-49cc0c489d2c/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 ) 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 { 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 import0 := f.Offset() 1479 1480 c1 = '\n' // the last line ended in \n 1481 c2 = bgetc(f) 1482 c3 = bgetc(f) 1483 for c1 != '\n' || c2 != '!' || c3 != '\n' { 1484 c1 = c2 1485 c2 = c3 1486 c3 = bgetc(f) 1487 if c3 == -1 { 1488 Errorf(nil, "truncated object file: %s", pn) 1489 return nil 1490 } 1491 } 1492 1493 import1 := f.Offset() 1494 1495 f.Seek(import0, 0) 1496 ldpkg(ctxt, f, pkg, import1-import0-2, pn, whence) // -2 for !\n 1497 f.Seek(import1, 0) 1498 1499 objfile.Load(ctxt.Arch, ctxt.Syms, f, lib, eof-f.Offset(), pn) 1500 addImports(ctxt, lib, pn) 1501 return nil 1502 } 1503 1504 func readelfsymboldata(ctxt *Link, f *elf.File, sym *elf.Symbol) []byte { 1505 data := make([]byte, sym.Size) 1506 sect := f.Sections[sym.Section] 1507 if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE { 1508 Errorf(nil, "reading %s from non-data section", sym.Name) 1509 } 1510 n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr)) 1511 if uint64(n) != sym.Size { 1512 Errorf(nil, "reading contents of %s: %v", sym.Name, err) 1513 } 1514 return data 1515 } 1516 1517 func readwithpad(r io.Reader, sz int32) ([]byte, error) { 1518 data := make([]byte, Rnd(int64(sz), 4)) 1519 _, err := io.ReadFull(r, data) 1520 if err != nil { 1521 return nil, err 1522 } 1523 data = data[:sz] 1524 return data, nil 1525 } 1526 1527 func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) { 1528 for _, sect := range f.Sections { 1529 if sect.Type != elf.SHT_NOTE { 1530 continue 1531 } 1532 r := sect.Open() 1533 for { 1534 var namesize, descsize, noteType int32 1535 err := binary.Read(r, f.ByteOrder, &namesize) 1536 if err != nil { 1537 if err == io.EOF { 1538 break 1539 } 1540 return nil, fmt.Errorf("read namesize failed: %v", err) 1541 } 1542 err = binary.Read(r, f.ByteOrder, &descsize) 1543 if err != nil { 1544 return nil, fmt.Errorf("read descsize failed: %v", err) 1545 } 1546 err = binary.Read(r, f.ByteOrder, ¬eType) 1547 if err != nil { 1548 return nil, fmt.Errorf("read type failed: %v", err) 1549 } 1550 noteName, err := readwithpad(r, namesize) 1551 if err != nil { 1552 return nil, fmt.Errorf("read name failed: %v", err) 1553 } 1554 desc, err := readwithpad(r, descsize) 1555 if err != nil { 1556 return nil, fmt.Errorf("read desc failed: %v", err) 1557 } 1558 if string(name) == string(noteName) && typ == noteType { 1559 return desc, nil 1560 } 1561 } 1562 } 1563 return nil, nil 1564 } 1565 1566 func findshlib(ctxt *Link, shlib string) string { 1567 if filepath.IsAbs(shlib) { 1568 return shlib 1569 } 1570 for _, libdir := range ctxt.Libdir { 1571 libpath := filepath.Join(libdir, shlib) 1572 if _, err := os.Stat(libpath); err == nil { 1573 return libpath 1574 } 1575 } 1576 Errorf(nil, "cannot find shared library: %s", shlib) 1577 return "" 1578 } 1579 1580 func ldshlibsyms(ctxt *Link, shlib string) { 1581 var libpath string 1582 if filepath.IsAbs(shlib) { 1583 libpath = shlib 1584 shlib = filepath.Base(shlib) 1585 } else { 1586 libpath = findshlib(ctxt, shlib) 1587 if libpath == "" { 1588 return 1589 } 1590 } 1591 for _, processedlib := range ctxt.Shlibs { 1592 if processedlib.Path == libpath { 1593 return 1594 } 1595 } 1596 if ctxt.Debugvlog > 1 { 1597 ctxt.Logf("%5.2f ldshlibsyms: found library with name %s at %s\n", Cputime(), shlib, libpath) 1598 } 1599 1600 f, err := elf.Open(libpath) 1601 if err != nil { 1602 Errorf(nil, "cannot open shared library: %s", libpath) 1603 return 1604 } 1605 defer f.Close() 1606 1607 hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG) 1608 if err != nil { 1609 Errorf(nil, "cannot read ABI hash from shared library %s: %v", libpath, err) 1610 return 1611 } 1612 1613 depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG) 1614 if err != nil { 1615 Errorf(nil, "cannot read dep list from shared library %s: %v", libpath, err) 1616 return 1617 } 1618 var deps []string 1619 for _, dep := range strings.Split(string(depsbytes), "\n") { 1620 if dep == "" { 1621 continue 1622 } 1623 if !filepath.IsAbs(dep) { 1624 // If the dep can be interpreted as a path relative to the shlib 1625 // in which it was found, do that. Otherwise, we will leave it 1626 // to be resolved by libdir lookup. 1627 abs := filepath.Join(filepath.Dir(libpath), dep) 1628 if _, err := os.Stat(abs); err == nil { 1629 dep = abs 1630 } 1631 } 1632 deps = append(deps, dep) 1633 } 1634 1635 syms, err := f.DynamicSymbols() 1636 if err != nil { 1637 Errorf(nil, "cannot read symbols from shared library: %s", libpath) 1638 return 1639 } 1640 gcdataLocations := make(map[uint64]*sym.Symbol) 1641 for _, elfsym := range syms { 1642 if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION { 1643 continue 1644 } 1645 lsym := ctxt.Syms.Lookup(elfsym.Name, 0) 1646 // Because loadlib above loads all .a files before loading any shared 1647 // libraries, any non-dynimport symbols we find that duplicate symbols 1648 // already loaded should be ignored (the symbols from the .a files 1649 // "win"). 1650 if lsym.Type != 0 && lsym.Type != sym.SDYNIMPORT { 1651 continue 1652 } 1653 lsym.Type = sym.SDYNIMPORT 1654 lsym.ElfType = elf.ST_TYPE(elfsym.Info) 1655 lsym.Size = int64(elfsym.Size) 1656 if elfsym.Section != elf.SHN_UNDEF { 1657 // Set .File for the library that actually defines the symbol. 1658 lsym.File = libpath 1659 // The decodetype_* functions in decodetype.go need access to 1660 // the type data. 1661 if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") { 1662 lsym.P = readelfsymboldata(ctxt, f, &elfsym) 1663 gcdataLocations[elfsym.Value+2*uint64(ctxt.Arch.PtrSize)+8+1*uint64(ctxt.Arch.PtrSize)] = lsym 1664 } 1665 } 1666 } 1667 gcdataAddresses := make(map[*sym.Symbol]uint64) 1668 if ctxt.Arch.Family == sys.ARM64 { 1669 for _, sect := range f.Sections { 1670 if sect.Type == elf.SHT_RELA { 1671 var rela elf.Rela64 1672 rdr := sect.Open() 1673 for { 1674 err := binary.Read(rdr, f.ByteOrder, &rela) 1675 if err == io.EOF { 1676 break 1677 } else if err != nil { 1678 Errorf(nil, "reading relocation failed %v", err) 1679 return 1680 } 1681 t := elf.R_AARCH64(rela.Info & 0xffff) 1682 if t != elf.R_AARCH64_RELATIVE { 1683 continue 1684 } 1685 if lsym, ok := gcdataLocations[rela.Off]; ok { 1686 gcdataAddresses[lsym] = uint64(rela.Addend) 1687 } 1688 } 1689 } 1690 } 1691 } 1692 1693 ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdataAddresses: gcdataAddresses}) 1694 } 1695 1696 func addsection(arch *sys.Arch, seg *sym.Segment, name string, rwx int) *sym.Section { 1697 sect := new(sym.Section) 1698 sect.Rwx = uint8(rwx) 1699 sect.Name = name 1700 sect.Seg = seg 1701 sect.Align = int32(arch.PtrSize) // everything is at least pointer-aligned 1702 seg.Sections = append(seg.Sections, sect) 1703 return sect 1704 } 1705 1706 func Le16(b []byte) uint16 { 1707 return uint16(b[0]) | uint16(b[1])<<8 1708 } 1709 1710 func Le32(b []byte) uint32 { 1711 return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 1712 } 1713 1714 func Le64(b []byte) uint64 { 1715 return uint64(Le32(b)) | uint64(Le32(b[4:]))<<32 1716 } 1717 1718 func Be16(b []byte) uint16 { 1719 return uint16(b[0])<<8 | uint16(b[1]) 1720 } 1721 1722 func Be32(b []byte) uint32 { 1723 return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]) 1724 } 1725 1726 type chain struct { 1727 sym *sym.Symbol 1728 up *chain 1729 limit int // limit on entry to sym 1730 } 1731 1732 var morestack *sym.Symbol 1733 1734 // TODO: Record enough information in new object files to 1735 // allow stack checks here. 1736 1737 func haslinkregister(ctxt *Link) bool { 1738 return ctxt.FixedFrameSize() != 0 1739 } 1740 1741 func callsize(ctxt *Link) int { 1742 if haslinkregister(ctxt) { 1743 return 0 1744 } 1745 return ctxt.Arch.RegSize 1746 } 1747 1748 func (ctxt *Link) dostkcheck() { 1749 var ch chain 1750 1751 morestack = ctxt.Syms.Lookup("runtime.morestack", 0) 1752 1753 // Every splitting function ensures that there are at least StackLimit 1754 // bytes available below SP when the splitting prologue finishes. 1755 // If the splitting function calls F, then F begins execution with 1756 // at least StackLimit - callsize() bytes available. 1757 // Check that every function behaves correctly with this amount 1758 // of stack, following direct calls in order to piece together chains 1759 // of non-splitting functions. 1760 ch.up = nil 1761 1762 ch.limit = objabi.StackLimit - callsize(ctxt) 1763 1764 // Check every function, but do the nosplit functions in a first pass, 1765 // to make the printed failure chains as short as possible. 1766 for _, s := range ctxt.Textp { 1767 // runtime.racesymbolizethunk is called from gcc-compiled C 1768 // code running on the operating system thread stack. 1769 // It uses more than the usual amount of stack but that's okay. 1770 if s.Name == "runtime.racesymbolizethunk" { 1771 continue 1772 } 1773 1774 if s.Attr.NoSplit() { 1775 ch.sym = s 1776 stkcheck(ctxt, &ch, 0) 1777 } 1778 } 1779 1780 for _, s := range ctxt.Textp { 1781 if !s.Attr.NoSplit() { 1782 ch.sym = s 1783 stkcheck(ctxt, &ch, 0) 1784 } 1785 } 1786 } 1787 1788 func stkcheck(ctxt *Link, up *chain, depth int) int { 1789 limit := up.limit 1790 s := up.sym 1791 1792 // Don't duplicate work: only need to consider each 1793 // function at top of safe zone once. 1794 top := limit == objabi.StackLimit-callsize(ctxt) 1795 if top { 1796 if s.Attr.StackCheck() { 1797 return 0 1798 } 1799 s.Attr |= sym.AttrStackCheck 1800 } 1801 1802 if depth > 100 { 1803 Errorf(s, "nosplit stack check too deep") 1804 stkbroke(ctxt, up, 0) 1805 return -1 1806 } 1807 1808 if s.Attr.External() || s.FuncInfo == nil { 1809 // external function. 1810 // should never be called directly. 1811 // onlyctxt.Diagnose the direct caller. 1812 // TODO(mwhudson): actually think about this. 1813 if depth == 1 && s.Type != sym.SXREF && !ctxt.DynlinkingGo() && 1814 ctxt.BuildMode != BuildModeCArchive && ctxt.BuildMode != BuildModePIE && ctxt.BuildMode != BuildModeCShared && ctxt.BuildMode != BuildModePlugin { 1815 1816 Errorf(s, "call to external function") 1817 } 1818 return -1 1819 } 1820 1821 if limit < 0 { 1822 stkbroke(ctxt, up, limit) 1823 return -1 1824 } 1825 1826 // morestack looks like it calls functions, 1827 // but it switches the stack pointer first. 1828 if s == morestack { 1829 return 0 1830 } 1831 1832 var ch chain 1833 ch.up = up 1834 1835 if !s.Attr.NoSplit() { 1836 // Ensure we have enough stack to call morestack. 1837 ch.limit = limit - callsize(ctxt) 1838 ch.sym = morestack 1839 if stkcheck(ctxt, &ch, depth+1) < 0 { 1840 return -1 1841 } 1842 if !top { 1843 return 0 1844 } 1845 // Raise limit to allow frame. 1846 locals := int32(0) 1847 if s.FuncInfo != nil { 1848 locals = s.FuncInfo.Locals 1849 } 1850 limit = int(objabi.StackLimit+locals) + int(ctxt.FixedFrameSize()) 1851 } 1852 1853 // Walk through sp adjustments in function, consuming relocs. 1854 ri := 0 1855 1856 endr := len(s.R) 1857 var ch1 chain 1858 var pcsp Pciter 1859 var r *sym.Reloc 1860 for pciterinit(ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) { 1861 // pcsp.value is in effect for [pcsp.pc, pcsp.nextpc). 1862 1863 // Check stack size in effect for this span. 1864 if int32(limit)-pcsp.value < 0 { 1865 stkbroke(ctxt, up, int(int32(limit)-pcsp.value)) 1866 return -1 1867 } 1868 1869 // Process calls in this span. 1870 for ; ri < endr && uint32(s.R[ri].Off) < pcsp.nextpc; ri++ { 1871 r = &s.R[ri] 1872 switch r.Type { 1873 // Direct call. 1874 case objabi.R_CALL, objabi.R_CALLARM, objabi.R_CALLARM64, objabi.R_CALLPOWER, objabi.R_CALLMIPS: 1875 ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt))) 1876 ch.sym = r.Sym 1877 if stkcheck(ctxt, &ch, depth+1) < 0 { 1878 return -1 1879 } 1880 1881 // Indirect call. Assume it is a call to a splitting function, 1882 // so we have to make sure it can call morestack. 1883 // Arrange the data structures to report both calls, so that 1884 // if there is an error, stkprint shows all the steps involved. 1885 case objabi.R_CALLIND: 1886 ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt))) 1887 1888 ch.sym = nil 1889 ch1.limit = ch.limit - callsize(ctxt) // for morestack in called prologue 1890 ch1.up = &ch 1891 ch1.sym = morestack 1892 if stkcheck(ctxt, &ch1, depth+2) < 0 { 1893 return -1 1894 } 1895 } 1896 } 1897 } 1898 1899 return 0 1900 } 1901 1902 func stkbroke(ctxt *Link, ch *chain, limit int) { 1903 Errorf(ch.sym, "nosplit stack overflow") 1904 stkprint(ctxt, ch, limit) 1905 } 1906 1907 func stkprint(ctxt *Link, ch *chain, limit int) { 1908 var name string 1909 1910 if ch.sym != nil { 1911 name = ch.sym.Name 1912 if ch.sym.Attr.NoSplit() { 1913 name += " (nosplit)" 1914 } 1915 } else { 1916 name = "function pointer" 1917 } 1918 1919 if ch.up == nil { 1920 // top of chain. ch->sym != nil. 1921 if ch.sym.Attr.NoSplit() { 1922 fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name) 1923 } else { 1924 fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name) 1925 } 1926 } else { 1927 stkprint(ctxt, ch.up, ch.limit+callsize(ctxt)) 1928 if !haslinkregister(ctxt) { 1929 fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name) 1930 } 1931 } 1932 1933 if ch.limit != limit { 1934 fmt.Printf("\t%d\tafter %s uses %d\n", limit, name, ch.limit-limit) 1935 } 1936 } 1937 1938 func usage() { 1939 fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n") 1940 objabi.Flagprint(2) 1941 Exit(2) 1942 } 1943 1944 func doversion() { 1945 Exitf("version %s", objabi.Version) 1946 } 1947 1948 type SymbolType int8 1949 1950 const ( 1951 TextSym SymbolType = 'T' 1952 DataSym = 'D' 1953 BSSSym = 'B' 1954 UndefinedSym = 'U' 1955 TLSSym = 't' 1956 FrameSym = 'm' 1957 ParamSym = 'p' 1958 AutoSym = 'a' 1959 ) 1960 1961 func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int64, *sym.Symbol)) { 1962 // These symbols won't show up in the first loop below because we 1963 // skip sym.STEXT symbols. Normal sym.STEXT symbols are emitted by walking textp. 1964 s := ctxt.Syms.Lookup("runtime.text", 0) 1965 if s.Type == sym.STEXT { 1966 // We've already included this symbol in ctxt.Textp 1967 // if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin. 1968 // See data.go:/textaddress 1969 if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) { 1970 put(ctxt, s, s.Name, TextSym, s.Value, nil) 1971 } 1972 } 1973 1974 n := 0 1975 1976 // Generate base addresses for all text sections if there are multiple 1977 for _, sect := range Segtext.Sections { 1978 if n == 0 { 1979 n++ 1980 continue 1981 } 1982 if sect.Name != ".text" { 1983 break 1984 } 1985 s = ctxt.Syms.ROLookup(fmt.Sprintf("runtime.text.%d", n), 0) 1986 if s == nil { 1987 break 1988 } 1989 if s.Type == sym.STEXT { 1990 put(ctxt, s, s.Name, TextSym, s.Value, nil) 1991 } 1992 n++ 1993 } 1994 1995 s = ctxt.Syms.Lookup("runtime.etext", 0) 1996 if s.Type == sym.STEXT { 1997 // We've already included this symbol in ctxt.Textp 1998 // if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin. 1999 // See data.go:/textaddress 2000 if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) { 2001 put(ctxt, s, s.Name, TextSym, s.Value, nil) 2002 } 2003 } 2004 2005 for _, s := range ctxt.Syms.Allsym { 2006 if s.Attr.NotInSymbolTable() { 2007 continue 2008 } 2009 if (s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC." { 2010 continue 2011 } 2012 switch s.Type { 2013 case sym.SCONST, 2014 sym.SRODATA, 2015 sym.SSYMTAB, 2016 sym.SPCLNTAB, 2017 sym.SINITARR, 2018 sym.SDATA, 2019 sym.SNOPTRDATA, 2020 sym.SELFROSECT, 2021 sym.SMACHOGOT, 2022 sym.STYPE, 2023 sym.SSTRING, 2024 sym.SGOSTRING, 2025 sym.SGOFUNC, 2026 sym.SGCBITS, 2027 sym.STYPERELRO, 2028 sym.SSTRINGRELRO, 2029 sym.SGOSTRINGRELRO, 2030 sym.SGOFUNCRELRO, 2031 sym.SGCBITSRELRO, 2032 sym.SRODATARELRO, 2033 sym.STYPELINK, 2034 sym.SITABLINK, 2035 sym.SWINDOWS: 2036 if !s.Attr.Reachable() { 2037 continue 2038 } 2039 put(ctxt, s, s.Name, DataSym, Symaddr(s), s.Gotype) 2040 2041 case sym.SBSS, sym.SNOPTRBSS: 2042 if !s.Attr.Reachable() { 2043 continue 2044 } 2045 if len(s.P) > 0 { 2046 Errorf(s, "should not be bss (size=%d type=%v special=%v)", len(s.P), s.Type, s.Attr.Special()) 2047 } 2048 put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype) 2049 2050 case sym.SHOSTOBJ: 2051 if ctxt.HeadType == objabi.Hwindows || ctxt.IsELF { 2052 put(ctxt, s, s.Name, UndefinedSym, s.Value, nil) 2053 } 2054 2055 case sym.SDYNIMPORT: 2056 if !s.Attr.Reachable() { 2057 continue 2058 } 2059 put(ctxt, s, s.Extname, UndefinedSym, 0, nil) 2060 2061 case sym.STLSBSS: 2062 if ctxt.LinkMode == LinkExternal { 2063 put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype) 2064 } 2065 } 2066 } 2067 2068 var off int32 2069 for _, s := range ctxt.Textp { 2070 put(ctxt, s, s.Name, TextSym, s.Value, s.Gotype) 2071 2072 locals := int32(0) 2073 if s.FuncInfo != nil { 2074 locals = s.FuncInfo.Locals 2075 } 2076 // NOTE(ality): acid can't produce a stack trace without .frame symbols 2077 put(ctxt, nil, ".frame", FrameSym, int64(locals)+int64(ctxt.Arch.PtrSize), nil) 2078 2079 if s.FuncInfo == nil { 2080 continue 2081 } 2082 for _, a := range s.FuncInfo.Autom { 2083 // Emit a or p according to actual offset, even if label is wrong. 2084 // This avoids negative offsets, which cannot be encoded. 2085 if a.Name != objabi.A_AUTO && a.Name != objabi.A_PARAM { 2086 continue 2087 } 2088 2089 // compute offset relative to FP 2090 if a.Name == objabi.A_PARAM { 2091 off = a.Aoffset 2092 } else { 2093 off = a.Aoffset - int32(ctxt.Arch.PtrSize) 2094 } 2095 2096 // FP 2097 if off >= 0 { 2098 put(ctxt, nil, a.Asym.Name, ParamSym, int64(off), a.Gotype) 2099 continue 2100 } 2101 2102 // SP 2103 if off <= int32(-ctxt.Arch.PtrSize) { 2104 put(ctxt, nil, a.Asym.Name, AutoSym, -(int64(off) + int64(ctxt.Arch.PtrSize)), a.Gotype) 2105 continue 2106 } 2107 // Otherwise, off is addressing the saved program counter. 2108 // Something underhanded is going on. Say nothing. 2109 } 2110 } 2111 2112 if ctxt.Debugvlog != 0 || *flagN { 2113 ctxt.Logf("%5.2f symsize = %d\n", Cputime(), uint32(Symsize)) 2114 } 2115 } 2116 2117 func Symaddr(s *sym.Symbol) int64 { 2118 if !s.Attr.Reachable() { 2119 Errorf(s, "unreachable symbol in symaddr") 2120 } 2121 return s.Value 2122 } 2123 2124 func (ctxt *Link) xdefine(p string, t sym.SymKind, v int64) { 2125 s := ctxt.Syms.Lookup(p, 0) 2126 s.Type = t 2127 s.Value = v 2128 s.Attr |= sym.AttrReachable 2129 s.Attr |= sym.AttrSpecial 2130 s.Attr |= sym.AttrLocal 2131 } 2132 2133 func datoff(s *sym.Symbol, addr int64) int64 { 2134 if uint64(addr) >= Segdata.Vaddr { 2135 return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff) 2136 } 2137 if uint64(addr) >= Segtext.Vaddr { 2138 return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff) 2139 } 2140 Errorf(s, "invalid datoff %#x", addr) 2141 return 0 2142 } 2143 2144 func Entryvalue(ctxt *Link) int64 { 2145 a := *flagEntrySymbol 2146 if a[0] >= '0' && a[0] <= '9' { 2147 return atolwhex(a) 2148 } 2149 s := ctxt.Syms.Lookup(a, 0) 2150 if s.Type == 0 { 2151 return *FlagTextAddr 2152 } 2153 if s.Type != sym.STEXT { 2154 Errorf(s, "entry not text") 2155 } 2156 return s.Value 2157 } 2158 2159 func undefsym(ctxt *Link, s *sym.Symbol) { 2160 var r *sym.Reloc 2161 2162 for i := 0; i < len(s.R); i++ { 2163 r = &s.R[i] 2164 if r.Sym == nil { // happens for some external ARM relocs 2165 continue 2166 } 2167 // TODO(mwhudson): the test of VisibilityHidden here probably doesn't make 2168 // sense and should be removed when someone has thought about it properly. 2169 if (r.Sym.Type == sym.Sxxx || r.Sym.Type == sym.SXREF) && !r.Sym.Attr.VisibilityHidden() { 2170 Errorf(s, "undefined: %q", r.Sym.Name) 2171 } 2172 if !r.Sym.Attr.Reachable() && r.Type != objabi.R_WEAKADDROFF { 2173 Errorf(s, "relocation target %q", r.Sym.Name) 2174 } 2175 } 2176 } 2177 2178 func (ctxt *Link) undef() { 2179 for _, s := range ctxt.Textp { 2180 undefsym(ctxt, s) 2181 } 2182 for _, s := range datap { 2183 undefsym(ctxt, s) 2184 } 2185 if nerrors > 0 { 2186 errorexit() 2187 } 2188 } 2189 2190 func (ctxt *Link) callgraph() { 2191 if !*FlagC { 2192 return 2193 } 2194 2195 var i int 2196 var r *sym.Reloc 2197 for _, s := range ctxt.Textp { 2198 for i = 0; i < len(s.R); i++ { 2199 r = &s.R[i] 2200 if r.Sym == nil { 2201 continue 2202 } 2203 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 { 2204 ctxt.Logf("%s calls %s\n", s.Name, r.Sym.Name) 2205 } 2206 } 2207 } 2208 } 2209 2210 func Rnd(v int64, r int64) int64 { 2211 if r <= 0 { 2212 return v 2213 } 2214 v += r - 1 2215 c := v % r 2216 if c < 0 { 2217 c += r 2218 } 2219 v -= c 2220 return v 2221 } 2222 2223 func bgetc(r *bio.Reader) int { 2224 c, err := r.ReadByte() 2225 if err != nil { 2226 if err != io.EOF { 2227 log.Fatalf("reading input: %v", err) 2228 } 2229 return -1 2230 } 2231 return int(c) 2232 } 2233 2234 type markKind uint8 // for postorder traversal 2235 const ( 2236 unvisited markKind = iota 2237 visiting 2238 visited 2239 ) 2240 2241 func postorder(libs []*sym.Library) []*sym.Library { 2242 order := make([]*sym.Library, 0, len(libs)) // hold the result 2243 mark := make(map[*sym.Library]markKind, len(libs)) 2244 for _, lib := range libs { 2245 dfs(lib, mark, &order) 2246 } 2247 return order 2248 } 2249 2250 func dfs(lib *sym.Library, mark map[*sym.Library]markKind, order *[]*sym.Library) { 2251 if mark[lib] == visited { 2252 return 2253 } 2254 if mark[lib] == visiting { 2255 panic("found import cycle while visiting " + lib.Pkg) 2256 } 2257 mark[lib] = visiting 2258 for _, i := range lib.Imports { 2259 dfs(i, mark, order) 2260 } 2261 mark[lib] = visited 2262 *order = append(*order, lib) 2263 }