github.com/eun/go@v0.0.0-20170811110501-92cfd07a6cfd/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 magbuf [len(ARMAG)]byte 728 if _, err := io.ReadFull(f, magbuf[:]); err != nil { 729 Exitf("file %s too short", lib.File) 730 } 731 732 if string(magbuf[:]) != ARMAG { 733 Exitf("%s is not an archive file", lib.File) 734 } 735 736 var arhdr ArHdr 737 l := nextar(f, f.Offset(), &arhdr) 738 if l <= 0 { 739 Errorf(nil, "%s: short read on archive file symbol header", lib.File) 740 return 741 } 742 743 h := sha1.New() 744 745 // To compute the hash of a package, we hash the first line of 746 // __.PKGDEF (which contains the toolchain version and any 747 // GOEXPERIMENT flags) and the export data (which is between 748 // the first two occurences of "\n$$"). 749 750 pkgDefBytes := make([]byte, atolwhex(arhdr.size)) 751 _, err = io.ReadFull(f, pkgDefBytes) 752 if err != nil { 753 Errorf(nil, "%s: error reading package data: %v", lib.File, err) 754 return 755 } 756 firstEOL := bytes.Index(pkgDefBytes, []byte("\n")) 757 if firstEOL < 0 { 758 Errorf(nil, "cannot parse package data of %s for hash generation, no newline found", lib.File) 759 return 760 } 761 firstDoubleDollar := bytes.Index(pkgDefBytes, []byte("\n$$")) 762 if firstDoubleDollar < 0 { 763 Errorf(nil, "cannot parse package data of %s for hash generation, no \\n$$ found", lib.File) 764 return 765 } 766 secondDoubleDollar := bytes.Index(pkgDefBytes[firstDoubleDollar+1:], []byte("\n$$")) 767 if secondDoubleDollar < 0 { 768 Errorf(nil, "cannot parse package data of %s for hash generation, only one \\n$$ found", lib.File) 769 return 770 } 771 h.Write(pkgDefBytes[0:firstEOL]) 772 h.Write(pkgDefBytes[firstDoubleDollar : firstDoubleDollar+secondDoubleDollar]) 773 lib.hash = hex.EncodeToString(h.Sum(nil)) 774 } 775 776 func objfile(ctxt *Link, lib *Library) { 777 pkg := objabi.PathToPrefix(lib.Pkg) 778 779 if ctxt.Debugvlog > 1 { 780 ctxt.Logf("%5.2f ldobj: %s (%s)\n", Cputime(), lib.File, pkg) 781 } 782 f, err := bio.Open(lib.File) 783 if err != nil { 784 Exitf("cannot open file %s: %v", lib.File, err) 785 } 786 787 for i := 0; i < len(ARMAG); i++ { 788 if c, err := f.ReadByte(); err == nil && c == ARMAG[i] { 789 continue 790 } 791 792 /* load it as a regular file */ 793 l := f.Seek(0, 2) 794 795 f.Seek(0, 0) 796 ldobj(ctxt, f, lib, l, lib.File, lib.File, FileObj) 797 f.Close() 798 799 return 800 } 801 802 /* process __.PKGDEF */ 803 off := f.Offset() 804 805 var arhdr ArHdr 806 l := nextar(f, off, &arhdr) 807 var pname string 808 if l <= 0 { 809 Errorf(nil, "%s: short read on archive file symbol header", lib.File) 810 goto out 811 } 812 813 if !strings.HasPrefix(arhdr.name, pkgname) { 814 Errorf(nil, "%s: cannot find package header", lib.File) 815 goto out 816 } 817 818 off += l 819 820 ldpkg(ctxt, f, pkg, atolwhex(arhdr.size), lib.File, Pkgdef) 821 822 /* 823 * load all the object files from the archive now. 824 * this gives us sequential file access and keeps us 825 * from needing to come back later to pick up more 826 * objects. it breaks the usual C archive model, but 827 * this is Go, not C. the common case in Go is that 828 * we need to load all the objects, and then we throw away 829 * the individual symbols that are unused. 830 * 831 * loading every object will also make it possible to 832 * load foreign objects not referenced by __.PKGDEF. 833 */ 834 for { 835 l = nextar(f, off, &arhdr) 836 if l == 0 { 837 break 838 } 839 if l < 0 { 840 Exitf("%s: malformed archive", lib.File) 841 } 842 843 off += l 844 845 pname = fmt.Sprintf("%s(%s)", lib.File, arhdr.name) 846 l = atolwhex(arhdr.size) 847 ldobj(ctxt, f, lib, l, pname, lib.File, ArchiveObj) 848 } 849 850 out: 851 f.Close() 852 } 853 854 type Hostobj struct { 855 ld func(*Link, *bio.Reader, string, int64, string) 856 pkg string 857 pn string 858 file string 859 off int64 860 length int64 861 } 862 863 var hostobj []Hostobj 864 865 // These packages can use internal linking mode. 866 // Others trigger external mode. 867 var internalpkg = []string{ 868 "crypto/x509", 869 "net", 870 "os/user", 871 "runtime/cgo", 872 "runtime/race", 873 "runtime/msan", 874 } 875 876 func ldhostobj(ld func(*Link, *bio.Reader, string, int64, string), f *bio.Reader, pkg string, length int64, pn string, file string) *Hostobj { 877 isinternal := false 878 for i := 0; i < len(internalpkg); i++ { 879 if pkg == internalpkg[i] { 880 isinternal = true 881 break 882 } 883 } 884 885 // DragonFly declares errno with __thread, which results in a symbol 886 // type of R_386_TLS_GD or R_X86_64_TLSGD. The Go linker does not 887 // currently know how to handle TLS relocations, hence we have to 888 // force external linking for any libraries that link in code that 889 // uses errno. This can be removed if the Go linker ever supports 890 // these relocation types. 891 if Headtype == objabi.Hdragonfly { 892 if pkg == "net" || pkg == "os/user" { 893 isinternal = false 894 } 895 } 896 897 if !isinternal { 898 externalobj = true 899 } 900 901 hostobj = append(hostobj, Hostobj{}) 902 h := &hostobj[len(hostobj)-1] 903 h.ld = ld 904 h.pkg = pkg 905 h.pn = pn 906 h.file = file 907 h.off = f.Offset() 908 h.length = length 909 return h 910 } 911 912 func hostobjs(ctxt *Link) { 913 var h *Hostobj 914 915 for i := 0; i < len(hostobj); i++ { 916 h = &hostobj[i] 917 f, err := bio.Open(h.file) 918 if err != nil { 919 Exitf("cannot reopen %s: %v", h.pn, err) 920 } 921 922 f.Seek(h.off, 0) 923 h.ld(ctxt, f, h.pkg, h.length, h.pn) 924 f.Close() 925 } 926 } 927 928 // provided by lib9 929 930 func rmtemp() { 931 os.RemoveAll(*flagTmpdir) 932 } 933 934 func hostlinksetup() { 935 if Linkmode != LinkExternal { 936 return 937 } 938 939 // For external link, record that we need to tell the external linker -s, 940 // and turn off -s internally: the external linker needs the symbol 941 // information for its final link. 942 debug_s = *FlagS 943 *FlagS = false 944 945 // create temporary directory and arrange cleanup 946 if *flagTmpdir == "" { 947 dir, err := ioutil.TempDir("", "go-link-") 948 if err != nil { 949 log.Fatal(err) 950 } 951 *flagTmpdir = dir 952 AtExit(rmtemp) 953 } 954 955 // change our output to temporary object file 956 coutbuf.f.Close() 957 mayberemoveoutfile() 958 959 p := filepath.Join(*flagTmpdir, "go.o") 960 var err error 961 f, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775) 962 if err != nil { 963 Exitf("cannot create %s: %v", p, err) 964 } 965 966 coutbuf.w = bufio.NewWriter(f) 967 coutbuf.f = f 968 } 969 970 // hostobjCopy creates a copy of the object files in hostobj in a 971 // temporary directory. 972 func hostobjCopy() (paths []string) { 973 var wg sync.WaitGroup 974 sema := make(chan struct{}, runtime.NumCPU()) // limit open file descriptors 975 for i, h := range hostobj { 976 h := h 977 dst := filepath.Join(*flagTmpdir, fmt.Sprintf("%06d.o", i)) 978 paths = append(paths, dst) 979 980 wg.Add(1) 981 go func() { 982 sema <- struct{}{} 983 defer func() { 984 <-sema 985 wg.Done() 986 }() 987 f, err := os.Open(h.file) 988 if err != nil { 989 Exitf("cannot reopen %s: %v", h.pn, err) 990 } 991 if _, err := f.Seek(h.off, 0); err != nil { 992 Exitf("cannot seek %s: %v", h.pn, err) 993 } 994 995 w, err := os.Create(dst) 996 if err != nil { 997 Exitf("cannot create %s: %v", dst, err) 998 } 999 if _, err := io.CopyN(w, f, h.length); err != nil { 1000 Exitf("cannot write %s: %v", dst, err) 1001 } 1002 if err := w.Close(); err != nil { 1003 Exitf("cannot close %s: %v", dst, err) 1004 } 1005 }() 1006 } 1007 wg.Wait() 1008 return paths 1009 } 1010 1011 // writeGDBLinkerScript creates gcc linker script file in temp 1012 // directory. writeGDBLinkerScript returns created file path. 1013 // The script is used to work around gcc bug 1014 // (see https://golang.org/issue/20183 for details). 1015 func writeGDBLinkerScript() string { 1016 name := "fix_debug_gdb_scripts.ld" 1017 path := filepath.Join(*flagTmpdir, name) 1018 src := `SECTIONS 1019 { 1020 .debug_gdb_scripts BLOCK(__section_alignment__) (NOLOAD) : 1021 { 1022 *(.debug_gdb_scripts) 1023 } 1024 } 1025 INSERT AFTER .debug_types; 1026 ` 1027 err := ioutil.WriteFile(path, []byte(src), 0666) 1028 if err != nil { 1029 Errorf(nil, "WriteFile %s failed: %v", name, err) 1030 } 1031 return path 1032 } 1033 1034 // archive builds a .a archive from the hostobj object files. 1035 func (ctxt *Link) archive() { 1036 if Buildmode != BuildmodeCArchive { 1037 return 1038 } 1039 1040 if *flagExtar == "" { 1041 *flagExtar = "ar" 1042 } 1043 1044 mayberemoveoutfile() 1045 1046 // Force the buffer to flush here so that external 1047 // tools will see a complete file. 1048 Cflush() 1049 if err := coutbuf.f.Close(); err != nil { 1050 Exitf("close: %v", err) 1051 } 1052 coutbuf.f = nil 1053 1054 argv := []string{*flagExtar, "-q", "-c", "-s", *flagOutfile} 1055 argv = append(argv, filepath.Join(*flagTmpdir, "go.o")) 1056 argv = append(argv, hostobjCopy()...) 1057 1058 if ctxt.Debugvlog != 0 { 1059 ctxt.Logf("archive: %s\n", strings.Join(argv, " ")) 1060 } 1061 1062 if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil { 1063 Exitf("running %s failed: %v\n%s", argv[0], err, out) 1064 } 1065 } 1066 1067 func (l *Link) hostlink() { 1068 if Linkmode != LinkExternal || nerrors > 0 { 1069 return 1070 } 1071 if Buildmode == BuildmodeCArchive { 1072 return 1073 } 1074 1075 if *flagExtld == "" { 1076 *flagExtld = "gcc" 1077 } 1078 1079 var argv []string 1080 argv = append(argv, *flagExtld) 1081 argv = append(argv, hostlinkArchArgs()...) 1082 1083 if !*FlagS && !debug_s { 1084 argv = append(argv, "-gdwarf-2") 1085 } else if Headtype == objabi.Hdarwin { 1086 // Recent versions of macOS print 1087 // ld: warning: option -s is obsolete and being ignored 1088 // so do not pass any arguments. 1089 } else { 1090 argv = append(argv, "-s") 1091 } 1092 1093 switch Headtype { 1094 case objabi.Hdarwin: 1095 argv = append(argv, "-Wl,-headerpad,1144") 1096 if l.DynlinkingGo() { 1097 argv = append(argv, "-Wl,-flat_namespace") 1098 } else if !SysArch.InFamily(sys.ARM64) { 1099 argv = append(argv, "-Wl,-no_pie") 1100 } 1101 case objabi.Hopenbsd: 1102 argv = append(argv, "-Wl,-nopie") 1103 case objabi.Hwindows: 1104 if windowsgui { 1105 argv = append(argv, "-mwindows") 1106 } else { 1107 argv = append(argv, "-mconsole") 1108 } 1109 } 1110 1111 switch Buildmode { 1112 case BuildmodeExe: 1113 if Headtype == objabi.Hdarwin { 1114 argv = append(argv, "-Wl,-pagezero_size,4000000") 1115 } 1116 case BuildmodePIE: 1117 if UseRelro() { 1118 argv = append(argv, "-Wl,-z,relro") 1119 } 1120 argv = append(argv, "-pie") 1121 case BuildmodeCShared: 1122 if Headtype == objabi.Hdarwin { 1123 argv = append(argv, "-dynamiclib") 1124 if SysArch.Family != sys.AMD64 { 1125 argv = append(argv, "-Wl,-read_only_relocs,suppress") 1126 } 1127 } else { 1128 // ELF. 1129 argv = append(argv, "-Wl,-Bsymbolic") 1130 if UseRelro() { 1131 argv = append(argv, "-Wl,-z,relro") 1132 } 1133 // Pass -z nodelete to mark the shared library as 1134 // non-closeable: a dlclose will do nothing. 1135 argv = append(argv, "-shared", "-Wl,-z,nodelete") 1136 } 1137 case BuildmodeShared: 1138 if UseRelro() { 1139 argv = append(argv, "-Wl,-z,relro") 1140 } 1141 argv = append(argv, "-shared") 1142 case BuildmodePlugin: 1143 if Headtype == objabi.Hdarwin { 1144 argv = append(argv, "-dynamiclib") 1145 } else { 1146 if UseRelro() { 1147 argv = append(argv, "-Wl,-z,relro") 1148 } 1149 argv = append(argv, "-shared") 1150 } 1151 } 1152 1153 if Iself && l.DynlinkingGo() { 1154 // We force all symbol resolution to be done at program startup 1155 // because lazy PLT resolution can use large amounts of stack at 1156 // times we cannot allow it to do so. 1157 argv = append(argv, "-Wl,-znow") 1158 1159 // Do not let the host linker generate COPY relocations. These 1160 // can move symbols out of sections that rely on stable offsets 1161 // from the beginning of the section (like STYPE). 1162 argv = append(argv, "-Wl,-znocopyreloc") 1163 1164 if SysArch.InFamily(sys.ARM, sys.ARM64) { 1165 // On ARM, the GNU linker will generate COPY relocations 1166 // even with -znocopyreloc set. 1167 // https://sourceware.org/bugzilla/show_bug.cgi?id=19962 1168 // 1169 // On ARM64, the GNU linker will fail instead of 1170 // generating COPY relocations. 1171 // 1172 // In both cases, switch to gold. 1173 argv = append(argv, "-fuse-ld=gold") 1174 1175 // If gold is not installed, gcc will silently switch 1176 // back to ld.bfd. So we parse the version information 1177 // and provide a useful error if gold is missing. 1178 cmd := exec.Command(*flagExtld, "-fuse-ld=gold", "-Wl,--version") 1179 if out, err := cmd.CombinedOutput(); err == nil { 1180 if !bytes.Contains(out, []byte("GNU gold")) { 1181 log.Fatalf("ARM external linker must be gold (issue #15696), but is not: %s", out) 1182 } 1183 } 1184 } 1185 } 1186 1187 if Iself && len(buildinfo) > 0 { 1188 argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo)) 1189 } 1190 1191 // On Windows, given -o foo, GCC will append ".exe" to produce 1192 // "foo.exe". We have decided that we want to honor the -o 1193 // option. To make this work, we append a '.' so that GCC 1194 // will decide that the file already has an extension. We 1195 // only want to do this when producing a Windows output file 1196 // on a Windows host. 1197 outopt := *flagOutfile 1198 if objabi.GOOS == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" { 1199 outopt += "." 1200 } 1201 argv = append(argv, "-o") 1202 argv = append(argv, outopt) 1203 1204 if rpath.val != "" { 1205 argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val)) 1206 } 1207 1208 // Force global symbols to be exported for dlopen, etc. 1209 if Iself { 1210 argv = append(argv, "-rdynamic") 1211 } 1212 1213 if strings.Contains(argv[0], "clang") { 1214 argv = append(argv, "-Qunused-arguments") 1215 } 1216 1217 argv = append(argv, filepath.Join(*flagTmpdir, "go.o")) 1218 argv = append(argv, hostobjCopy()...) 1219 1220 if *FlagLinkshared { 1221 seenDirs := make(map[string]bool) 1222 seenLibs := make(map[string]bool) 1223 addshlib := func(path string) { 1224 dir, base := filepath.Split(path) 1225 if !seenDirs[dir] { 1226 argv = append(argv, "-L"+dir) 1227 if !rpath.set { 1228 argv = append(argv, "-Wl,-rpath="+dir) 1229 } 1230 seenDirs[dir] = true 1231 } 1232 base = strings.TrimSuffix(base, ".so") 1233 base = strings.TrimPrefix(base, "lib") 1234 if !seenLibs[base] { 1235 argv = append(argv, "-l"+base) 1236 seenLibs[base] = true 1237 } 1238 } 1239 for _, shlib := range l.Shlibs { 1240 addshlib(shlib.Path) 1241 for _, dep := range shlib.Deps { 1242 if dep == "" { 1243 continue 1244 } 1245 libpath := findshlib(l, dep) 1246 if libpath != "" { 1247 addshlib(libpath) 1248 } 1249 } 1250 } 1251 } 1252 1253 argv = append(argv, ldflag...) 1254 1255 // When building a program with the default -buildmode=exe the 1256 // gc compiler generates code requires DT_TEXTREL in a 1257 // position independent executable (PIE). On systems where the 1258 // toolchain creates PIEs by default, and where DT_TEXTREL 1259 // does not work, the resulting programs will not run. See 1260 // issue #17847. To avoid this problem pass -no-pie to the 1261 // toolchain if it is supported. 1262 if Buildmode == BuildmodeExe { 1263 src := filepath.Join(*flagTmpdir, "trivial.c") 1264 if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil { 1265 Errorf(nil, "WriteFile trivial.c failed: %v", err) 1266 } 1267 1268 // GCC uses -no-pie, clang uses -nopie. 1269 for _, nopie := range []string{"-no-pie", "-nopie"} { 1270 cmd := exec.Command(argv[0], nopie, "trivial.c") 1271 cmd.Dir = *flagTmpdir 1272 cmd.Env = append([]string{"LC_ALL=C"}, os.Environ()...) 1273 out, err := cmd.CombinedOutput() 1274 // GCC says "unrecognized command line option ‘-no-pie’" 1275 // clang says "unknown argument: '-no-pie'" 1276 supported := err == nil && !bytes.Contains(out, []byte("unrecognized")) && !bytes.Contains(out, []byte("unknown")) 1277 if supported { 1278 argv = append(argv, nopie) 1279 break 1280 } 1281 } 1282 } 1283 1284 for _, p := range strings.Fields(*flagExtldflags) { 1285 argv = append(argv, p) 1286 1287 // clang, unlike GCC, passes -rdynamic to the linker 1288 // even when linking with -static, causing a linker 1289 // error when using GNU ld. So take out -rdynamic if 1290 // we added it. We do it in this order, rather than 1291 // only adding -rdynamic later, so that -*extldflags 1292 // can override -rdynamic without using -static. 1293 if Iself && p == "-static" { 1294 for i := range argv { 1295 if argv[i] == "-rdynamic" { 1296 argv[i] = "-static" 1297 } 1298 } 1299 } 1300 } 1301 if Headtype == objabi.Hwindows { 1302 // use gcc linker script to work around gcc bug 1303 // (see https://golang.org/issue/20183 for details). 1304 p := writeGDBLinkerScript() 1305 argv = append(argv, "-Wl,-T,"+p) 1306 // libmingw32 and libmingwex have some inter-dependencies, 1307 // so must use linker groups. 1308 argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group") 1309 argv = append(argv, peimporteddlls()...) 1310 } 1311 1312 if l.Debugvlog != 0 { 1313 l.Logf("%5.2f host link:", Cputime()) 1314 for _, v := range argv { 1315 l.Logf(" %q", v) 1316 } 1317 l.Logf("\n") 1318 } 1319 1320 if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil { 1321 Exitf("running %s failed: %v\n%s", argv[0], err, out) 1322 } else if len(out) > 0 { 1323 // always print external output even if the command is successful, so that we don't 1324 // swallow linker warnings (see https://golang.org/issue/17935). 1325 l.Logf("%s", out) 1326 } 1327 1328 if !*FlagS && !*FlagW && !debug_s && Headtype == objabi.Hdarwin { 1329 // Skip combining dwarf on arm. 1330 if !SysArch.InFamily(sys.ARM, sys.ARM64) { 1331 dsym := filepath.Join(*flagTmpdir, "go.dwarf") 1332 if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil { 1333 Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out) 1334 } 1335 // Skip combining if `dsymutil` didn't generate a file. See #11994. 1336 if _, err := os.Stat(dsym); os.IsNotExist(err) { 1337 return 1338 } 1339 // For os.Rename to work reliably, must be in same directory as outfile. 1340 combinedOutput := *flagOutfile + "~" 1341 if err := machoCombineDwarf(*flagOutfile, dsym, combinedOutput); err != nil { 1342 Exitf("%s: combining dwarf failed: %v", os.Args[0], err) 1343 } 1344 os.Remove(*flagOutfile) 1345 if err := os.Rename(combinedOutput, *flagOutfile); err != nil { 1346 Exitf("%s: %v", os.Args[0], err) 1347 } 1348 } 1349 } 1350 } 1351 1352 // hostlinkArchArgs returns arguments to pass to the external linker 1353 // based on the architecture. 1354 func hostlinkArchArgs() []string { 1355 switch SysArch.Family { 1356 case sys.I386: 1357 return []string{"-m32"} 1358 case sys.AMD64, sys.PPC64, sys.S390X: 1359 return []string{"-m64"} 1360 case sys.ARM: 1361 return []string{"-marm"} 1362 case sys.ARM64: 1363 // nothing needed 1364 case sys.MIPS64: 1365 return []string{"-mabi=64"} 1366 case sys.MIPS: 1367 return []string{"-mabi=32"} 1368 } 1369 return nil 1370 } 1371 1372 // ldobj loads an input object. If it is a host object (an object 1373 // compiled by a non-Go compiler) it returns the Hostobj pointer. If 1374 // it is a Go object, it returns nil. 1375 func ldobj(ctxt *Link, f *bio.Reader, lib *Library, length int64, pn string, file string, whence int) *Hostobj { 1376 pkg := objabi.PathToPrefix(lib.Pkg) 1377 1378 eof := f.Offset() + length 1379 start := f.Offset() 1380 c1 := bgetc(f) 1381 c2 := bgetc(f) 1382 c3 := bgetc(f) 1383 c4 := bgetc(f) 1384 f.Seek(start, 0) 1385 1386 magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4) 1387 if magic == 0x7f454c46 { // \x7F E L F 1388 return ldhostobj(ldelf, f, pkg, length, pn, file) 1389 } 1390 1391 if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe { 1392 return ldhostobj(ldmacho, f, pkg, length, pn, file) 1393 } 1394 1395 if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 { 1396 return ldhostobj(ldpe, f, pkg, length, pn, file) 1397 } 1398 1399 /* check the header */ 1400 line, err := f.ReadString('\n') 1401 if err != nil { 1402 Errorf(nil, "truncated object file: %s: %v", pn, err) 1403 return nil 1404 } 1405 1406 if !strings.HasPrefix(line, "go object ") { 1407 if strings.HasSuffix(pn, ".go") { 1408 Exitf("%s: uncompiled .go source file", pn) 1409 return nil 1410 } 1411 1412 if line == SysArch.Name { 1413 // old header format: just $GOOS 1414 Errorf(nil, "%s: stale object file", pn) 1415 return nil 1416 } 1417 1418 Errorf(nil, "%s: not an object file", pn) 1419 return nil 1420 } 1421 1422 // First, check that the basic GOOS, GOARCH, and Version match. 1423 t := fmt.Sprintf("%s %s %s ", objabi.GOOS, objabi.GOARCH, objabi.Version) 1424 1425 line = strings.TrimRight(line, "\n") 1426 if !strings.HasPrefix(line[10:]+" ", t) && !*flagF { 1427 Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], t) 1428 return nil 1429 } 1430 1431 // Second, check that longer lines match each other exactly, 1432 // so that the Go compiler and write additional information 1433 // that must be the same from run to run. 1434 if len(line) >= len(t)+10 { 1435 if theline == "" { 1436 theline = line[10:] 1437 } else if theline != line[10:] { 1438 Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], theline) 1439 return nil 1440 } 1441 } 1442 1443 /* skip over exports and other info -- ends with \n!\n */ 1444 import0 := f.Offset() 1445 1446 c1 = '\n' // the last line ended in \n 1447 c2 = bgetc(f) 1448 c3 = bgetc(f) 1449 for c1 != '\n' || c2 != '!' || c3 != '\n' { 1450 c1 = c2 1451 c2 = c3 1452 c3 = bgetc(f) 1453 if c3 == -1 { 1454 Errorf(nil, "truncated object file: %s", pn) 1455 return nil 1456 } 1457 } 1458 1459 import1 := f.Offset() 1460 1461 f.Seek(import0, 0) 1462 ldpkg(ctxt, f, pkg, import1-import0-2, pn, whence) // -2 for !\n 1463 f.Seek(import1, 0) 1464 1465 LoadObjFile(ctxt, f, lib, eof-f.Offset(), pn) 1466 return nil 1467 } 1468 1469 func readelfsymboldata(ctxt *Link, f *elf.File, sym *elf.Symbol) []byte { 1470 data := make([]byte, sym.Size) 1471 sect := f.Sections[sym.Section] 1472 if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE { 1473 Errorf(nil, "reading %s from non-data section", sym.Name) 1474 } 1475 n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr)) 1476 if uint64(n) != sym.Size { 1477 Errorf(nil, "reading contents of %s: %v", sym.Name, err) 1478 } 1479 return data 1480 } 1481 1482 func readwithpad(r io.Reader, sz int32) ([]byte, error) { 1483 data := make([]byte, Rnd(int64(sz), 4)) 1484 _, err := io.ReadFull(r, data) 1485 if err != nil { 1486 return nil, err 1487 } 1488 data = data[:sz] 1489 return data, nil 1490 } 1491 1492 func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) { 1493 for _, sect := range f.Sections { 1494 if sect.Type != elf.SHT_NOTE { 1495 continue 1496 } 1497 r := sect.Open() 1498 for { 1499 var namesize, descsize, noteType int32 1500 err := binary.Read(r, f.ByteOrder, &namesize) 1501 if err != nil { 1502 if err == io.EOF { 1503 break 1504 } 1505 return nil, fmt.Errorf("read namesize failed: %v", err) 1506 } 1507 err = binary.Read(r, f.ByteOrder, &descsize) 1508 if err != nil { 1509 return nil, fmt.Errorf("read descsize failed: %v", err) 1510 } 1511 err = binary.Read(r, f.ByteOrder, ¬eType) 1512 if err != nil { 1513 return nil, fmt.Errorf("read type failed: %v", err) 1514 } 1515 noteName, err := readwithpad(r, namesize) 1516 if err != nil { 1517 return nil, fmt.Errorf("read name failed: %v", err) 1518 } 1519 desc, err := readwithpad(r, descsize) 1520 if err != nil { 1521 return nil, fmt.Errorf("read desc failed: %v", err) 1522 } 1523 if string(name) == string(noteName) && typ == noteType { 1524 return desc, nil 1525 } 1526 } 1527 } 1528 return nil, nil 1529 } 1530 1531 func findshlib(ctxt *Link, shlib string) string { 1532 for _, libdir := range ctxt.Libdir { 1533 libpath := filepath.Join(libdir, shlib) 1534 if _, err := os.Stat(libpath); err == nil { 1535 return libpath 1536 } 1537 } 1538 Errorf(nil, "cannot find shared library: %s", shlib) 1539 return "" 1540 } 1541 1542 func ldshlibsyms(ctxt *Link, shlib string) { 1543 libpath := findshlib(ctxt, shlib) 1544 if libpath == "" { 1545 return 1546 } 1547 for _, processedlib := range ctxt.Shlibs { 1548 if processedlib.Path == libpath { 1549 return 1550 } 1551 } 1552 if ctxt.Debugvlog > 1 { 1553 ctxt.Logf("%5.2f ldshlibsyms: found library with name %s at %s\n", Cputime(), shlib, libpath) 1554 } 1555 1556 f, err := elf.Open(libpath) 1557 if err != nil { 1558 Errorf(nil, "cannot open shared library: %s", libpath) 1559 return 1560 } 1561 1562 hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG) 1563 if err != nil { 1564 Errorf(nil, "cannot read ABI hash from shared library %s: %v", libpath, err) 1565 return 1566 } 1567 1568 depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG) 1569 if err != nil { 1570 Errorf(nil, "cannot read dep list from shared library %s: %v", libpath, err) 1571 return 1572 } 1573 deps := strings.Split(string(depsbytes), "\n") 1574 1575 syms, err := f.DynamicSymbols() 1576 if err != nil { 1577 Errorf(nil, "cannot read symbols from shared library: %s", libpath) 1578 return 1579 } 1580 gcdataLocations := make(map[uint64]*Symbol) 1581 for _, elfsym := range syms { 1582 if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION { 1583 continue 1584 } 1585 lsym := ctxt.Syms.Lookup(elfsym.Name, 0) 1586 // Because loadlib above loads all .a files before loading any shared 1587 // libraries, any non-dynimport symbols we find that duplicate symbols 1588 // already loaded should be ignored (the symbols from the .a files 1589 // "win"). 1590 if lsym.Type != 0 && lsym.Type != SDYNIMPORT { 1591 continue 1592 } 1593 lsym.Type = SDYNIMPORT 1594 lsym.ElfType = elf.ST_TYPE(elfsym.Info) 1595 lsym.Size = int64(elfsym.Size) 1596 if elfsym.Section != elf.SHN_UNDEF { 1597 // Set .File for the library that actually defines the symbol. 1598 lsym.File = libpath 1599 // The decodetype_* functions in decodetype.go need access to 1600 // the type data. 1601 if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") { 1602 lsym.P = readelfsymboldata(ctxt, f, &elfsym) 1603 gcdataLocations[elfsym.Value+2*uint64(SysArch.PtrSize)+8+1*uint64(SysArch.PtrSize)] = lsym 1604 } 1605 } 1606 } 1607 gcdataAddresses := make(map[*Symbol]uint64) 1608 if SysArch.Family == sys.ARM64 { 1609 for _, sect := range f.Sections { 1610 if sect.Type == elf.SHT_RELA { 1611 var rela elf.Rela64 1612 rdr := sect.Open() 1613 for { 1614 err := binary.Read(rdr, f.ByteOrder, &rela) 1615 if err == io.EOF { 1616 break 1617 } else if err != nil { 1618 Errorf(nil, "reading relocation failed %v", err) 1619 return 1620 } 1621 t := elf.R_AARCH64(rela.Info & 0xffff) 1622 if t != elf.R_AARCH64_RELATIVE { 1623 continue 1624 } 1625 if lsym, ok := gcdataLocations[rela.Off]; ok { 1626 gcdataAddresses[lsym] = uint64(rela.Addend) 1627 } 1628 } 1629 } 1630 } 1631 } 1632 1633 ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdataAddresses: gcdataAddresses}) 1634 } 1635 1636 func addsection(seg *Segment, name string, rwx int) *Section { 1637 sect := new(Section) 1638 sect.Rwx = uint8(rwx) 1639 sect.Name = name 1640 sect.Seg = seg 1641 sect.Align = int32(SysArch.PtrSize) // everything is at least pointer-aligned 1642 seg.Sections = append(seg.Sections, sect) 1643 return sect 1644 } 1645 1646 func Le16(b []byte) uint16 { 1647 return uint16(b[0]) | uint16(b[1])<<8 1648 } 1649 1650 func Le32(b []byte) uint32 { 1651 return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 1652 } 1653 1654 func Le64(b []byte) uint64 { 1655 return uint64(Le32(b)) | uint64(Le32(b[4:]))<<32 1656 } 1657 1658 func Be16(b []byte) uint16 { 1659 return uint16(b[0])<<8 | uint16(b[1]) 1660 } 1661 1662 func Be32(b []byte) uint32 { 1663 return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]) 1664 } 1665 1666 type chain struct { 1667 sym *Symbol 1668 up *chain 1669 limit int // limit on entry to sym 1670 } 1671 1672 var morestack *Symbol 1673 1674 // TODO: Record enough information in new object files to 1675 // allow stack checks here. 1676 1677 func haslinkregister(ctxt *Link) bool { 1678 return ctxt.FixedFrameSize() != 0 1679 } 1680 1681 func callsize(ctxt *Link) int { 1682 if haslinkregister(ctxt) { 1683 return 0 1684 } 1685 return SysArch.RegSize 1686 } 1687 1688 func (ctxt *Link) dostkcheck() { 1689 var ch chain 1690 1691 morestack = ctxt.Syms.Lookup("runtime.morestack", 0) 1692 1693 // Every splitting function ensures that there are at least StackLimit 1694 // bytes available below SP when the splitting prologue finishes. 1695 // If the splitting function calls F, then F begins execution with 1696 // at least StackLimit - callsize() bytes available. 1697 // Check that every function behaves correctly with this amount 1698 // of stack, following direct calls in order to piece together chains 1699 // of non-splitting functions. 1700 ch.up = nil 1701 1702 ch.limit = objabi.StackLimit - callsize(ctxt) 1703 1704 // Check every function, but do the nosplit functions in a first pass, 1705 // to make the printed failure chains as short as possible. 1706 for _, s := range ctxt.Textp { 1707 // runtime.racesymbolizethunk is called from gcc-compiled C 1708 // code running on the operating system thread stack. 1709 // It uses more than the usual amount of stack but that's okay. 1710 if s.Name == "runtime.racesymbolizethunk" { 1711 continue 1712 } 1713 1714 if s.Attr.NoSplit() { 1715 ch.sym = s 1716 stkcheck(ctxt, &ch, 0) 1717 } 1718 } 1719 1720 for _, s := range ctxt.Textp { 1721 if !s.Attr.NoSplit() { 1722 ch.sym = s 1723 stkcheck(ctxt, &ch, 0) 1724 } 1725 } 1726 } 1727 1728 func stkcheck(ctxt *Link, up *chain, depth int) int { 1729 limit := up.limit 1730 s := up.sym 1731 1732 // Don't duplicate work: only need to consider each 1733 // function at top of safe zone once. 1734 top := limit == objabi.StackLimit-callsize(ctxt) 1735 if top { 1736 if s.Attr.StackCheck() { 1737 return 0 1738 } 1739 s.Attr |= AttrStackCheck 1740 } 1741 1742 if depth > 100 { 1743 Errorf(s, "nosplit stack check too deep") 1744 stkbroke(ctxt, up, 0) 1745 return -1 1746 } 1747 1748 if s.Attr.External() || s.FuncInfo == nil { 1749 // external function. 1750 // should never be called directly. 1751 // onlyctxt.Diagnose the direct caller. 1752 // TODO(mwhudson): actually think about this. 1753 if depth == 1 && s.Type != SXREF && !ctxt.DynlinkingGo() && 1754 Buildmode != BuildmodeCArchive && Buildmode != BuildmodePIE && Buildmode != BuildmodeCShared && Buildmode != BuildmodePlugin { 1755 1756 Errorf(s, "call to external function") 1757 } 1758 return -1 1759 } 1760 1761 if limit < 0 { 1762 stkbroke(ctxt, up, limit) 1763 return -1 1764 } 1765 1766 // morestack looks like it calls functions, 1767 // but it switches the stack pointer first. 1768 if s == morestack { 1769 return 0 1770 } 1771 1772 var ch chain 1773 ch.up = up 1774 1775 if !s.Attr.NoSplit() { 1776 // Ensure we have enough stack to call morestack. 1777 ch.limit = limit - callsize(ctxt) 1778 ch.sym = morestack 1779 if stkcheck(ctxt, &ch, depth+1) < 0 { 1780 return -1 1781 } 1782 if !top { 1783 return 0 1784 } 1785 // Raise limit to allow frame. 1786 locals := int32(0) 1787 if s.FuncInfo != nil { 1788 locals = s.FuncInfo.Locals 1789 } 1790 limit = int(objabi.StackLimit+locals) + int(ctxt.FixedFrameSize()) 1791 } 1792 1793 // Walk through sp adjustments in function, consuming relocs. 1794 ri := 0 1795 1796 endr := len(s.R) 1797 var ch1 chain 1798 var pcsp Pciter 1799 var r *Reloc 1800 for pciterinit(ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) { 1801 // pcsp.value is in effect for [pcsp.pc, pcsp.nextpc). 1802 1803 // Check stack size in effect for this span. 1804 if int32(limit)-pcsp.value < 0 { 1805 stkbroke(ctxt, up, int(int32(limit)-pcsp.value)) 1806 return -1 1807 } 1808 1809 // Process calls in this span. 1810 for ; ri < endr && uint32(s.R[ri].Off) < pcsp.nextpc; ri++ { 1811 r = &s.R[ri] 1812 switch r.Type { 1813 // Direct call. 1814 case objabi.R_CALL, objabi.R_CALLARM, objabi.R_CALLARM64, objabi.R_CALLPOWER, objabi.R_CALLMIPS: 1815 ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt))) 1816 ch.sym = r.Sym 1817 if stkcheck(ctxt, &ch, depth+1) < 0 { 1818 return -1 1819 } 1820 1821 // Indirect call. Assume it is a call to a splitting function, 1822 // so we have to make sure it can call morestack. 1823 // Arrange the data structures to report both calls, so that 1824 // if there is an error, stkprint shows all the steps involved. 1825 case objabi.R_CALLIND: 1826 ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt))) 1827 1828 ch.sym = nil 1829 ch1.limit = ch.limit - callsize(ctxt) // for morestack in called prologue 1830 ch1.up = &ch 1831 ch1.sym = morestack 1832 if stkcheck(ctxt, &ch1, depth+2) < 0 { 1833 return -1 1834 } 1835 } 1836 } 1837 } 1838 1839 return 0 1840 } 1841 1842 func stkbroke(ctxt *Link, ch *chain, limit int) { 1843 Errorf(ch.sym, "nosplit stack overflow") 1844 stkprint(ctxt, ch, limit) 1845 } 1846 1847 func stkprint(ctxt *Link, ch *chain, limit int) { 1848 var name string 1849 1850 if ch.sym != nil { 1851 name = ch.sym.Name 1852 if ch.sym.Attr.NoSplit() { 1853 name += " (nosplit)" 1854 } 1855 } else { 1856 name = "function pointer" 1857 } 1858 1859 if ch.up == nil { 1860 // top of chain. ch->sym != nil. 1861 if ch.sym.Attr.NoSplit() { 1862 fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name) 1863 } else { 1864 fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name) 1865 } 1866 } else { 1867 stkprint(ctxt, ch.up, ch.limit+callsize(ctxt)) 1868 if !haslinkregister(ctxt) { 1869 fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name) 1870 } 1871 } 1872 1873 if ch.limit != limit { 1874 fmt.Printf("\t%d\tafter %s uses %d\n", limit, name, ch.limit-limit) 1875 } 1876 } 1877 1878 func Cflush() { 1879 if err := coutbuf.w.Flush(); err != nil { 1880 Exitf("flushing %s: %v", coutbuf.f.Name(), err) 1881 } 1882 } 1883 1884 func Cseek(p int64) { 1885 if p == coutbuf.off { 1886 return 1887 } 1888 Cflush() 1889 if _, err := coutbuf.f.Seek(p, 0); err != nil { 1890 Exitf("seeking in output [0, 1]: %v", err) 1891 } 1892 coutbuf.off = p 1893 } 1894 1895 func Cwritestring(s string) { 1896 coutbuf.WriteString(s) 1897 } 1898 1899 func Cwrite(p []byte) { 1900 coutbuf.Write(p) 1901 } 1902 1903 func Cput(c uint8) { 1904 coutbuf.w.WriteByte(c) 1905 coutbuf.off++ 1906 } 1907 1908 func usage() { 1909 fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n") 1910 objabi.Flagprint(2) 1911 Exit(2) 1912 } 1913 1914 func doversion() { 1915 Exitf("version %s", objabi.Version) 1916 } 1917 1918 type SymbolType int8 1919 1920 const ( 1921 TextSym SymbolType = 'T' 1922 DataSym = 'D' 1923 BSSSym = 'B' 1924 UndefinedSym = 'U' 1925 TLSSym = 't' 1926 FileSym = 'f' 1927 FrameSym = 'm' 1928 ParamSym = 'p' 1929 AutoSym = 'a' 1930 ) 1931 1932 func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *Symbol)) { 1933 // These symbols won't show up in the first loop below because we 1934 // skip STEXT symbols. Normal STEXT symbols are emitted by walking textp. 1935 s := ctxt.Syms.Lookup("runtime.text", 0) 1936 if s.Type == STEXT { 1937 put(ctxt, s, s.Name, TextSym, s.Value, nil) 1938 } 1939 1940 n := 0 1941 1942 // Generate base addresses for all text sections if there are multiple 1943 for _, sect := range Segtext.Sections { 1944 if n == 0 { 1945 n++ 1946 continue 1947 } 1948 if sect.Name != ".text" { 1949 break 1950 } 1951 s = ctxt.Syms.ROLookup(fmt.Sprintf("runtime.text.%d", n), 0) 1952 if s == nil { 1953 break 1954 } 1955 if s.Type == STEXT { 1956 put(ctxt, s, s.Name, TextSym, s.Value, nil) 1957 } 1958 n++ 1959 } 1960 1961 s = ctxt.Syms.Lookup("runtime.etext", 0) 1962 if s.Type == STEXT { 1963 put(ctxt, s, s.Name, TextSym, s.Value, nil) 1964 } 1965 1966 for _, s := range ctxt.Syms.Allsym { 1967 if s.Attr.NotInSymbolTable() { 1968 continue 1969 } 1970 if (s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC." { 1971 continue 1972 } 1973 switch s.Type & SMASK { 1974 case SCONST, 1975 SRODATA, 1976 SSYMTAB, 1977 SPCLNTAB, 1978 SINITARR, 1979 SDATA, 1980 SNOPTRDATA, 1981 SELFROSECT, 1982 SMACHOGOT, 1983 STYPE, 1984 SSTRING, 1985 SGOSTRING, 1986 SGOFUNC, 1987 SGCBITS, 1988 STYPERELRO, 1989 SSTRINGRELRO, 1990 SGOSTRINGRELRO, 1991 SGOFUNCRELRO, 1992 SGCBITSRELRO, 1993 SRODATARELRO, 1994 STYPELINK, 1995 SITABLINK, 1996 SWINDOWS: 1997 if !s.Attr.Reachable() { 1998 continue 1999 } 2000 put(ctxt, s, s.Name, DataSym, Symaddr(s), s.Gotype) 2001 2002 case SBSS, SNOPTRBSS: 2003 if !s.Attr.Reachable() { 2004 continue 2005 } 2006 if len(s.P) > 0 { 2007 Errorf(s, "should not be bss (size=%d type=%v special=%v)", len(s.P), s.Type, s.Attr.Special()) 2008 } 2009 put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype) 2010 2011 case SFILE: 2012 put(ctxt, nil, s.Name, FileSym, s.Value, nil) 2013 2014 case SHOSTOBJ: 2015 if Headtype == objabi.Hwindows || Iself { 2016 put(ctxt, s, s.Name, UndefinedSym, s.Value, nil) 2017 } 2018 2019 case SDYNIMPORT: 2020 if !s.Attr.Reachable() { 2021 continue 2022 } 2023 put(ctxt, s, s.Extname, UndefinedSym, 0, nil) 2024 2025 case STLSBSS: 2026 if Linkmode == LinkExternal { 2027 put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype) 2028 } 2029 } 2030 } 2031 2032 var off int32 2033 for _, s := range ctxt.Textp { 2034 put(ctxt, s, s.Name, TextSym, s.Value, s.Gotype) 2035 2036 locals := int32(0) 2037 if s.FuncInfo != nil { 2038 locals = s.FuncInfo.Locals 2039 } 2040 // NOTE(ality): acid can't produce a stack trace without .frame symbols 2041 put(ctxt, nil, ".frame", FrameSym, int64(locals)+int64(SysArch.PtrSize), nil) 2042 2043 if s.FuncInfo == nil { 2044 continue 2045 } 2046 for _, a := range s.FuncInfo.Autom { 2047 // Emit a or p according to actual offset, even if label is wrong. 2048 // This avoids negative offsets, which cannot be encoded. 2049 if a.Name != objabi.A_AUTO && a.Name != objabi.A_PARAM { 2050 continue 2051 } 2052 2053 // compute offset relative to FP 2054 if a.Name == objabi.A_PARAM { 2055 off = a.Aoffset 2056 } else { 2057 off = a.Aoffset - int32(SysArch.PtrSize) 2058 } 2059 2060 // FP 2061 if off >= 0 { 2062 put(ctxt, nil, a.Asym.Name, ParamSym, int64(off), a.Gotype) 2063 continue 2064 } 2065 2066 // SP 2067 if off <= int32(-SysArch.PtrSize) { 2068 put(ctxt, nil, a.Asym.Name, AutoSym, -(int64(off) + int64(SysArch.PtrSize)), a.Gotype) 2069 continue 2070 } 2071 // Otherwise, off is addressing the saved program counter. 2072 // Something underhanded is going on. Say nothing. 2073 } 2074 } 2075 2076 if ctxt.Debugvlog != 0 || *flagN { 2077 ctxt.Logf("%5.2f symsize = %d\n", Cputime(), uint32(Symsize)) 2078 } 2079 } 2080 2081 func Symaddr(s *Symbol) int64 { 2082 if !s.Attr.Reachable() { 2083 Errorf(s, "unreachable symbol in symaddr") 2084 } 2085 return s.Value 2086 } 2087 2088 func (ctxt *Link) xdefine(p string, t SymKind, v int64) { 2089 s := ctxt.Syms.Lookup(p, 0) 2090 s.Type = t 2091 s.Value = v 2092 s.Attr |= AttrReachable 2093 s.Attr |= AttrSpecial 2094 s.Attr |= AttrLocal 2095 } 2096 2097 func datoff(s *Symbol, addr int64) int64 { 2098 if uint64(addr) >= Segdata.Vaddr { 2099 return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff) 2100 } 2101 if uint64(addr) >= Segtext.Vaddr { 2102 return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff) 2103 } 2104 Errorf(s, "invalid datoff %#x", addr) 2105 return 0 2106 } 2107 2108 func Entryvalue(ctxt *Link) int64 { 2109 a := *flagEntrySymbol 2110 if a[0] >= '0' && a[0] <= '9' { 2111 return atolwhex(a) 2112 } 2113 s := ctxt.Syms.Lookup(a, 0) 2114 if s.Type == 0 { 2115 return *FlagTextAddr 2116 } 2117 if s.Type != STEXT { 2118 Errorf(s, "entry not text") 2119 } 2120 return s.Value 2121 } 2122 2123 func undefsym(ctxt *Link, s *Symbol) { 2124 var r *Reloc 2125 2126 for i := 0; i < len(s.R); i++ { 2127 r = &s.R[i] 2128 if r.Sym == nil { // happens for some external ARM relocs 2129 continue 2130 } 2131 if r.Sym.Type == Sxxx || r.Sym.Type == SXREF { 2132 Errorf(s, "undefined: %q", r.Sym.Name) 2133 } 2134 if !r.Sym.Attr.Reachable() && r.Type != objabi.R_WEAKADDROFF { 2135 Errorf(s, "relocation target %q", r.Sym.Name) 2136 } 2137 } 2138 } 2139 2140 func (ctxt *Link) undef() { 2141 for _, s := range ctxt.Textp { 2142 undefsym(ctxt, s) 2143 } 2144 for _, s := range datap { 2145 undefsym(ctxt, s) 2146 } 2147 if nerrors > 0 { 2148 errorexit() 2149 } 2150 } 2151 2152 func (ctxt *Link) callgraph() { 2153 if !*FlagC { 2154 return 2155 } 2156 2157 var i int 2158 var r *Reloc 2159 for _, s := range ctxt.Textp { 2160 for i = 0; i < len(s.R); i++ { 2161 r = &s.R[i] 2162 if r.Sym == nil { 2163 continue 2164 } 2165 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 { 2166 ctxt.Logf("%s calls %s\n", s.Name, r.Sym.Name) 2167 } 2168 } 2169 } 2170 } 2171 2172 func Rnd(v int64, r int64) int64 { 2173 if r <= 0 { 2174 return v 2175 } 2176 v += r - 1 2177 c := v % r 2178 if c < 0 { 2179 c += r 2180 } 2181 v -= c 2182 return v 2183 } 2184 2185 func bgetc(r *bio.Reader) int { 2186 c, err := r.ReadByte() 2187 if err != nil { 2188 if err != io.EOF { 2189 log.Fatalf("reading input: %v", err) 2190 } 2191 return -1 2192 } 2193 return int(c) 2194 } 2195 2196 type markKind uint8 // for postorder traversal 2197 const ( 2198 unvisited markKind = iota 2199 visiting 2200 visited 2201 ) 2202 2203 func postorder(libs []*Library) []*Library { 2204 order := make([]*Library, 0, len(libs)) // hold the result 2205 mark := make(map[*Library]markKind, len(libs)) 2206 for _, lib := range libs { 2207 dfs(lib, mark, &order) 2208 } 2209 return order 2210 } 2211 2212 func dfs(lib *Library, mark map[*Library]markKind, order *[]*Library) { 2213 if mark[lib] == visited { 2214 return 2215 } 2216 if mark[lib] == visiting { 2217 panic("found import cycle while visiting " + lib.Pkg) 2218 } 2219 mark[lib] = visiting 2220 for _, i := range lib.imports { 2221 dfs(i, mark, order) 2222 } 2223 mark[lib] = visited 2224 *order = append(*order, lib) 2225 }