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