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