github.com/karrick/go@v0.0.0-20170817181416-d5b0ec858b37/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 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 occurences 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, pkgname) { 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 } else if !SysArch.InFamily(sys.ARM64) && Buildmode != BuildmodePIE { 1100 argv = append(argv, "-Wl,-no_pie") 1101 } 1102 case objabi.Hopenbsd: 1103 argv = append(argv, "-Wl,-nopie") 1104 case objabi.Hwindows: 1105 if windowsgui { 1106 argv = append(argv, "-mwindows") 1107 } else { 1108 argv = append(argv, "-mconsole") 1109 } 1110 } 1111 1112 switch Buildmode { 1113 case BuildmodeExe: 1114 if Headtype == objabi.Hdarwin { 1115 argv = append(argv, "-Wl,-pagezero_size,4000000") 1116 } 1117 case BuildmodePIE: 1118 // ELF. 1119 if Headtype != objabi.Hdarwin { 1120 if UseRelro() { 1121 argv = append(argv, "-Wl,-z,relro") 1122 } 1123 argv = append(argv, "-pie") 1124 } 1125 case BuildmodeCShared: 1126 if Headtype == objabi.Hdarwin { 1127 argv = append(argv, "-dynamiclib") 1128 if SysArch.Family != sys.AMD64 { 1129 argv = append(argv, "-Wl,-read_only_relocs,suppress") 1130 } 1131 } else { 1132 // ELF. 1133 argv = append(argv, "-Wl,-Bsymbolic") 1134 if UseRelro() { 1135 argv = append(argv, "-Wl,-z,relro") 1136 } 1137 // Pass -z nodelete to mark the shared library as 1138 // non-closeable: a dlclose will do nothing. 1139 argv = append(argv, "-shared", "-Wl,-z,nodelete") 1140 } 1141 case BuildmodeShared: 1142 if UseRelro() { 1143 argv = append(argv, "-Wl,-z,relro") 1144 } 1145 argv = append(argv, "-shared") 1146 case BuildmodePlugin: 1147 if Headtype == objabi.Hdarwin { 1148 argv = append(argv, "-dynamiclib") 1149 } else { 1150 if UseRelro() { 1151 argv = append(argv, "-Wl,-z,relro") 1152 } 1153 argv = append(argv, "-shared") 1154 } 1155 } 1156 1157 if Iself && l.DynlinkingGo() { 1158 // We force all symbol resolution to be done at program startup 1159 // because lazy PLT resolution can use large amounts of stack at 1160 // times we cannot allow it to do so. 1161 argv = append(argv, "-Wl,-znow") 1162 1163 // Do not let the host linker generate COPY relocations. These 1164 // can move symbols out of sections that rely on stable offsets 1165 // from the beginning of the section (like STYPE). 1166 argv = append(argv, "-Wl,-znocopyreloc") 1167 1168 if SysArch.InFamily(sys.ARM, sys.ARM64) { 1169 // On ARM, the GNU linker will generate COPY relocations 1170 // even with -znocopyreloc set. 1171 // https://sourceware.org/bugzilla/show_bug.cgi?id=19962 1172 // 1173 // On ARM64, the GNU linker will fail instead of 1174 // generating COPY relocations. 1175 // 1176 // In both cases, switch to gold. 1177 argv = append(argv, "-fuse-ld=gold") 1178 1179 // If gold is not installed, gcc will silently switch 1180 // back to ld.bfd. So we parse the version information 1181 // and provide a useful error if gold is missing. 1182 cmd := exec.Command(*flagExtld, "-fuse-ld=gold", "-Wl,--version") 1183 if out, err := cmd.CombinedOutput(); err == nil { 1184 if !bytes.Contains(out, []byte("GNU gold")) { 1185 log.Fatalf("ARM external linker must be gold (issue #15696), but is not: %s", out) 1186 } 1187 } 1188 } 1189 } 1190 1191 if Iself && len(buildinfo) > 0 { 1192 argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo)) 1193 } 1194 1195 // On Windows, given -o foo, GCC will append ".exe" to produce 1196 // "foo.exe". We have decided that we want to honor the -o 1197 // option. To make this work, we append a '.' so that GCC 1198 // will decide that the file already has an extension. We 1199 // only want to do this when producing a Windows output file 1200 // on a Windows host. 1201 outopt := *flagOutfile 1202 if objabi.GOOS == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" { 1203 outopt += "." 1204 } 1205 argv = append(argv, "-o") 1206 argv = append(argv, outopt) 1207 1208 if rpath.val != "" { 1209 argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val)) 1210 } 1211 1212 // Force global symbols to be exported for dlopen, etc. 1213 if Iself { 1214 argv = append(argv, "-rdynamic") 1215 } 1216 1217 if strings.Contains(argv[0], "clang") { 1218 argv = append(argv, "-Qunused-arguments") 1219 } 1220 1221 argv = append(argv, filepath.Join(*flagTmpdir, "go.o")) 1222 argv = append(argv, hostobjCopy()...) 1223 1224 if *FlagLinkshared { 1225 seenDirs := make(map[string]bool) 1226 seenLibs := make(map[string]bool) 1227 addshlib := func(path string) { 1228 dir, base := filepath.Split(path) 1229 if !seenDirs[dir] { 1230 argv = append(argv, "-L"+dir) 1231 if !rpath.set { 1232 argv = append(argv, "-Wl,-rpath="+dir) 1233 } 1234 seenDirs[dir] = true 1235 } 1236 base = strings.TrimSuffix(base, ".so") 1237 base = strings.TrimPrefix(base, "lib") 1238 if !seenLibs[base] { 1239 argv = append(argv, "-l"+base) 1240 seenLibs[base] = true 1241 } 1242 } 1243 for _, shlib := range l.Shlibs { 1244 addshlib(shlib.Path) 1245 for _, dep := range shlib.Deps { 1246 if dep == "" { 1247 continue 1248 } 1249 libpath := findshlib(l, dep) 1250 if libpath != "" { 1251 addshlib(libpath) 1252 } 1253 } 1254 } 1255 } 1256 1257 argv = append(argv, ldflag...) 1258 1259 // When building a program with the default -buildmode=exe the 1260 // gc compiler generates code requires DT_TEXTREL in a 1261 // position independent executable (PIE). On systems where the 1262 // toolchain creates PIEs by default, and where DT_TEXTREL 1263 // does not work, the resulting programs will not run. See 1264 // issue #17847. To avoid this problem pass -no-pie to the 1265 // toolchain if it is supported. 1266 if Buildmode == BuildmodeExe { 1267 src := filepath.Join(*flagTmpdir, "trivial.c") 1268 if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil { 1269 Errorf(nil, "WriteFile trivial.c failed: %v", err) 1270 } 1271 1272 // GCC uses -no-pie, clang uses -nopie. 1273 for _, nopie := range []string{"-no-pie", "-nopie"} { 1274 cmd := exec.Command(argv[0], nopie, "trivial.c") 1275 cmd.Dir = *flagTmpdir 1276 cmd.Env = append([]string{"LC_ALL=C"}, os.Environ()...) 1277 out, err := cmd.CombinedOutput() 1278 // GCC says "unrecognized command line option ‘-no-pie’" 1279 // clang says "unknown argument: '-no-pie'" 1280 supported := err == nil && !bytes.Contains(out, []byte("unrecognized")) && !bytes.Contains(out, []byte("unknown")) 1281 if supported { 1282 argv = append(argv, nopie) 1283 break 1284 } 1285 } 1286 } 1287 1288 for _, p := range strings.Fields(*flagExtldflags) { 1289 argv = append(argv, p) 1290 1291 // clang, unlike GCC, passes -rdynamic to the linker 1292 // even when linking with -static, causing a linker 1293 // error when using GNU ld. So take out -rdynamic if 1294 // we added it. We do it in this order, rather than 1295 // only adding -rdynamic later, so that -*extldflags 1296 // can override -rdynamic without using -static. 1297 if Iself && p == "-static" { 1298 for i := range argv { 1299 if argv[i] == "-rdynamic" { 1300 argv[i] = "-static" 1301 } 1302 } 1303 } 1304 } 1305 if Headtype == objabi.Hwindows { 1306 // use gcc linker script to work around gcc bug 1307 // (see https://golang.org/issue/20183 for details). 1308 p := writeGDBLinkerScript() 1309 argv = append(argv, "-Wl,-T,"+p) 1310 // libmingw32 and libmingwex have some inter-dependencies, 1311 // so must use linker groups. 1312 argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group") 1313 argv = append(argv, peimporteddlls()...) 1314 } 1315 1316 if l.Debugvlog != 0 { 1317 l.Logf("%5.2f host link:", Cputime()) 1318 for _, v := range argv { 1319 l.Logf(" %q", v) 1320 } 1321 l.Logf("\n") 1322 } 1323 1324 if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil { 1325 Exitf("running %s failed: %v\n%s", argv[0], err, out) 1326 } else if len(out) > 0 { 1327 // always print external output even if the command is successful, so that we don't 1328 // swallow linker warnings (see https://golang.org/issue/17935). 1329 l.Logf("%s", out) 1330 } 1331 1332 if !*FlagS && !*FlagW && !debug_s && Headtype == objabi.Hdarwin { 1333 // Skip combining dwarf on arm. 1334 if !SysArch.InFamily(sys.ARM, sys.ARM64) { 1335 dsym := filepath.Join(*flagTmpdir, "go.dwarf") 1336 if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil { 1337 Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out) 1338 } 1339 // Skip combining if `dsymutil` didn't generate a file. See #11994. 1340 if _, err := os.Stat(dsym); os.IsNotExist(err) { 1341 return 1342 } 1343 // For os.Rename to work reliably, must be in same directory as outfile. 1344 combinedOutput := *flagOutfile + "~" 1345 if err := machoCombineDwarf(*flagOutfile, dsym, combinedOutput); err != nil { 1346 Exitf("%s: combining dwarf failed: %v", os.Args[0], err) 1347 } 1348 os.Remove(*flagOutfile) 1349 if err := os.Rename(combinedOutput, *flagOutfile); err != nil { 1350 Exitf("%s: %v", os.Args[0], err) 1351 } 1352 } 1353 } 1354 } 1355 1356 // hostlinkArchArgs returns arguments to pass to the external linker 1357 // based on the architecture. 1358 func hostlinkArchArgs() []string { 1359 switch SysArch.Family { 1360 case sys.I386: 1361 return []string{"-m32"} 1362 case sys.AMD64, sys.PPC64, sys.S390X: 1363 return []string{"-m64"} 1364 case sys.ARM: 1365 return []string{"-marm"} 1366 case sys.ARM64: 1367 // nothing needed 1368 case sys.MIPS64: 1369 return []string{"-mabi=64"} 1370 case sys.MIPS: 1371 return []string{"-mabi=32"} 1372 } 1373 return nil 1374 } 1375 1376 // ldobj loads an input object. If it is a host object (an object 1377 // compiled by a non-Go compiler) it returns the Hostobj pointer. If 1378 // it is a Go object, it returns nil. 1379 func ldobj(ctxt *Link, f *bio.Reader, lib *Library, length int64, pn string, file string, whence int) *Hostobj { 1380 pkg := objabi.PathToPrefix(lib.Pkg) 1381 1382 eof := f.Offset() + length 1383 start := f.Offset() 1384 c1 := bgetc(f) 1385 c2 := bgetc(f) 1386 c3 := bgetc(f) 1387 c4 := bgetc(f) 1388 f.Seek(start, 0) 1389 1390 magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4) 1391 if magic == 0x7f454c46 { // \x7F E L F 1392 return ldhostobj(ldelf, f, pkg, length, pn, file) 1393 } 1394 1395 if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe { 1396 return ldhostobj(ldmacho, f, pkg, length, pn, file) 1397 } 1398 1399 if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 { 1400 return ldhostobj(ldpe, f, pkg, length, pn, file) 1401 } 1402 1403 /* check the header */ 1404 line, err := f.ReadString('\n') 1405 if err != nil { 1406 Errorf(nil, "truncated object file: %s: %v", pn, err) 1407 return nil 1408 } 1409 1410 if !strings.HasPrefix(line, "go object ") { 1411 if strings.HasSuffix(pn, ".go") { 1412 Exitf("%s: uncompiled .go source file", pn) 1413 return nil 1414 } 1415 1416 if line == SysArch.Name { 1417 // old header format: just $GOOS 1418 Errorf(nil, "%s: stale object file", pn) 1419 return nil 1420 } 1421 1422 Errorf(nil, "%s: not an object file", pn) 1423 return nil 1424 } 1425 1426 // First, check that the basic GOOS, GOARCH, and Version match. 1427 t := fmt.Sprintf("%s %s %s ", objabi.GOOS, objabi.GOARCH, objabi.Version) 1428 1429 line = strings.TrimRight(line, "\n") 1430 if !strings.HasPrefix(line[10:]+" ", t) && !*flagF { 1431 Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], t) 1432 return nil 1433 } 1434 1435 // Second, check that longer lines match each other exactly, 1436 // so that the Go compiler and write additional information 1437 // that must be the same from run to run. 1438 if len(line) >= len(t)+10 { 1439 if theline == "" { 1440 theline = line[10:] 1441 } else if theline != line[10:] { 1442 Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], theline) 1443 return nil 1444 } 1445 } 1446 1447 /* skip over exports and other info -- ends with \n!\n */ 1448 import0 := f.Offset() 1449 1450 c1 = '\n' // the last line ended in \n 1451 c2 = bgetc(f) 1452 c3 = bgetc(f) 1453 for c1 != '\n' || c2 != '!' || c3 != '\n' { 1454 c1 = c2 1455 c2 = c3 1456 c3 = bgetc(f) 1457 if c3 == -1 { 1458 Errorf(nil, "truncated object file: %s", pn) 1459 return nil 1460 } 1461 } 1462 1463 import1 := f.Offset() 1464 1465 f.Seek(import0, 0) 1466 ldpkg(ctxt, f, pkg, import1-import0-2, pn, whence) // -2 for !\n 1467 f.Seek(import1, 0) 1468 1469 LoadObjFile(ctxt, f, lib, eof-f.Offset(), pn) 1470 return nil 1471 } 1472 1473 func readelfsymboldata(ctxt *Link, f *elf.File, sym *elf.Symbol) []byte { 1474 data := make([]byte, sym.Size) 1475 sect := f.Sections[sym.Section] 1476 if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE { 1477 Errorf(nil, "reading %s from non-data section", sym.Name) 1478 } 1479 n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr)) 1480 if uint64(n) != sym.Size { 1481 Errorf(nil, "reading contents of %s: %v", sym.Name, err) 1482 } 1483 return data 1484 } 1485 1486 func readwithpad(r io.Reader, sz int32) ([]byte, error) { 1487 data := make([]byte, Rnd(int64(sz), 4)) 1488 _, err := io.ReadFull(r, data) 1489 if err != nil { 1490 return nil, err 1491 } 1492 data = data[:sz] 1493 return data, nil 1494 } 1495 1496 func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) { 1497 for _, sect := range f.Sections { 1498 if sect.Type != elf.SHT_NOTE { 1499 continue 1500 } 1501 r := sect.Open() 1502 for { 1503 var namesize, descsize, noteType int32 1504 err := binary.Read(r, f.ByteOrder, &namesize) 1505 if err != nil { 1506 if err == io.EOF { 1507 break 1508 } 1509 return nil, fmt.Errorf("read namesize failed: %v", err) 1510 } 1511 err = binary.Read(r, f.ByteOrder, &descsize) 1512 if err != nil { 1513 return nil, fmt.Errorf("read descsize failed: %v", err) 1514 } 1515 err = binary.Read(r, f.ByteOrder, ¬eType) 1516 if err != nil { 1517 return nil, fmt.Errorf("read type failed: %v", err) 1518 } 1519 noteName, err := readwithpad(r, namesize) 1520 if err != nil { 1521 return nil, fmt.Errorf("read name failed: %v", err) 1522 } 1523 desc, err := readwithpad(r, descsize) 1524 if err != nil { 1525 return nil, fmt.Errorf("read desc failed: %v", err) 1526 } 1527 if string(name) == string(noteName) && typ == noteType { 1528 return desc, nil 1529 } 1530 } 1531 } 1532 return nil, nil 1533 } 1534 1535 func findshlib(ctxt *Link, shlib string) string { 1536 for _, libdir := range ctxt.Libdir { 1537 libpath := filepath.Join(libdir, shlib) 1538 if _, err := os.Stat(libpath); err == nil { 1539 return libpath 1540 } 1541 } 1542 Errorf(nil, "cannot find shared library: %s", shlib) 1543 return "" 1544 } 1545 1546 func ldshlibsyms(ctxt *Link, shlib string) { 1547 libpath := findshlib(ctxt, shlib) 1548 if libpath == "" { 1549 return 1550 } 1551 for _, processedlib := range ctxt.Shlibs { 1552 if processedlib.Path == libpath { 1553 return 1554 } 1555 } 1556 if ctxt.Debugvlog > 1 { 1557 ctxt.Logf("%5.2f ldshlibsyms: found library with name %s at %s\n", Cputime(), shlib, libpath) 1558 } 1559 1560 f, err := elf.Open(libpath) 1561 if err != nil { 1562 Errorf(nil, "cannot open shared library: %s", libpath) 1563 return 1564 } 1565 1566 hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG) 1567 if err != nil { 1568 Errorf(nil, "cannot read ABI hash from shared library %s: %v", libpath, err) 1569 return 1570 } 1571 1572 depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG) 1573 if err != nil { 1574 Errorf(nil, "cannot read dep list from shared library %s: %v", libpath, err) 1575 return 1576 } 1577 deps := strings.Split(string(depsbytes), "\n") 1578 1579 syms, err := f.DynamicSymbols() 1580 if err != nil { 1581 Errorf(nil, "cannot read symbols from shared library: %s", libpath) 1582 return 1583 } 1584 gcdataLocations := make(map[uint64]*Symbol) 1585 for _, elfsym := range syms { 1586 if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION { 1587 continue 1588 } 1589 lsym := ctxt.Syms.Lookup(elfsym.Name, 0) 1590 // Because loadlib above loads all .a files before loading any shared 1591 // libraries, any non-dynimport symbols we find that duplicate symbols 1592 // already loaded should be ignored (the symbols from the .a files 1593 // "win"). 1594 if lsym.Type != 0 && lsym.Type != SDYNIMPORT { 1595 continue 1596 } 1597 lsym.Type = SDYNIMPORT 1598 lsym.ElfType = elf.ST_TYPE(elfsym.Info) 1599 lsym.Size = int64(elfsym.Size) 1600 if elfsym.Section != elf.SHN_UNDEF { 1601 // Set .File for the library that actually defines the symbol. 1602 lsym.File = libpath 1603 // The decodetype_* functions in decodetype.go need access to 1604 // the type data. 1605 if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") { 1606 lsym.P = readelfsymboldata(ctxt, f, &elfsym) 1607 gcdataLocations[elfsym.Value+2*uint64(SysArch.PtrSize)+8+1*uint64(SysArch.PtrSize)] = lsym 1608 } 1609 } 1610 } 1611 gcdataAddresses := make(map[*Symbol]uint64) 1612 if SysArch.Family == sys.ARM64 { 1613 for _, sect := range f.Sections { 1614 if sect.Type == elf.SHT_RELA { 1615 var rela elf.Rela64 1616 rdr := sect.Open() 1617 for { 1618 err := binary.Read(rdr, f.ByteOrder, &rela) 1619 if err == io.EOF { 1620 break 1621 } else if err != nil { 1622 Errorf(nil, "reading relocation failed %v", err) 1623 return 1624 } 1625 t := elf.R_AARCH64(rela.Info & 0xffff) 1626 if t != elf.R_AARCH64_RELATIVE { 1627 continue 1628 } 1629 if lsym, ok := gcdataLocations[rela.Off]; ok { 1630 gcdataAddresses[lsym] = uint64(rela.Addend) 1631 } 1632 } 1633 } 1634 } 1635 } 1636 1637 ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdataAddresses: gcdataAddresses}) 1638 } 1639 1640 func addsection(seg *Segment, name string, rwx int) *Section { 1641 sect := new(Section) 1642 sect.Rwx = uint8(rwx) 1643 sect.Name = name 1644 sect.Seg = seg 1645 sect.Align = int32(SysArch.PtrSize) // everything is at least pointer-aligned 1646 seg.Sections = append(seg.Sections, sect) 1647 return sect 1648 } 1649 1650 func Le16(b []byte) uint16 { 1651 return uint16(b[0]) | uint16(b[1])<<8 1652 } 1653 1654 func Le32(b []byte) uint32 { 1655 return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 1656 } 1657 1658 func Le64(b []byte) uint64 { 1659 return uint64(Le32(b)) | uint64(Le32(b[4:]))<<32 1660 } 1661 1662 func Be16(b []byte) uint16 { 1663 return uint16(b[0])<<8 | uint16(b[1]) 1664 } 1665 1666 func Be32(b []byte) uint32 { 1667 return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]) 1668 } 1669 1670 type chain struct { 1671 sym *Symbol 1672 up *chain 1673 limit int // limit on entry to sym 1674 } 1675 1676 var morestack *Symbol 1677 1678 // TODO: Record enough information in new object files to 1679 // allow stack checks here. 1680 1681 func haslinkregister(ctxt *Link) bool { 1682 return ctxt.FixedFrameSize() != 0 1683 } 1684 1685 func callsize(ctxt *Link) int { 1686 if haslinkregister(ctxt) { 1687 return 0 1688 } 1689 return SysArch.RegSize 1690 } 1691 1692 func (ctxt *Link) dostkcheck() { 1693 var ch chain 1694 1695 morestack = ctxt.Syms.Lookup("runtime.morestack", 0) 1696 1697 // Every splitting function ensures that there are at least StackLimit 1698 // bytes available below SP when the splitting prologue finishes. 1699 // If the splitting function calls F, then F begins execution with 1700 // at least StackLimit - callsize() bytes available. 1701 // Check that every function behaves correctly with this amount 1702 // of stack, following direct calls in order to piece together chains 1703 // of non-splitting functions. 1704 ch.up = nil 1705 1706 ch.limit = objabi.StackLimit - callsize(ctxt) 1707 1708 // Check every function, but do the nosplit functions in a first pass, 1709 // to make the printed failure chains as short as possible. 1710 for _, s := range ctxt.Textp { 1711 // runtime.racesymbolizethunk is called from gcc-compiled C 1712 // code running on the operating system thread stack. 1713 // It uses more than the usual amount of stack but that's okay. 1714 if s.Name == "runtime.racesymbolizethunk" { 1715 continue 1716 } 1717 1718 if s.Attr.NoSplit() { 1719 ch.sym = s 1720 stkcheck(ctxt, &ch, 0) 1721 } 1722 } 1723 1724 for _, s := range ctxt.Textp { 1725 if !s.Attr.NoSplit() { 1726 ch.sym = s 1727 stkcheck(ctxt, &ch, 0) 1728 } 1729 } 1730 } 1731 1732 func stkcheck(ctxt *Link, up *chain, depth int) int { 1733 limit := up.limit 1734 s := up.sym 1735 1736 // Don't duplicate work: only need to consider each 1737 // function at top of safe zone once. 1738 top := limit == objabi.StackLimit-callsize(ctxt) 1739 if top { 1740 if s.Attr.StackCheck() { 1741 return 0 1742 } 1743 s.Attr |= AttrStackCheck 1744 } 1745 1746 if depth > 100 { 1747 Errorf(s, "nosplit stack check too deep") 1748 stkbroke(ctxt, up, 0) 1749 return -1 1750 } 1751 1752 if s.Attr.External() || s.FuncInfo == nil { 1753 // external function. 1754 // should never be called directly. 1755 // onlyctxt.Diagnose the direct caller. 1756 // TODO(mwhudson): actually think about this. 1757 if depth == 1 && s.Type != SXREF && !ctxt.DynlinkingGo() && 1758 Buildmode != BuildmodeCArchive && Buildmode != BuildmodePIE && Buildmode != BuildmodeCShared && Buildmode != BuildmodePlugin { 1759 1760 Errorf(s, "call to external function") 1761 } 1762 return -1 1763 } 1764 1765 if limit < 0 { 1766 stkbroke(ctxt, up, limit) 1767 return -1 1768 } 1769 1770 // morestack looks like it calls functions, 1771 // but it switches the stack pointer first. 1772 if s == morestack { 1773 return 0 1774 } 1775 1776 var ch chain 1777 ch.up = up 1778 1779 if !s.Attr.NoSplit() { 1780 // Ensure we have enough stack to call morestack. 1781 ch.limit = limit - callsize(ctxt) 1782 ch.sym = morestack 1783 if stkcheck(ctxt, &ch, depth+1) < 0 { 1784 return -1 1785 } 1786 if !top { 1787 return 0 1788 } 1789 // Raise limit to allow frame. 1790 locals := int32(0) 1791 if s.FuncInfo != nil { 1792 locals = s.FuncInfo.Locals 1793 } 1794 limit = int(objabi.StackLimit+locals) + int(ctxt.FixedFrameSize()) 1795 } 1796 1797 // Walk through sp adjustments in function, consuming relocs. 1798 ri := 0 1799 1800 endr := len(s.R) 1801 var ch1 chain 1802 var pcsp Pciter 1803 var r *Reloc 1804 for pciterinit(ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) { 1805 // pcsp.value is in effect for [pcsp.pc, pcsp.nextpc). 1806 1807 // Check stack size in effect for this span. 1808 if int32(limit)-pcsp.value < 0 { 1809 stkbroke(ctxt, up, int(int32(limit)-pcsp.value)) 1810 return -1 1811 } 1812 1813 // Process calls in this span. 1814 for ; ri < endr && uint32(s.R[ri].Off) < pcsp.nextpc; ri++ { 1815 r = &s.R[ri] 1816 switch r.Type { 1817 // Direct call. 1818 case objabi.R_CALL, objabi.R_CALLARM, objabi.R_CALLARM64, objabi.R_CALLPOWER, objabi.R_CALLMIPS: 1819 ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt))) 1820 ch.sym = r.Sym 1821 if stkcheck(ctxt, &ch, depth+1) < 0 { 1822 return -1 1823 } 1824 1825 // Indirect call. Assume it is a call to a splitting function, 1826 // so we have to make sure it can call morestack. 1827 // Arrange the data structures to report both calls, so that 1828 // if there is an error, stkprint shows all the steps involved. 1829 case objabi.R_CALLIND: 1830 ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt))) 1831 1832 ch.sym = nil 1833 ch1.limit = ch.limit - callsize(ctxt) // for morestack in called prologue 1834 ch1.up = &ch 1835 ch1.sym = morestack 1836 if stkcheck(ctxt, &ch1, depth+2) < 0 { 1837 return -1 1838 } 1839 } 1840 } 1841 } 1842 1843 return 0 1844 } 1845 1846 func stkbroke(ctxt *Link, ch *chain, limit int) { 1847 Errorf(ch.sym, "nosplit stack overflow") 1848 stkprint(ctxt, ch, limit) 1849 } 1850 1851 func stkprint(ctxt *Link, ch *chain, limit int) { 1852 var name string 1853 1854 if ch.sym != nil { 1855 name = ch.sym.Name 1856 if ch.sym.Attr.NoSplit() { 1857 name += " (nosplit)" 1858 } 1859 } else { 1860 name = "function pointer" 1861 } 1862 1863 if ch.up == nil { 1864 // top of chain. ch->sym != nil. 1865 if ch.sym.Attr.NoSplit() { 1866 fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name) 1867 } else { 1868 fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name) 1869 } 1870 } else { 1871 stkprint(ctxt, ch.up, ch.limit+callsize(ctxt)) 1872 if !haslinkregister(ctxt) { 1873 fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name) 1874 } 1875 } 1876 1877 if ch.limit != limit { 1878 fmt.Printf("\t%d\tafter %s uses %d\n", limit, name, ch.limit-limit) 1879 } 1880 } 1881 1882 func Cflush() { 1883 if err := coutbuf.w.Flush(); err != nil { 1884 Exitf("flushing %s: %v", coutbuf.f.Name(), err) 1885 } 1886 } 1887 1888 func Cseek(p int64) { 1889 if p == coutbuf.off { 1890 return 1891 } 1892 Cflush() 1893 if _, err := coutbuf.f.Seek(p, 0); err != nil { 1894 Exitf("seeking in output [0, 1]: %v", err) 1895 } 1896 coutbuf.off = p 1897 } 1898 1899 func Cwritestring(s string) { 1900 coutbuf.WriteString(s) 1901 } 1902 1903 func Cwrite(p []byte) { 1904 coutbuf.Write(p) 1905 } 1906 1907 func Cput(c uint8) { 1908 coutbuf.w.WriteByte(c) 1909 coutbuf.off++ 1910 } 1911 1912 func usage() { 1913 fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n") 1914 objabi.Flagprint(2) 1915 Exit(2) 1916 } 1917 1918 func doversion() { 1919 Exitf("version %s", objabi.Version) 1920 } 1921 1922 type SymbolType int8 1923 1924 const ( 1925 TextSym SymbolType = 'T' 1926 DataSym = 'D' 1927 BSSSym = 'B' 1928 UndefinedSym = 'U' 1929 TLSSym = 't' 1930 FileSym = 'f' 1931 FrameSym = 'm' 1932 ParamSym = 'p' 1933 AutoSym = 'a' 1934 ) 1935 1936 func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *Symbol)) { 1937 // These symbols won't show up in the first loop below because we 1938 // skip STEXT symbols. Normal STEXT symbols are emitted by walking textp. 1939 s := ctxt.Syms.Lookup("runtime.text", 0) 1940 if s.Type == STEXT { 1941 put(ctxt, s, s.Name, TextSym, s.Value, nil) 1942 } 1943 1944 n := 0 1945 1946 // Generate base addresses for all text sections if there are multiple 1947 for _, sect := range Segtext.Sections { 1948 if n == 0 { 1949 n++ 1950 continue 1951 } 1952 if sect.Name != ".text" { 1953 break 1954 } 1955 s = ctxt.Syms.ROLookup(fmt.Sprintf("runtime.text.%d", n), 0) 1956 if s == nil { 1957 break 1958 } 1959 if s.Type == STEXT { 1960 put(ctxt, s, s.Name, TextSym, s.Value, nil) 1961 } 1962 n++ 1963 } 1964 1965 s = ctxt.Syms.Lookup("runtime.etext", 0) 1966 if s.Type == STEXT { 1967 put(ctxt, s, s.Name, TextSym, s.Value, nil) 1968 } 1969 1970 for _, s := range ctxt.Syms.Allsym { 1971 if s.Attr.NotInSymbolTable() { 1972 continue 1973 } 1974 if (s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC." { 1975 continue 1976 } 1977 switch s.Type & SMASK { 1978 case SCONST, 1979 SRODATA, 1980 SSYMTAB, 1981 SPCLNTAB, 1982 SINITARR, 1983 SDATA, 1984 SNOPTRDATA, 1985 SELFROSECT, 1986 SMACHOGOT, 1987 STYPE, 1988 SSTRING, 1989 SGOSTRING, 1990 SGOFUNC, 1991 SGCBITS, 1992 STYPERELRO, 1993 SSTRINGRELRO, 1994 SGOSTRINGRELRO, 1995 SGOFUNCRELRO, 1996 SGCBITSRELRO, 1997 SRODATARELRO, 1998 STYPELINK, 1999 SITABLINK, 2000 SWINDOWS: 2001 if !s.Attr.Reachable() { 2002 continue 2003 } 2004 put(ctxt, s, s.Name, DataSym, Symaddr(s), s.Gotype) 2005 2006 case SBSS, SNOPTRBSS: 2007 if !s.Attr.Reachable() { 2008 continue 2009 } 2010 if len(s.P) > 0 { 2011 Errorf(s, "should not be bss (size=%d type=%v special=%v)", len(s.P), s.Type, s.Attr.Special()) 2012 } 2013 put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype) 2014 2015 case SFILE: 2016 put(ctxt, nil, s.Name, FileSym, s.Value, nil) 2017 2018 case SHOSTOBJ: 2019 if Headtype == objabi.Hwindows || Iself { 2020 put(ctxt, s, s.Name, UndefinedSym, s.Value, nil) 2021 } 2022 2023 case SDYNIMPORT: 2024 if !s.Attr.Reachable() { 2025 continue 2026 } 2027 put(ctxt, s, s.Extname, UndefinedSym, 0, nil) 2028 2029 case STLSBSS: 2030 if Linkmode == LinkExternal { 2031 put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype) 2032 } 2033 } 2034 } 2035 2036 var off int32 2037 for _, s := range ctxt.Textp { 2038 put(ctxt, s, s.Name, TextSym, s.Value, s.Gotype) 2039 2040 locals := int32(0) 2041 if s.FuncInfo != nil { 2042 locals = s.FuncInfo.Locals 2043 } 2044 // NOTE(ality): acid can't produce a stack trace without .frame symbols 2045 put(ctxt, nil, ".frame", FrameSym, int64(locals)+int64(SysArch.PtrSize), nil) 2046 2047 if s.FuncInfo == nil { 2048 continue 2049 } 2050 for _, a := range s.FuncInfo.Autom { 2051 // Emit a or p according to actual offset, even if label is wrong. 2052 // This avoids negative offsets, which cannot be encoded. 2053 if a.Name != objabi.A_AUTO && a.Name != objabi.A_PARAM { 2054 continue 2055 } 2056 2057 // compute offset relative to FP 2058 if a.Name == objabi.A_PARAM { 2059 off = a.Aoffset 2060 } else { 2061 off = a.Aoffset - int32(SysArch.PtrSize) 2062 } 2063 2064 // FP 2065 if off >= 0 { 2066 put(ctxt, nil, a.Asym.Name, ParamSym, int64(off), a.Gotype) 2067 continue 2068 } 2069 2070 // SP 2071 if off <= int32(-SysArch.PtrSize) { 2072 put(ctxt, nil, a.Asym.Name, AutoSym, -(int64(off) + int64(SysArch.PtrSize)), a.Gotype) 2073 continue 2074 } 2075 // Otherwise, off is addressing the saved program counter. 2076 // Something underhanded is going on. Say nothing. 2077 } 2078 } 2079 2080 if ctxt.Debugvlog != 0 || *flagN { 2081 ctxt.Logf("%5.2f symsize = %d\n", Cputime(), uint32(Symsize)) 2082 } 2083 } 2084 2085 func Symaddr(s *Symbol) int64 { 2086 if !s.Attr.Reachable() { 2087 Errorf(s, "unreachable symbol in symaddr") 2088 } 2089 return s.Value 2090 } 2091 2092 func (ctxt *Link) xdefine(p string, t SymKind, v int64) { 2093 s := ctxt.Syms.Lookup(p, 0) 2094 s.Type = t 2095 s.Value = v 2096 s.Attr |= AttrReachable 2097 s.Attr |= AttrSpecial 2098 s.Attr |= AttrLocal 2099 } 2100 2101 func datoff(s *Symbol, addr int64) int64 { 2102 if uint64(addr) >= Segdata.Vaddr { 2103 return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff) 2104 } 2105 if uint64(addr) >= Segtext.Vaddr { 2106 return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff) 2107 } 2108 Errorf(s, "invalid datoff %#x", addr) 2109 return 0 2110 } 2111 2112 func Entryvalue(ctxt *Link) int64 { 2113 a := *flagEntrySymbol 2114 if a[0] >= '0' && a[0] <= '9' { 2115 return atolwhex(a) 2116 } 2117 s := ctxt.Syms.Lookup(a, 0) 2118 if s.Type == 0 { 2119 return *FlagTextAddr 2120 } 2121 if s.Type != STEXT { 2122 Errorf(s, "entry not text") 2123 } 2124 return s.Value 2125 } 2126 2127 func undefsym(ctxt *Link, s *Symbol) { 2128 var r *Reloc 2129 2130 for i := 0; i < len(s.R); i++ { 2131 r = &s.R[i] 2132 if r.Sym == nil { // happens for some external ARM relocs 2133 continue 2134 } 2135 if r.Sym.Type == Sxxx || r.Sym.Type == SXREF { 2136 Errorf(s, "undefined: %q", r.Sym.Name) 2137 } 2138 if !r.Sym.Attr.Reachable() && r.Type != objabi.R_WEAKADDROFF { 2139 Errorf(s, "relocation target %q", r.Sym.Name) 2140 } 2141 } 2142 } 2143 2144 func (ctxt *Link) undef() { 2145 for _, s := range ctxt.Textp { 2146 undefsym(ctxt, s) 2147 } 2148 for _, s := range datap { 2149 undefsym(ctxt, s) 2150 } 2151 if nerrors > 0 { 2152 errorexit() 2153 } 2154 } 2155 2156 func (ctxt *Link) callgraph() { 2157 if !*FlagC { 2158 return 2159 } 2160 2161 var i int 2162 var r *Reloc 2163 for _, s := range ctxt.Textp { 2164 for i = 0; i < len(s.R); i++ { 2165 r = &s.R[i] 2166 if r.Sym == nil { 2167 continue 2168 } 2169 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 { 2170 ctxt.Logf("%s calls %s\n", s.Name, r.Sym.Name) 2171 } 2172 } 2173 } 2174 } 2175 2176 func Rnd(v int64, r int64) int64 { 2177 if r <= 0 { 2178 return v 2179 } 2180 v += r - 1 2181 c := v % r 2182 if c < 0 { 2183 c += r 2184 } 2185 v -= c 2186 return v 2187 } 2188 2189 func bgetc(r *bio.Reader) int { 2190 c, err := r.ReadByte() 2191 if err != nil { 2192 if err != io.EOF { 2193 log.Fatalf("reading input: %v", err) 2194 } 2195 return -1 2196 } 2197 return int(c) 2198 } 2199 2200 type markKind uint8 // for postorder traversal 2201 const ( 2202 unvisited markKind = iota 2203 visiting 2204 visited 2205 ) 2206 2207 func postorder(libs []*Library) []*Library { 2208 order := make([]*Library, 0, len(libs)) // hold the result 2209 mark := make(map[*Library]markKind, len(libs)) 2210 for _, lib := range libs { 2211 dfs(lib, mark, &order) 2212 } 2213 return order 2214 } 2215 2216 func dfs(lib *Library, mark map[*Library]markKind, order *[]*Library) { 2217 if mark[lib] == visited { 2218 return 2219 } 2220 if mark[lib] == visiting { 2221 panic("found import cycle while visiting " + lib.Pkg) 2222 } 2223 mark[lib] = visiting 2224 for _, i := range lib.imports { 2225 dfs(i, mark, order) 2226 } 2227 mark[lib] = visited 2228 *order = append(*order, lib) 2229 }