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