github.com/sanprasirt/go@v0.0.0-20170607001320-a027466e4b6d/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) int 102 Archrelocvariant func(*Link, *Reloc, *Symbol, int64) int64 103 Trampoline func(*Link, *Reloc, *Symbol) 104 Asmb func(*Link) 105 Elfreloc1 func(*Link, *Reloc, int64) int 106 Elfsetupplt func(*Link) 107 Gentext func(*Link) 108 Machoreloc1 func(*Symbol, *Reloc, int64) int 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 pkgname = "__.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 iscgo = iscgo || ctxt.Library[i].Pkg == "runtime/cgo" 425 if ctxt.Library[i].Shlib == "" { 426 if ctxt.Debugvlog > 1 { 427 ctxt.Logf("%5.2f autolib: %s (from %s)\n", Cputime(), ctxt.Library[i].File, ctxt.Library[i].Objref) 428 } 429 objfile(ctxt, ctxt.Library[i]) 430 } 431 } 432 433 for i = 0; i < len(ctxt.Library); i++ { 434 if ctxt.Library[i].Shlib != "" { 435 if ctxt.Debugvlog > 1 { 436 ctxt.Logf("%5.2f autolib: %s (from %s)\n", Cputime(), ctxt.Library[i].Shlib, ctxt.Library[i].Objref) 437 } 438 ldshlibsyms(ctxt, ctxt.Library[i].Shlib) 439 } 440 } 441 442 // We now have enough information to determine the link mode. 443 determineLinkMode(ctxt) 444 445 // Recalculate pe parameters now that we have Linkmode set. 446 if Headtype == objabi.Hwindows { 447 Peinit(ctxt) 448 } 449 450 if Headtype == objabi.Hdarwin && Linkmode == LinkExternal { 451 *FlagTextAddr = 0 452 } 453 454 if Linkmode == LinkExternal && SysArch.Family == sys.PPC64 { 455 toc := ctxt.Syms.Lookup(".TOC.", 0) 456 toc.Type = SDYNIMPORT 457 } 458 459 if Linkmode == LinkExternal && !iscgo { 460 // This indicates a user requested -linkmode=external. 461 // The startup code uses an import of runtime/cgo to decide 462 // whether to initialize the TLS. So give it one. This could 463 // be handled differently but it's an unusual case. 464 loadinternal(ctxt, "runtime/cgo") 465 466 if i < len(ctxt.Library) { 467 if ctxt.Library[i].Shlib != "" { 468 ldshlibsyms(ctxt, ctxt.Library[i].Shlib) 469 } else { 470 if Buildmode == BuildmodeShared || *FlagLinkshared { 471 Exitf("cannot implicitly include runtime/cgo in a shared library") 472 } 473 objfile(ctxt, ctxt.Library[i]) 474 } 475 } 476 } 477 478 if Linkmode == LinkInternal { 479 // Drop all the cgo_import_static declarations. 480 // Turns out we won't be needing them. 481 for _, s := range ctxt.Syms.Allsym { 482 if s.Type == SHOSTOBJ { 483 // If a symbol was marked both 484 // cgo_import_static and cgo_import_dynamic, 485 // then we want to make it cgo_import_dynamic 486 // now. 487 if s.Extname != "" && s.Dynimplib != "" && !s.Attr.CgoExport() { 488 s.Type = SDYNIMPORT 489 } else { 490 s.Type = 0 491 } 492 } 493 } 494 } 495 496 tlsg := ctxt.Syms.Lookup("runtime.tlsg", 0) 497 498 // runtime.tlsg is used for external linking on platforms that do not define 499 // a variable to hold g in assembly (currently only intel). 500 if tlsg.Type == 0 { 501 tlsg.Type = STLSBSS 502 tlsg.Size = int64(SysArch.PtrSize) 503 } else if tlsg.Type != SDYNIMPORT { 504 Errorf(nil, "runtime declared tlsg variable %v", tlsg.Type) 505 } 506 tlsg.Attr |= AttrReachable 507 ctxt.Tlsg = tlsg 508 509 var moduledata *Symbol 510 if Buildmode == BuildmodePlugin { 511 moduledata = ctxt.Syms.Lookup("local.pluginmoduledata", 0) 512 moduledata.Attr |= AttrLocal 513 } else { 514 moduledata = ctxt.Syms.Lookup("runtime.firstmoduledata", 0) 515 } 516 if moduledata.Type != 0 && moduledata.Type != SDYNIMPORT { 517 // If the module (toolchain-speak for "executable or shared 518 // library") we are linking contains the runtime package, it 519 // will define the runtime.firstmoduledata symbol and we 520 // truncate it back to 0 bytes so we can define its entire 521 // contents in symtab.go:symtab(). 522 moduledata.Size = 0 523 524 // In addition, on ARM, the runtime depends on the linker 525 // recording the value of GOARM. 526 if SysArch.Family == sys.ARM { 527 s := ctxt.Syms.Lookup("runtime.goarm", 0) 528 s.Type = SRODATA 529 s.Size = 0 530 Adduint8(ctxt, s, uint8(objabi.GOARM)) 531 } 532 533 if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) { 534 s := ctxt.Syms.Lookup("runtime.framepointer_enabled", 0) 535 s.Type = SRODATA 536 s.Size = 0 537 Adduint8(ctxt, s, 1) 538 } 539 } else { 540 // If OTOH the module does not contain the runtime package, 541 // create a local symbol for the moduledata. 542 moduledata = ctxt.Syms.Lookup("local.moduledata", 0) 543 moduledata.Attr |= AttrLocal 544 } 545 // In all cases way we mark the moduledata as noptrdata to hide it from 546 // the GC. 547 moduledata.Type = SNOPTRDATA 548 moduledata.Attr |= AttrReachable 549 ctxt.Moduledata = moduledata 550 551 // Now that we know the link mode, trim the dynexp list. 552 x := AttrCgoExportDynamic 553 554 if Linkmode == LinkExternal { 555 x = AttrCgoExportStatic 556 } 557 w := 0 558 for i := 0; i < len(dynexp); i++ { 559 if dynexp[i].Attr&x != 0 { 560 dynexp[w] = dynexp[i] 561 w++ 562 } 563 } 564 dynexp = dynexp[:w] 565 566 // In internal link mode, read the host object files. 567 if Linkmode == LinkInternal { 568 hostobjs(ctxt) 569 570 // If we have any undefined symbols in external 571 // objects, try to read them from the libgcc file. 572 any := false 573 for _, s := range ctxt.Syms.Allsym { 574 for _, r := range s.R { 575 if r.Sym != nil && r.Sym.Type&SMASK == SXREF && r.Sym.Name != ".got" { 576 any = true 577 break 578 } 579 } 580 } 581 if any { 582 if *flagLibGCC == "" { 583 *flagLibGCC = ctxt.findLibPathCmd("--print-libgcc-file-name", "libgcc") 584 } 585 if *flagLibGCC != "none" { 586 hostArchive(ctxt, *flagLibGCC) 587 } 588 if Headtype == objabi.Hwindows { 589 if p := ctxt.findLibPath("libmingwex.a"); p != "none" { 590 hostArchive(ctxt, p) 591 } 592 if p := ctxt.findLibPath("libmingw32.a"); p != "none" { 593 hostArchive(ctxt, p) 594 } 595 // TODO: maybe do something similar to peimporteddlls to collect all lib names 596 // and try link them all to final exe just like libmingwex.a and libmingw32.a: 597 /* 598 for: 599 #cgo windows LDFLAGS: -lmsvcrt -lm 600 import: 601 libmsvcrt.a libm.a 602 */ 603 } 604 } 605 } else { 606 hostlinksetup() 607 } 608 609 // We've loaded all the code now. 610 ctxt.Loaded = true 611 612 // If there are no dynamic libraries needed, gcc disables dynamic linking. 613 // Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13) 614 // assumes that a dynamic binary always refers to at least one dynamic library. 615 // Rather than be a source of test cases for glibc, disable dynamic linking 616 // the same way that gcc would. 617 // 618 // Exception: on OS X, programs such as Shark only work with dynamic 619 // binaries, so leave it enabled on OS X (Mach-O) binaries. 620 // Also leave it enabled on Solaris which doesn't support 621 // statically linked binaries. 622 if Buildmode == BuildmodeExe { 623 if havedynamic == 0 && Headtype != objabi.Hdarwin && Headtype != objabi.Hsolaris { 624 *FlagD = true 625 } 626 } 627 628 // If package versioning is required, generate a hash of the 629 // the packages used in the link. 630 if Buildmode == BuildmodeShared || Buildmode == BuildmodePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil { 631 for i = 0; i < len(ctxt.Library); i++ { 632 if ctxt.Library[i].Shlib == "" { 633 genhash(ctxt, ctxt.Library[i]) 634 } 635 } 636 } 637 638 if SysArch == sys.Arch386 { 639 if (Buildmode == BuildmodeCArchive && Iself) || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE || ctxt.DynlinkingGo() { 640 got := ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0) 641 got.Type = SDYNIMPORT 642 got.Attr |= AttrReachable 643 } 644 } 645 646 importcycles() 647 648 // put symbols into Textp 649 // do it in postorder so that packages are laid down in dependency order 650 // internal first, then everything else 651 ctxt.Library = postorder(ctxt.Library) 652 for _, doInternal := range [2]bool{true, false} { 653 for _, lib := range ctxt.Library { 654 if isRuntimeDepPkg(lib.Pkg) != doInternal { 655 continue 656 } 657 ctxt.Textp = append(ctxt.Textp, lib.textp...) 658 for _, s := range lib.dupTextSyms { 659 if !s.Attr.OnList() { 660 ctxt.Textp = append(ctxt.Textp, s) 661 s.Attr |= AttrOnList 662 // dupok symbols may be defined in multiple packages. its 663 // associated package is chosen sort of arbitrarily (the 664 // first containing package that the linker loads). canonicalize 665 // it here to the package with which it will be laid down 666 // in text. 667 s.File = objabi.PathToPrefix(lib.Pkg) 668 } 669 } 670 } 671 } 672 673 if len(ctxt.Shlibs) > 0 { 674 // We might have overwritten some functions above (this tends to happen for the 675 // autogenerated type equality/hashing functions) and we don't want to generated 676 // pcln table entries for these any more so remove them from Textp. 677 textp := make([]*Symbol, 0, len(ctxt.Textp)) 678 for _, s := range ctxt.Textp { 679 if s.Type != SDYNIMPORT { 680 textp = append(textp, s) 681 } 682 } 683 ctxt.Textp = textp 684 } 685 } 686 687 /* 688 * look for the next file in an archive. 689 * adapted from libmach. 690 */ 691 func nextar(bp *bio.Reader, off int64, a *ArHdr) int64 { 692 if off&1 != 0 { 693 off++ 694 } 695 bp.Seek(off, 0) 696 var buf [SAR_HDR]byte 697 if n, err := io.ReadFull(bp, buf[:]); err != nil { 698 if n == 0 && err != io.EOF { 699 return -1 700 } 701 return 0 702 } 703 704 a.name = artrim(buf[0:16]) 705 a.date = artrim(buf[16:28]) 706 a.uid = artrim(buf[28:34]) 707 a.gid = artrim(buf[34:40]) 708 a.mode = artrim(buf[40:48]) 709 a.size = artrim(buf[48:58]) 710 a.fmag = artrim(buf[58:60]) 711 712 arsize := atolwhex(a.size) 713 if arsize&1 != 0 { 714 arsize++ 715 } 716 return arsize + SAR_HDR 717 } 718 719 func genhash(ctxt *Link, lib *Library) { 720 f, err := bio.Open(lib.File) 721 if err != nil { 722 Errorf(nil, "cannot open file %s for hash generation: %v", lib.File, err) 723 return 724 } 725 defer f.Close() 726 727 var arhdr ArHdr 728 l := nextar(f, int64(len(ARMAG)), &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 occurences 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.Index(pkgDefBytes, []byte("\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 objfile(ctxt *Link, lib *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, pkgname) { 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() { 926 if 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 coutbuf.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 coutbuf.w = bufio.NewWriter(f) 958 coutbuf.f = f 959 } 960 961 // hostobjCopy creates a copy of the object files in hostobj in a 962 // temporary directory. 963 func hostobjCopy() (paths []string) { 964 var wg sync.WaitGroup 965 sema := make(chan struct{}, runtime.NumCPU()) // limit open file descriptors 966 for i, h := range hostobj { 967 h := h 968 dst := filepath.Join(*flagTmpdir, fmt.Sprintf("%06d.o", i)) 969 paths = append(paths, dst) 970 971 wg.Add(1) 972 go func() { 973 sema <- struct{}{} 974 defer func() { 975 <-sema 976 wg.Done() 977 }() 978 f, err := os.Open(h.file) 979 if err != nil { 980 Exitf("cannot reopen %s: %v", h.pn, err) 981 } 982 if _, err := f.Seek(h.off, 0); err != nil { 983 Exitf("cannot seek %s: %v", h.pn, err) 984 } 985 986 w, err := os.Create(dst) 987 if err != nil { 988 Exitf("cannot create %s: %v", dst, err) 989 } 990 if _, err := io.CopyN(w, f, h.length); err != nil { 991 Exitf("cannot write %s: %v", dst, err) 992 } 993 if err := w.Close(); err != nil { 994 Exitf("cannot close %s: %v", dst, err) 995 } 996 }() 997 } 998 wg.Wait() 999 return paths 1000 } 1001 1002 // writeGDBLinkerScript creates gcc linker script file in temp 1003 // directory. writeGDBLinkerScript returns created file path. 1004 // The script is used to work around gcc bug 1005 // (see https://golang.org/issue/20183 for details). 1006 func writeGDBLinkerScript() string { 1007 name := "fix_debug_gdb_scripts.ld" 1008 path := filepath.Join(*flagTmpdir, name) 1009 src := `SECTIONS 1010 { 1011 .debug_gdb_scripts BLOCK(__section_alignment__) (NOLOAD) : 1012 { 1013 *(.debug_gdb_scripts) 1014 } 1015 } 1016 INSERT AFTER .debug_types; 1017 ` 1018 err := ioutil.WriteFile(path, []byte(src), 0666) 1019 if err != nil { 1020 Errorf(nil, "WriteFile %s failed: %v", name, err) 1021 } 1022 return path 1023 } 1024 1025 // archive builds a .a archive from the hostobj object files. 1026 func (ctxt *Link) archive() { 1027 if Buildmode != BuildmodeCArchive { 1028 return 1029 } 1030 1031 if *flagExtar == "" { 1032 *flagExtar = "ar" 1033 } 1034 1035 mayberemoveoutfile() 1036 1037 // Force the buffer to flush here so that external 1038 // tools will see a complete file. 1039 Cflush() 1040 if err := coutbuf.f.Close(); err != nil { 1041 Exitf("close: %v", err) 1042 } 1043 coutbuf.f = nil 1044 1045 argv := []string{*flagExtar, "-q", "-c", "-s", *flagOutfile} 1046 argv = append(argv, filepath.Join(*flagTmpdir, "go.o")) 1047 argv = append(argv, hostobjCopy()...) 1048 1049 if ctxt.Debugvlog != 0 { 1050 ctxt.Logf("archive: %s\n", strings.Join(argv, " ")) 1051 } 1052 1053 if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil { 1054 Exitf("running %s failed: %v\n%s", argv[0], err, out) 1055 } 1056 } 1057 1058 func (l *Link) hostlink() { 1059 if Linkmode != LinkExternal || nerrors > 0 { 1060 return 1061 } 1062 if Buildmode == BuildmodeCArchive { 1063 return 1064 } 1065 1066 if *flagExtld == "" { 1067 *flagExtld = "gcc" 1068 } 1069 1070 var argv []string 1071 argv = append(argv, *flagExtld) 1072 argv = append(argv, hostlinkArchArgs()...) 1073 1074 if !*FlagS && !debug_s { 1075 argv = append(argv, "-gdwarf-2") 1076 } else if Headtype == objabi.Hdarwin { 1077 // Recent versions of macOS print 1078 // ld: warning: option -s is obsolete and being ignored 1079 // so do not pass any arguments. 1080 } else { 1081 argv = append(argv, "-s") 1082 } 1083 1084 switch Headtype { 1085 case objabi.Hdarwin: 1086 argv = append(argv, "-Wl,-headerpad,1144") 1087 if l.DynlinkingGo() { 1088 argv = append(argv, "-Wl,-flat_namespace") 1089 } else if !SysArch.InFamily(sys.ARM64) { 1090 argv = append(argv, "-Wl,-no_pie") 1091 } 1092 case objabi.Hopenbsd: 1093 argv = append(argv, "-Wl,-nopie") 1094 case objabi.Hwindows: 1095 if windowsgui { 1096 argv = append(argv, "-mwindows") 1097 } else { 1098 argv = append(argv, "-mconsole") 1099 } 1100 } 1101 1102 switch Buildmode { 1103 case BuildmodeExe: 1104 if Headtype == objabi.Hdarwin { 1105 argv = append(argv, "-Wl,-pagezero_size,4000000") 1106 } 1107 case BuildmodePIE: 1108 if UseRelro() { 1109 argv = append(argv, "-Wl,-z,relro") 1110 } 1111 argv = append(argv, "-pie") 1112 case BuildmodeCShared: 1113 if Headtype == objabi.Hdarwin { 1114 argv = append(argv, "-dynamiclib") 1115 if SysArch.Family != sys.AMD64 { 1116 argv = append(argv, "-Wl,-read_only_relocs,suppress") 1117 } 1118 } else { 1119 // ELF. 1120 argv = append(argv, "-Wl,-Bsymbolic") 1121 if UseRelro() { 1122 argv = append(argv, "-Wl,-z,relro") 1123 } 1124 // Pass -z nodelete to mark the shared library as 1125 // non-closeable: a dlclose will do nothing. 1126 argv = append(argv, "-shared", "-Wl,-z,nodelete") 1127 } 1128 case BuildmodeShared: 1129 if UseRelro() { 1130 argv = append(argv, "-Wl,-z,relro") 1131 } 1132 argv = append(argv, "-shared") 1133 case BuildmodePlugin: 1134 if Headtype == objabi.Hdarwin { 1135 argv = append(argv, "-dynamiclib") 1136 } else { 1137 if UseRelro() { 1138 argv = append(argv, "-Wl,-z,relro") 1139 } 1140 argv = append(argv, "-shared") 1141 } 1142 } 1143 1144 if Iself && l.DynlinkingGo() { 1145 // We force all symbol resolution to be done at program startup 1146 // because lazy PLT resolution can use large amounts of stack at 1147 // times we cannot allow it to do so. 1148 argv = append(argv, "-Wl,-znow") 1149 1150 // Do not let the host linker generate COPY relocations. These 1151 // can move symbols out of sections that rely on stable offsets 1152 // from the beginning of the section (like STYPE). 1153 argv = append(argv, "-Wl,-znocopyreloc") 1154 1155 if SysArch.InFamily(sys.ARM, sys.ARM64) { 1156 // On ARM, the GNU linker will generate COPY relocations 1157 // even with -znocopyreloc set. 1158 // https://sourceware.org/bugzilla/show_bug.cgi?id=19962 1159 // 1160 // On ARM64, the GNU linker will fail instead of 1161 // generating COPY relocations. 1162 // 1163 // In both cases, switch to gold. 1164 argv = append(argv, "-fuse-ld=gold") 1165 1166 // If gold is not installed, gcc will silently switch 1167 // back to ld.bfd. So we parse the version information 1168 // and provide a useful error if gold is missing. 1169 cmd := exec.Command(*flagExtld, "-fuse-ld=gold", "-Wl,--version") 1170 if out, err := cmd.CombinedOutput(); err == nil { 1171 if !bytes.Contains(out, []byte("GNU gold")) { 1172 log.Fatalf("ARM external linker must be gold (issue #15696), but is not: %s", out) 1173 } 1174 } 1175 } 1176 } 1177 1178 if Iself && len(buildinfo) > 0 { 1179 argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo)) 1180 } 1181 1182 // On Windows, given -o foo, GCC will append ".exe" to produce 1183 // "foo.exe". We have decided that we want to honor the -o 1184 // option. To make this work, we append a '.' so that GCC 1185 // will decide that the file already has an extension. We 1186 // only want to do this when producing a Windows output file 1187 // on a Windows host. 1188 outopt := *flagOutfile 1189 if objabi.GOOS == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" { 1190 outopt += "." 1191 } 1192 argv = append(argv, "-o") 1193 argv = append(argv, outopt) 1194 1195 if rpath.val != "" { 1196 argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val)) 1197 } 1198 1199 // Force global symbols to be exported for dlopen, etc. 1200 if Iself { 1201 argv = append(argv, "-rdynamic") 1202 } 1203 1204 if strings.Contains(argv[0], "clang") { 1205 argv = append(argv, "-Qunused-arguments") 1206 } 1207 1208 argv = append(argv, filepath.Join(*flagTmpdir, "go.o")) 1209 argv = append(argv, hostobjCopy()...) 1210 1211 if *FlagLinkshared { 1212 seenDirs := make(map[string]bool) 1213 seenLibs := make(map[string]bool) 1214 addshlib := func(path string) { 1215 dir, base := filepath.Split(path) 1216 if !seenDirs[dir] { 1217 argv = append(argv, "-L"+dir) 1218 if !rpath.set { 1219 argv = append(argv, "-Wl,-rpath="+dir) 1220 } 1221 seenDirs[dir] = true 1222 } 1223 base = strings.TrimSuffix(base, ".so") 1224 base = strings.TrimPrefix(base, "lib") 1225 if !seenLibs[base] { 1226 argv = append(argv, "-l"+base) 1227 seenLibs[base] = true 1228 } 1229 } 1230 for _, shlib := range l.Shlibs { 1231 addshlib(shlib.Path) 1232 for _, dep := range shlib.Deps { 1233 if dep == "" { 1234 continue 1235 } 1236 libpath := findshlib(l, dep) 1237 if libpath != "" { 1238 addshlib(libpath) 1239 } 1240 } 1241 } 1242 } 1243 1244 argv = append(argv, ldflag...) 1245 1246 // When building a program with the default -buildmode=exe the 1247 // gc compiler generates code requires DT_TEXTREL in a 1248 // position independent executable (PIE). On systems where the 1249 // toolchain creates PIEs by default, and where DT_TEXTREL 1250 // does not work, the resulting programs will not run. See 1251 // issue #17847. To avoid this problem pass -no-pie to the 1252 // toolchain if it is supported. 1253 if Buildmode == BuildmodeExe { 1254 src := filepath.Join(*flagTmpdir, "trivial.c") 1255 if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil { 1256 Errorf(nil, "WriteFile trivial.c failed: %v", err) 1257 } 1258 cmd := exec.Command(argv[0], "-c", "-no-pie", "trivial.c") 1259 cmd.Dir = *flagTmpdir 1260 cmd.Env = append([]string{"LC_ALL=C"}, os.Environ()...) 1261 out, err := cmd.CombinedOutput() 1262 supported := err == nil && !bytes.Contains(out, []byte("unrecognized")) 1263 if supported { 1264 argv = append(argv, "-no-pie") 1265 } 1266 } 1267 1268 for _, p := range strings.Fields(*flagExtldflags) { 1269 argv = append(argv, p) 1270 1271 // clang, unlike GCC, passes -rdynamic to the linker 1272 // even when linking with -static, causing a linker 1273 // error when using GNU ld. So take out -rdynamic if 1274 // we added it. We do it in this order, rather than 1275 // only adding -rdynamic later, so that -*extldflags 1276 // can override -rdynamic without using -static. 1277 if Iself && p == "-static" { 1278 for i := range argv { 1279 if argv[i] == "-rdynamic" { 1280 argv[i] = "-static" 1281 } 1282 } 1283 } 1284 } 1285 if Headtype == objabi.Hwindows { 1286 // use gcc linker script to work around gcc bug 1287 // (see https://golang.org/issue/20183 for details). 1288 p := writeGDBLinkerScript() 1289 argv = append(argv, "-Wl,-T,"+p) 1290 // libmingw32 and libmingwex have some inter-dependencies, 1291 // so must use linker groups. 1292 argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group") 1293 argv = append(argv, peimporteddlls()...) 1294 } 1295 1296 if l.Debugvlog != 0 { 1297 l.Logf("%5.2f host link:", Cputime()) 1298 for _, v := range argv { 1299 l.Logf(" %q", v) 1300 } 1301 l.Logf("\n") 1302 } 1303 1304 if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil { 1305 Exitf("running %s failed: %v\n%s", argv[0], err, out) 1306 } else if len(out) > 0 { 1307 // always print external output even if the command is successful, so that we don't 1308 // swallow linker warnings (see https://golang.org/issue/17935). 1309 l.Logf("%s", out) 1310 } 1311 1312 if !*FlagS && !*FlagW && !debug_s && Headtype == objabi.Hdarwin { 1313 // Skip combining dwarf on arm. 1314 if !SysArch.InFamily(sys.ARM, sys.ARM64) { 1315 dsym := filepath.Join(*flagTmpdir, "go.dwarf") 1316 if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil { 1317 Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out) 1318 } 1319 // Skip combining if `dsymutil` didn't generate a file. See #11994. 1320 if _, err := os.Stat(dsym); os.IsNotExist(err) { 1321 return 1322 } 1323 // For os.Rename to work reliably, must be in same directory as outfile. 1324 combinedOutput := *flagOutfile + "~" 1325 if err := machoCombineDwarf(*flagOutfile, dsym, combinedOutput); err != nil { 1326 Exitf("%s: combining dwarf failed: %v", os.Args[0], err) 1327 } 1328 os.Remove(*flagOutfile) 1329 if err := os.Rename(combinedOutput, *flagOutfile); err != nil { 1330 Exitf("%s: %v", os.Args[0], err) 1331 } 1332 } 1333 } 1334 } 1335 1336 // hostlinkArchArgs returns arguments to pass to the external linker 1337 // based on the architecture. 1338 func hostlinkArchArgs() []string { 1339 switch SysArch.Family { 1340 case sys.I386: 1341 return []string{"-m32"} 1342 case sys.AMD64, sys.PPC64, sys.S390X: 1343 return []string{"-m64"} 1344 case sys.ARM: 1345 return []string{"-marm"} 1346 case sys.ARM64: 1347 // nothing needed 1348 case sys.MIPS64: 1349 return []string{"-mabi=64"} 1350 case sys.MIPS: 1351 return []string{"-mabi=32"} 1352 } 1353 return nil 1354 } 1355 1356 // ldobj loads an input object. If it is a host object (an object 1357 // compiled by a non-Go compiler) it returns the Hostobj pointer. If 1358 // it is a Go object, it returns nil. 1359 func ldobj(ctxt *Link, f *bio.Reader, lib *Library, length int64, pn string, file string, whence int) *Hostobj { 1360 pkg := objabi.PathToPrefix(lib.Pkg) 1361 1362 eof := f.Offset() + length 1363 start := f.Offset() 1364 c1 := bgetc(f) 1365 c2 := bgetc(f) 1366 c3 := bgetc(f) 1367 c4 := bgetc(f) 1368 f.Seek(start, 0) 1369 1370 magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4) 1371 if magic == 0x7f454c46 { // \x7F E L F 1372 return ldhostobj(ldelf, f, pkg, length, pn, file) 1373 } 1374 1375 if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe { 1376 return ldhostobj(ldmacho, f, pkg, length, pn, file) 1377 } 1378 1379 if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 { 1380 return ldhostobj(ldpe, f, pkg, length, pn, file) 1381 } 1382 1383 /* check the header */ 1384 line, err := f.ReadString('\n') 1385 if err != nil { 1386 Errorf(nil, "truncated object file: %s: %v", pn, err) 1387 return nil 1388 } 1389 1390 if !strings.HasPrefix(line, "go object ") { 1391 if strings.HasSuffix(pn, ".go") { 1392 Exitf("%s: uncompiled .go source file", pn) 1393 return nil 1394 } 1395 1396 if line == SysArch.Name { 1397 // old header format: just $GOOS 1398 Errorf(nil, "%s: stale object file", pn) 1399 return nil 1400 } 1401 1402 Errorf(nil, "%s: not an object file", pn) 1403 return nil 1404 } 1405 1406 // First, check that the basic GOOS, GOARCH, and Version match. 1407 t := fmt.Sprintf("%s %s %s ", objabi.GOOS, objabi.GOARCH, objabi.Version) 1408 1409 line = strings.TrimRight(line, "\n") 1410 if !strings.HasPrefix(line[10:]+" ", t) && !*flagF { 1411 Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], t) 1412 return nil 1413 } 1414 1415 // Second, check that longer lines match each other exactly, 1416 // so that the Go compiler and write additional information 1417 // that must be the same from run to run. 1418 if len(line) >= len(t)+10 { 1419 if theline == "" { 1420 theline = line[10:] 1421 } else if theline != line[10:] { 1422 Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], theline) 1423 return nil 1424 } 1425 } 1426 1427 /* skip over exports and other info -- ends with \n!\n */ 1428 import0 := f.Offset() 1429 1430 c1 = '\n' // the last line ended in \n 1431 c2 = bgetc(f) 1432 c3 = bgetc(f) 1433 for c1 != '\n' || c2 != '!' || c3 != '\n' { 1434 c1 = c2 1435 c2 = c3 1436 c3 = bgetc(f) 1437 if c3 == -1 { 1438 Errorf(nil, "truncated object file: %s", pn) 1439 return nil 1440 } 1441 } 1442 1443 import1 := f.Offset() 1444 1445 f.Seek(import0, 0) 1446 ldpkg(ctxt, f, pkg, import1-import0-2, pn, whence) // -2 for !\n 1447 f.Seek(import1, 0) 1448 1449 LoadObjFile(ctxt, f, lib, eof-f.Offset(), pn) 1450 return nil 1451 } 1452 1453 func readelfsymboldata(ctxt *Link, f *elf.File, sym *elf.Symbol) []byte { 1454 data := make([]byte, sym.Size) 1455 sect := f.Sections[sym.Section] 1456 if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE { 1457 Errorf(nil, "reading %s from non-data section", sym.Name) 1458 } 1459 n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr)) 1460 if uint64(n) != sym.Size { 1461 Errorf(nil, "reading contents of %s: %v", sym.Name, err) 1462 } 1463 return data 1464 } 1465 1466 func readwithpad(r io.Reader, sz int32) ([]byte, error) { 1467 data := make([]byte, Rnd(int64(sz), 4)) 1468 _, err := io.ReadFull(r, data) 1469 if err != nil { 1470 return nil, err 1471 } 1472 data = data[:sz] 1473 return data, nil 1474 } 1475 1476 func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) { 1477 for _, sect := range f.Sections { 1478 if sect.Type != elf.SHT_NOTE { 1479 continue 1480 } 1481 r := sect.Open() 1482 for { 1483 var namesize, descsize, noteType int32 1484 err := binary.Read(r, f.ByteOrder, &namesize) 1485 if err != nil { 1486 if err == io.EOF { 1487 break 1488 } 1489 return nil, fmt.Errorf("read namesize failed: %v", err) 1490 } 1491 err = binary.Read(r, f.ByteOrder, &descsize) 1492 if err != nil { 1493 return nil, fmt.Errorf("read descsize failed: %v", err) 1494 } 1495 err = binary.Read(r, f.ByteOrder, ¬eType) 1496 if err != nil { 1497 return nil, fmt.Errorf("read type failed: %v", err) 1498 } 1499 noteName, err := readwithpad(r, namesize) 1500 if err != nil { 1501 return nil, fmt.Errorf("read name failed: %v", err) 1502 } 1503 desc, err := readwithpad(r, descsize) 1504 if err != nil { 1505 return nil, fmt.Errorf("read desc failed: %v", err) 1506 } 1507 if string(name) == string(noteName) && typ == noteType { 1508 return desc, nil 1509 } 1510 } 1511 } 1512 return nil, nil 1513 } 1514 1515 func findshlib(ctxt *Link, shlib string) string { 1516 for _, libdir := range ctxt.Libdir { 1517 libpath := filepath.Join(libdir, shlib) 1518 if _, err := os.Stat(libpath); err == nil { 1519 return libpath 1520 } 1521 } 1522 Errorf(nil, "cannot find shared library: %s", shlib) 1523 return "" 1524 } 1525 1526 func ldshlibsyms(ctxt *Link, shlib string) { 1527 libpath := findshlib(ctxt, shlib) 1528 if libpath == "" { 1529 return 1530 } 1531 for _, processedlib := range ctxt.Shlibs { 1532 if processedlib.Path == libpath { 1533 return 1534 } 1535 } 1536 if ctxt.Debugvlog > 1 { 1537 ctxt.Logf("%5.2f ldshlibsyms: found library with name %s at %s\n", Cputime(), shlib, libpath) 1538 } 1539 1540 f, err := elf.Open(libpath) 1541 if err != nil { 1542 Errorf(nil, "cannot open shared library: %s", libpath) 1543 return 1544 } 1545 1546 hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG) 1547 if err != nil { 1548 Errorf(nil, "cannot read ABI hash from shared library %s: %v", libpath, err) 1549 return 1550 } 1551 1552 depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG) 1553 if err != nil { 1554 Errorf(nil, "cannot read dep list from shared library %s: %v", libpath, err) 1555 return 1556 } 1557 deps := strings.Split(string(depsbytes), "\n") 1558 1559 syms, err := f.DynamicSymbols() 1560 if err != nil { 1561 Errorf(nil, "cannot read symbols from shared library: %s", libpath) 1562 return 1563 } 1564 gcdataLocations := make(map[uint64]*Symbol) 1565 for _, elfsym := range syms { 1566 if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION { 1567 continue 1568 } 1569 lsym := ctxt.Syms.Lookup(elfsym.Name, 0) 1570 // Because loadlib above loads all .a files before loading any shared 1571 // libraries, any non-dynimport symbols we find that duplicate symbols 1572 // already loaded should be ignored (the symbols from the .a files 1573 // "win"). 1574 if lsym.Type != 0 && lsym.Type != SDYNIMPORT { 1575 continue 1576 } 1577 lsym.Type = SDYNIMPORT 1578 lsym.ElfType = elf.ST_TYPE(elfsym.Info) 1579 lsym.Size = int64(elfsym.Size) 1580 if elfsym.Section != elf.SHN_UNDEF { 1581 // Set .File for the library that actually defines the symbol. 1582 lsym.File = libpath 1583 // The decodetype_* functions in decodetype.go need access to 1584 // the type data. 1585 if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") { 1586 lsym.P = readelfsymboldata(ctxt, f, &elfsym) 1587 gcdataLocations[elfsym.Value+2*uint64(SysArch.PtrSize)+8+1*uint64(SysArch.PtrSize)] = lsym 1588 } 1589 } 1590 } 1591 gcdataAddresses := make(map[*Symbol]uint64) 1592 if SysArch.Family == sys.ARM64 { 1593 for _, sect := range f.Sections { 1594 if sect.Type == elf.SHT_RELA { 1595 var rela elf.Rela64 1596 rdr := sect.Open() 1597 for { 1598 err := binary.Read(rdr, f.ByteOrder, &rela) 1599 if err == io.EOF { 1600 break 1601 } else if err != nil { 1602 Errorf(nil, "reading relocation failed %v", err) 1603 return 1604 } 1605 t := elf.R_AARCH64(rela.Info & 0xffff) 1606 if t != elf.R_AARCH64_RELATIVE { 1607 continue 1608 } 1609 if lsym, ok := gcdataLocations[rela.Off]; ok { 1610 gcdataAddresses[lsym] = uint64(rela.Addend) 1611 } 1612 } 1613 } 1614 } 1615 } 1616 1617 ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdataAddresses: gcdataAddresses}) 1618 } 1619 1620 func addsection(seg *Segment, name string, rwx int) *Section { 1621 sect := new(Section) 1622 sect.Rwx = uint8(rwx) 1623 sect.Name = name 1624 sect.Seg = seg 1625 sect.Align = int32(SysArch.PtrSize) // everything is at least pointer-aligned 1626 seg.Sections = append(seg.Sections, sect) 1627 return sect 1628 } 1629 1630 func Le16(b []byte) uint16 { 1631 return uint16(b[0]) | uint16(b[1])<<8 1632 } 1633 1634 func Le32(b []byte) uint32 { 1635 return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 1636 } 1637 1638 func Le64(b []byte) uint64 { 1639 return uint64(Le32(b)) | uint64(Le32(b[4:]))<<32 1640 } 1641 1642 func Be16(b []byte) uint16 { 1643 return uint16(b[0])<<8 | uint16(b[1]) 1644 } 1645 1646 func Be32(b []byte) uint32 { 1647 return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]) 1648 } 1649 1650 type chain struct { 1651 sym *Symbol 1652 up *chain 1653 limit int // limit on entry to sym 1654 } 1655 1656 var morestack *Symbol 1657 1658 // TODO: Record enough information in new object files to 1659 // allow stack checks here. 1660 1661 func haslinkregister(ctxt *Link) bool { 1662 return ctxt.FixedFrameSize() != 0 1663 } 1664 1665 func callsize(ctxt *Link) int { 1666 if haslinkregister(ctxt) { 1667 return 0 1668 } 1669 return SysArch.RegSize 1670 } 1671 1672 func (ctxt *Link) dostkcheck() { 1673 var ch chain 1674 1675 morestack = ctxt.Syms.Lookup("runtime.morestack", 0) 1676 1677 // Every splitting function ensures that there are at least StackLimit 1678 // bytes available below SP when the splitting prologue finishes. 1679 // If the splitting function calls F, then F begins execution with 1680 // at least StackLimit - callsize() bytes available. 1681 // Check that every function behaves correctly with this amount 1682 // of stack, following direct calls in order to piece together chains 1683 // of non-splitting functions. 1684 ch.up = nil 1685 1686 ch.limit = objabi.StackLimit - callsize(ctxt) 1687 1688 // Check every function, but do the nosplit functions in a first pass, 1689 // to make the printed failure chains as short as possible. 1690 for _, s := range ctxt.Textp { 1691 // runtime.racesymbolizethunk is called from gcc-compiled C 1692 // code running on the operating system thread stack. 1693 // It uses more than the usual amount of stack but that's okay. 1694 if s.Name == "runtime.racesymbolizethunk" { 1695 continue 1696 } 1697 1698 if s.Attr.NoSplit() { 1699 ch.sym = s 1700 stkcheck(ctxt, &ch, 0) 1701 } 1702 } 1703 1704 for _, s := range ctxt.Textp { 1705 if !s.Attr.NoSplit() { 1706 ch.sym = s 1707 stkcheck(ctxt, &ch, 0) 1708 } 1709 } 1710 } 1711 1712 func stkcheck(ctxt *Link, up *chain, depth int) int { 1713 limit := up.limit 1714 s := up.sym 1715 1716 // Don't duplicate work: only need to consider each 1717 // function at top of safe zone once. 1718 top := limit == objabi.StackLimit-callsize(ctxt) 1719 if top { 1720 if s.Attr.StackCheck() { 1721 return 0 1722 } 1723 s.Attr |= AttrStackCheck 1724 } 1725 1726 if depth > 100 { 1727 Errorf(s, "nosplit stack check too deep") 1728 stkbroke(ctxt, up, 0) 1729 return -1 1730 } 1731 1732 if s.Attr.External() || s.FuncInfo == nil { 1733 // external function. 1734 // should never be called directly. 1735 // onlyctxt.Diagnose the direct caller. 1736 // TODO(mwhudson): actually think about this. 1737 if depth == 1 && s.Type != SXREF && !ctxt.DynlinkingGo() && 1738 Buildmode != BuildmodeCArchive && Buildmode != BuildmodePIE && Buildmode != BuildmodeCShared && Buildmode != BuildmodePlugin { 1739 1740 Errorf(s, "call to external function") 1741 } 1742 return -1 1743 } 1744 1745 if limit < 0 { 1746 stkbroke(ctxt, up, limit) 1747 return -1 1748 } 1749 1750 // morestack looks like it calls functions, 1751 // but it switches the stack pointer first. 1752 if s == morestack { 1753 return 0 1754 } 1755 1756 var ch chain 1757 ch.up = up 1758 1759 if !s.Attr.NoSplit() { 1760 // Ensure we have enough stack to call morestack. 1761 ch.limit = limit - callsize(ctxt) 1762 ch.sym = morestack 1763 if stkcheck(ctxt, &ch, depth+1) < 0 { 1764 return -1 1765 } 1766 if !top { 1767 return 0 1768 } 1769 // Raise limit to allow frame. 1770 locals := int32(0) 1771 if s.FuncInfo != nil { 1772 locals = s.FuncInfo.Locals 1773 } 1774 limit = int(objabi.StackLimit+locals) + int(ctxt.FixedFrameSize()) 1775 } 1776 1777 // Walk through sp adjustments in function, consuming relocs. 1778 ri := 0 1779 1780 endr := len(s.R) 1781 var ch1 chain 1782 var pcsp Pciter 1783 var r *Reloc 1784 for pciterinit(ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) { 1785 // pcsp.value is in effect for [pcsp.pc, pcsp.nextpc). 1786 1787 // Check stack size in effect for this span. 1788 if int32(limit)-pcsp.value < 0 { 1789 stkbroke(ctxt, up, int(int32(limit)-pcsp.value)) 1790 return -1 1791 } 1792 1793 // Process calls in this span. 1794 for ; ri < endr && uint32(s.R[ri].Off) < pcsp.nextpc; ri++ { 1795 r = &s.R[ri] 1796 switch r.Type { 1797 // Direct call. 1798 case objabi.R_CALL, objabi.R_CALLARM, objabi.R_CALLARM64, objabi.R_CALLPOWER, objabi.R_CALLMIPS: 1799 ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt))) 1800 ch.sym = r.Sym 1801 if stkcheck(ctxt, &ch, depth+1) < 0 { 1802 return -1 1803 } 1804 1805 // Indirect call. Assume it is a call to a splitting function, 1806 // so we have to make sure it can call morestack. 1807 // Arrange the data structures to report both calls, so that 1808 // if there is an error, stkprint shows all the steps involved. 1809 case objabi.R_CALLIND: 1810 ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt))) 1811 1812 ch.sym = nil 1813 ch1.limit = ch.limit - callsize(ctxt) // for morestack in called prologue 1814 ch1.up = &ch 1815 ch1.sym = morestack 1816 if stkcheck(ctxt, &ch1, depth+2) < 0 { 1817 return -1 1818 } 1819 } 1820 } 1821 } 1822 1823 return 0 1824 } 1825 1826 func stkbroke(ctxt *Link, ch *chain, limit int) { 1827 Errorf(ch.sym, "nosplit stack overflow") 1828 stkprint(ctxt, ch, limit) 1829 } 1830 1831 func stkprint(ctxt *Link, ch *chain, limit int) { 1832 var name string 1833 1834 if ch.sym != nil { 1835 name = ch.sym.Name 1836 if ch.sym.Attr.NoSplit() { 1837 name += " (nosplit)" 1838 } 1839 } else { 1840 name = "function pointer" 1841 } 1842 1843 if ch.up == nil { 1844 // top of chain. ch->sym != nil. 1845 if ch.sym.Attr.NoSplit() { 1846 fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name) 1847 } else { 1848 fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name) 1849 } 1850 } else { 1851 stkprint(ctxt, ch.up, ch.limit+callsize(ctxt)) 1852 if !haslinkregister(ctxt) { 1853 fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name) 1854 } 1855 } 1856 1857 if ch.limit != limit { 1858 fmt.Printf("\t%d\tafter %s uses %d\n", limit, name, ch.limit-limit) 1859 } 1860 } 1861 1862 func Cflush() { 1863 if err := coutbuf.w.Flush(); err != nil { 1864 Exitf("flushing %s: %v", coutbuf.f.Name(), err) 1865 } 1866 } 1867 1868 func Cseek(p int64) { 1869 if p == coutbuf.off { 1870 return 1871 } 1872 Cflush() 1873 if _, err := coutbuf.f.Seek(p, 0); err != nil { 1874 Exitf("seeking in output [0, 1]: %v", err) 1875 } 1876 coutbuf.off = p 1877 } 1878 1879 func Cwritestring(s string) { 1880 coutbuf.WriteString(s) 1881 } 1882 1883 func Cwrite(p []byte) { 1884 coutbuf.Write(p) 1885 } 1886 1887 func Cput(c uint8) { 1888 coutbuf.w.WriteByte(c) 1889 coutbuf.off++ 1890 } 1891 1892 func usage() { 1893 fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n") 1894 objabi.Flagprint(2) 1895 Exit(2) 1896 } 1897 1898 func doversion() { 1899 Exitf("version %s", objabi.Version) 1900 } 1901 1902 type SymbolType int8 1903 1904 const ( 1905 TextSym SymbolType = 'T' 1906 DataSym = 'D' 1907 BSSSym = 'B' 1908 UndefinedSym = 'U' 1909 TLSSym = 't' 1910 FileSym = 'f' 1911 FrameSym = 'm' 1912 ParamSym = 'p' 1913 AutoSym = 'a' 1914 ) 1915 1916 func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *Symbol)) { 1917 // These symbols won't show up in the first loop below because we 1918 // skip STEXT symbols. Normal STEXT symbols are emitted by walking textp. 1919 s := ctxt.Syms.Lookup("runtime.text", 0) 1920 if s.Type == STEXT { 1921 put(ctxt, s, s.Name, TextSym, s.Value, nil) 1922 } 1923 1924 n := 0 1925 1926 // Generate base addresses for all text sections if there are multiple 1927 for _, sect := range Segtext.Sections { 1928 if n == 0 { 1929 n++ 1930 continue 1931 } 1932 if sect.Name != ".text" { 1933 break 1934 } 1935 s = ctxt.Syms.ROLookup(fmt.Sprintf("runtime.text.%d", n), 0) 1936 if s == nil { 1937 break 1938 } 1939 if s.Type == STEXT { 1940 put(ctxt, s, s.Name, TextSym, s.Value, nil) 1941 } 1942 n++ 1943 } 1944 1945 s = ctxt.Syms.Lookup("runtime.etext", 0) 1946 if s.Type == STEXT { 1947 put(ctxt, s, s.Name, TextSym, s.Value, nil) 1948 } 1949 1950 for _, s := range ctxt.Syms.Allsym { 1951 if s.Attr.NotInSymbolTable() { 1952 continue 1953 } 1954 if (s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC." { 1955 continue 1956 } 1957 switch s.Type & SMASK { 1958 case SCONST, 1959 SRODATA, 1960 SSYMTAB, 1961 SPCLNTAB, 1962 SINITARR, 1963 SDATA, 1964 SNOPTRDATA, 1965 SELFROSECT, 1966 SMACHOGOT, 1967 STYPE, 1968 SSTRING, 1969 SGOSTRING, 1970 SGOFUNC, 1971 SGCBITS, 1972 STYPERELRO, 1973 SSTRINGRELRO, 1974 SGOSTRINGRELRO, 1975 SGOFUNCRELRO, 1976 SGCBITSRELRO, 1977 SRODATARELRO, 1978 STYPELINK, 1979 SITABLINK, 1980 SWINDOWS: 1981 if !s.Attr.Reachable() { 1982 continue 1983 } 1984 put(ctxt, s, s.Name, DataSym, Symaddr(s), s.Gotype) 1985 1986 case SBSS, SNOPTRBSS: 1987 if !s.Attr.Reachable() { 1988 continue 1989 } 1990 if len(s.P) > 0 { 1991 Errorf(s, "should not be bss (size=%d type=%v special=%v)", len(s.P), s.Type, s.Attr.Special()) 1992 } 1993 put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype) 1994 1995 case SFILE: 1996 put(ctxt, nil, s.Name, FileSym, s.Value, nil) 1997 1998 case SHOSTOBJ: 1999 if Headtype == objabi.Hwindows || Iself { 2000 put(ctxt, s, s.Name, UndefinedSym, s.Value, nil) 2001 } 2002 2003 case SDYNIMPORT: 2004 if !s.Attr.Reachable() { 2005 continue 2006 } 2007 put(ctxt, s, s.Extname, UndefinedSym, 0, nil) 2008 2009 case STLSBSS: 2010 if Linkmode == LinkExternal { 2011 put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype) 2012 } 2013 } 2014 } 2015 2016 var off int32 2017 for _, s := range ctxt.Textp { 2018 put(ctxt, s, s.Name, TextSym, s.Value, s.Gotype) 2019 2020 locals := int32(0) 2021 if s.FuncInfo != nil { 2022 locals = s.FuncInfo.Locals 2023 } 2024 // NOTE(ality): acid can't produce a stack trace without .frame symbols 2025 put(ctxt, nil, ".frame", FrameSym, int64(locals)+int64(SysArch.PtrSize), nil) 2026 2027 if s.FuncInfo == nil { 2028 continue 2029 } 2030 for _, a := range s.FuncInfo.Autom { 2031 // Emit a or p according to actual offset, even if label is wrong. 2032 // This avoids negative offsets, which cannot be encoded. 2033 if a.Name != objabi.A_AUTO && a.Name != objabi.A_PARAM { 2034 continue 2035 } 2036 2037 // compute offset relative to FP 2038 if a.Name == objabi.A_PARAM { 2039 off = a.Aoffset 2040 } else { 2041 off = a.Aoffset - int32(SysArch.PtrSize) 2042 } 2043 2044 // FP 2045 if off >= 0 { 2046 put(ctxt, nil, a.Asym.Name, ParamSym, int64(off), a.Gotype) 2047 continue 2048 } 2049 2050 // SP 2051 if off <= int32(-SysArch.PtrSize) { 2052 put(ctxt, nil, a.Asym.Name, AutoSym, -(int64(off) + int64(SysArch.PtrSize)), a.Gotype) 2053 continue 2054 } 2055 // Otherwise, off is addressing the saved program counter. 2056 // Something underhanded is going on. Say nothing. 2057 } 2058 } 2059 2060 if ctxt.Debugvlog != 0 || *flagN { 2061 ctxt.Logf("%5.2f symsize = %d\n", Cputime(), uint32(Symsize)) 2062 } 2063 } 2064 2065 func Symaddr(s *Symbol) int64 { 2066 if !s.Attr.Reachable() { 2067 Errorf(s, "unreachable symbol in symaddr") 2068 } 2069 return s.Value 2070 } 2071 2072 func (ctxt *Link) xdefine(p string, t SymKind, v int64) { 2073 s := ctxt.Syms.Lookup(p, 0) 2074 s.Type = t 2075 s.Value = v 2076 s.Attr |= AttrReachable 2077 s.Attr |= AttrSpecial 2078 s.Attr |= AttrLocal 2079 } 2080 2081 func datoff(s *Symbol, addr int64) int64 { 2082 if uint64(addr) >= Segdata.Vaddr { 2083 return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff) 2084 } 2085 if uint64(addr) >= Segtext.Vaddr { 2086 return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff) 2087 } 2088 Errorf(s, "invalid datoff %#x", addr) 2089 return 0 2090 } 2091 2092 func Entryvalue(ctxt *Link) int64 { 2093 a := *flagEntrySymbol 2094 if a[0] >= '0' && a[0] <= '9' { 2095 return atolwhex(a) 2096 } 2097 s := ctxt.Syms.Lookup(a, 0) 2098 if s.Type == 0 { 2099 return *FlagTextAddr 2100 } 2101 if s.Type != STEXT { 2102 Errorf(s, "entry not text") 2103 } 2104 return s.Value 2105 } 2106 2107 func undefsym(ctxt *Link, s *Symbol) { 2108 var r *Reloc 2109 2110 for i := 0; i < len(s.R); i++ { 2111 r = &s.R[i] 2112 if r.Sym == nil { // happens for some external ARM relocs 2113 continue 2114 } 2115 if r.Sym.Type == Sxxx || r.Sym.Type == SXREF { 2116 Errorf(s, "undefined: %q", r.Sym.Name) 2117 } 2118 if !r.Sym.Attr.Reachable() && r.Type != objabi.R_WEAKADDROFF { 2119 Errorf(s, "relocation target %q", r.Sym.Name) 2120 } 2121 } 2122 } 2123 2124 func (ctxt *Link) undef() { 2125 for _, s := range ctxt.Textp { 2126 undefsym(ctxt, s) 2127 } 2128 for _, s := range datap { 2129 undefsym(ctxt, s) 2130 } 2131 if nerrors > 0 { 2132 errorexit() 2133 } 2134 } 2135 2136 func (ctxt *Link) callgraph() { 2137 if !*FlagC { 2138 return 2139 } 2140 2141 var i int 2142 var r *Reloc 2143 for _, s := range ctxt.Textp { 2144 for i = 0; i < len(s.R); i++ { 2145 r = &s.R[i] 2146 if r.Sym == nil { 2147 continue 2148 } 2149 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 { 2150 ctxt.Logf("%s calls %s\n", s.Name, r.Sym.Name) 2151 } 2152 } 2153 } 2154 } 2155 2156 func Rnd(v int64, r int64) int64 { 2157 if r <= 0 { 2158 return v 2159 } 2160 v += r - 1 2161 c := v % r 2162 if c < 0 { 2163 c += r 2164 } 2165 v -= c 2166 return v 2167 } 2168 2169 func bgetc(r *bio.Reader) int { 2170 c, err := r.ReadByte() 2171 if err != nil { 2172 if err != io.EOF { 2173 log.Fatalf("reading input: %v", err) 2174 } 2175 return -1 2176 } 2177 return int(c) 2178 } 2179 2180 type markKind uint8 // for postorder traversal 2181 const ( 2182 unvisited markKind = iota 2183 visiting 2184 visited 2185 ) 2186 2187 func postorder(libs []*Library) []*Library { 2188 order := make([]*Library, 0, len(libs)) // hold the result 2189 mark := make(map[*Library]markKind, len(libs)) 2190 for _, lib := range libs { 2191 dfs(lib, mark, &order) 2192 } 2193 return order 2194 } 2195 2196 func dfs(lib *Library, mark map[*Library]markKind, order *[]*Library) { 2197 if mark[lib] == visited { 2198 return 2199 } 2200 if mark[lib] == visiting { 2201 panic("found import cycle while visiting " + lib.Pkg) 2202 } 2203 mark[lib] = visiting 2204 for _, i := range lib.imports { 2205 dfs(i, mark, order) 2206 } 2207 mark[lib] = visited 2208 *order = append(*order, lib) 2209 }