github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/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 "github.com/gagliardetto/golang-go/cmd/internal/bio" 37 "github.com/gagliardetto/golang-go/cmd/internal/obj" 38 "github.com/gagliardetto/golang-go/cmd/internal/objabi" 39 "github.com/gagliardetto/golang-go/cmd/internal/sys" 40 "github.com/gagliardetto/golang-go/cmd/link/internal/loadelf" 41 "github.com/gagliardetto/golang-go/cmd/link/internal/loader" 42 "github.com/gagliardetto/golang-go/cmd/link/internal/loadmacho" 43 "github.com/gagliardetto/golang-go/cmd/link/internal/loadpe" 44 "github.com/gagliardetto/golang-go/cmd/link/internal/loadxcoff" 45 "github.com/gagliardetto/golang-go/cmd/link/internal/objfile" 46 "github.com/gagliardetto/golang-go/cmd/link/internal/sym" 47 "crypto/sha1" 48 "debug/elf" 49 "debug/macho" 50 "encoding/base64" 51 "encoding/binary" 52 "encoding/hex" 53 "fmt" 54 "io" 55 "io/ioutil" 56 "log" 57 "os" 58 "os/exec" 59 "path/filepath" 60 "runtime" 61 "sort" 62 "strings" 63 "sync" 64 ) 65 66 // Data layout and relocation. 67 68 // Derived from Inferno utils/6l/l.h 69 // https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h 70 // 71 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 72 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 73 // Portions Copyright © 1997-1999 Vita Nuova Limited 74 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 75 // Portions Copyright © 2004,2006 Bruce Ellis 76 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 77 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 78 // Portions Copyright © 2009 The Go Authors. All rights reserved. 79 // 80 // Permission is hereby granted, free of charge, to any person obtaining a copy 81 // of this software and associated documentation files (the "Software"), to deal 82 // in the Software without restriction, including without limitation the rights 83 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 84 // copies of the Software, and to permit persons to whom the Software is 85 // furnished to do so, subject to the following conditions: 86 // 87 // The above copyright notice and this permission notice shall be included in 88 // all copies or substantial portions of the Software. 89 // 90 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 91 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 92 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 93 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 94 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 95 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 96 // THE SOFTWARE. 97 98 type Arch struct { 99 Funcalign int 100 Maxalign int 101 Minalign int 102 Dwarfregsp int 103 Dwarfreglr int 104 Linuxdynld string 105 Freebsddynld string 106 Netbsddynld string 107 Openbsddynld string 108 Dragonflydynld string 109 Solarisdynld string 110 Adddynrel func(*Link, *sym.Symbol, *sym.Reloc) bool 111 Archinit func(*Link) 112 // Archreloc is an arch-specific hook that assists in 113 // relocation processing (invoked by 'relocsym'); it handles 114 // target-specific relocation tasks. Here "rel" is the current 115 // relocation being examined, "sym" is the symbol containing the 116 // chunk of data to which the relocation applies, and "off" is the 117 // contents of the to-be-relocated data item (from sym.P). Return 118 // value is the appropriately relocated value (to be written back 119 // to the same spot in sym.P) and a boolean indicating 120 // success/failure (a failing value indicates a fatal error). 121 Archreloc func(link *Link, rel *sym.Reloc, sym *sym.Symbol, 122 offset int64) (relocatedOffset int64, success bool) 123 // Archrelocvariant is a second arch-specific hook used for 124 // relocation processing; it handles relocations where r.Type is 125 // insufficient to describe the relocation (r.Variant != 126 // sym.RV_NONE). Here "rel" is the relocation being applied, "sym" 127 // is the symbol containing the chunk of data to which the 128 // relocation applies, and "off" is the contents of the 129 // to-be-relocated data item (from sym.P). Return is an updated 130 // offset value. 131 Archrelocvariant func(link *Link, rel *sym.Reloc, sym *sym.Symbol, 132 offset int64) (relocatedOffset int64) 133 Trampoline func(*Link, *sym.Reloc, *sym.Symbol) 134 135 // Asmb and Asmb2 are arch-specific routines that write the output 136 // file. Typically, Asmb writes most of the content (sections and 137 // segments), for which we have computed the size and offset. Asmb2 138 // writes the rest. 139 Asmb func(*Link) 140 Asmb2 func(*Link) 141 142 Elfreloc1 func(*Link, *sym.Reloc, int64) bool 143 Elfsetupplt func(*Link) 144 Gentext func(*Link) 145 Machoreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool 146 PEreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool 147 Xcoffreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool 148 149 // TLSIEtoLE converts a TLS Initial Executable relocation to 150 // a TLS Local Executable relocation. 151 // 152 // This is possible when a TLS IE relocation refers to a local 153 // symbol in an executable, which is typical when internally 154 // linking PIE binaries. 155 TLSIEtoLE func(s *sym.Symbol, off, size int) 156 157 // optional override for assignAddress 158 AssignAddress func(ctxt *Link, sect *sym.Section, n int, s *sym.Symbol, va uint64, isTramp bool) (*sym.Section, int, uint64) 159 } 160 161 var ( 162 thearch Arch 163 Lcsize int32 164 rpath Rpath 165 Spsize int32 166 Symsize int32 167 ) 168 169 const ( 170 MINFUNC = 16 // minimum size for a function 171 ) 172 173 // DynlinkingGo reports whether we are producing Go code that can live 174 // in separate shared libraries linked together at runtime. 175 func (ctxt *Link) DynlinkingGo() bool { 176 if !ctxt.Loaded { 177 panic("DynlinkingGo called before all symbols loaded") 178 } 179 return ctxt.BuildMode == BuildModeShared || ctxt.linkShared || ctxt.BuildMode == BuildModePlugin || ctxt.canUsePlugins 180 } 181 182 // CanUsePlugins reports whether a plugins can be used 183 func (ctxt *Link) CanUsePlugins() bool { 184 if !ctxt.Loaded { 185 panic("CanUsePlugins called before all symbols loaded") 186 } 187 return ctxt.canUsePlugins 188 } 189 190 // UseRelro reports whether to make use of "read only relocations" aka 191 // relro. 192 func (ctxt *Link) UseRelro() bool { 193 switch ctxt.BuildMode { 194 case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePIE, BuildModePlugin: 195 return ctxt.IsELF || ctxt.HeadType == objabi.Haix 196 default: 197 return ctxt.linkShared || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) 198 } 199 } 200 201 var ( 202 dynexp []*sym.Symbol 203 dynlib []string 204 ldflag []string 205 havedynamic int 206 Funcalign int 207 iscgo bool 208 elfglobalsymndx int 209 interpreter string 210 211 debug_s bool // backup old value of debug['s'] 212 HEADR int32 213 214 nerrors int 215 liveness int64 216 217 // See -strictdups command line flag. 218 checkStrictDups int // 0=off 1=warning 2=error 219 strictDupMsgCount int 220 ) 221 222 var ( 223 Segtext sym.Segment 224 Segrodata sym.Segment 225 Segrelrodata sym.Segment 226 Segdata sym.Segment 227 Segdwarf sym.Segment 228 ) 229 230 const pkgdef = "__.PKGDEF" 231 232 var ( 233 // Set if we see an object compiled by the host compiler that is not 234 // from a package that is known to support internal linking mode. 235 externalobj = false 236 theline string 237 ) 238 239 func Lflag(ctxt *Link, arg string) { 240 ctxt.Libdir = append(ctxt.Libdir, arg) 241 } 242 243 /* 244 * Unix doesn't like it when we write to a running (or, sometimes, 245 * recently run) binary, so remove the output file before writing it. 246 * On Windows 7, remove() can force a subsequent create() to fail. 247 * S_ISREG() does not exist on Plan 9. 248 */ 249 func mayberemoveoutfile() { 250 if fi, err := os.Lstat(*flagOutfile); err == nil && !fi.Mode().IsRegular() { 251 return 252 } 253 os.Remove(*flagOutfile) 254 } 255 256 func libinit(ctxt *Link) { 257 Funcalign = thearch.Funcalign 258 259 // add goroot to the end of the libdir list. 260 suffix := "" 261 262 suffixsep := "" 263 if *flagInstallSuffix != "" { 264 suffixsep = "_" 265 suffix = *flagInstallSuffix 266 } else if *flagRace { 267 suffixsep = "_" 268 suffix = "race" 269 } else if *flagMsan { 270 suffixsep = "_" 271 suffix = "msan" 272 } 273 274 Lflag(ctxt, filepath.Join(objabi.GOROOT, "pkg", fmt.Sprintf("%s_%s%s%s", objabi.GOOS, objabi.GOARCH, suffixsep, suffix))) 275 276 mayberemoveoutfile() 277 f, err := os.OpenFile(*flagOutfile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775) 278 if err != nil { 279 Exitf("cannot create %s: %v", *flagOutfile, err) 280 } 281 282 ctxt.Out.w = bufio.NewWriter(f) 283 ctxt.Out.f = f 284 285 if *flagEntrySymbol == "" { 286 switch ctxt.BuildMode { 287 case BuildModeCShared, BuildModeCArchive: 288 *flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s_lib", objabi.GOARCH, objabi.GOOS) 289 case BuildModeExe, BuildModePIE: 290 *flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s", objabi.GOARCH, objabi.GOOS) 291 case BuildModeShared, BuildModePlugin: 292 // No *flagEntrySymbol for -buildmode=shared and plugin 293 default: 294 Errorf(nil, "unknown *flagEntrySymbol for buildmode %v", ctxt.BuildMode) 295 } 296 } 297 } 298 299 func exitIfErrors() { 300 if nerrors != 0 || checkStrictDups > 1 && strictDupMsgCount > 0 { 301 mayberemoveoutfile() 302 Exit(2) 303 } 304 305 } 306 307 func errorexit() { 308 exitIfErrors() 309 Exit(0) 310 } 311 312 func loadinternal(ctxt *Link, name string) *sym.Library { 313 if ctxt.linkShared && ctxt.PackageShlib != nil { 314 if shlib := ctxt.PackageShlib[name]; shlib != "" { 315 return addlibpath(ctxt, "internal", "internal", "", name, shlib) 316 } 317 } 318 if ctxt.PackageFile != nil { 319 if pname := ctxt.PackageFile[name]; pname != "" { 320 return addlibpath(ctxt, "internal", "internal", pname, name, "") 321 } 322 ctxt.Logf("loadinternal: cannot find %s\n", name) 323 return nil 324 } 325 326 for _, libdir := range ctxt.Libdir { 327 if ctxt.linkShared { 328 shlibname := filepath.Join(libdir, name+".shlibname") 329 if ctxt.Debugvlog != 0 { 330 ctxt.Logf("searching for %s.a in %s\n", name, shlibname) 331 } 332 if _, err := os.Stat(shlibname); err == nil { 333 return addlibpath(ctxt, "internal", "internal", "", name, shlibname) 334 } 335 } 336 pname := filepath.Join(libdir, name+".a") 337 if ctxt.Debugvlog != 0 { 338 ctxt.Logf("searching for %s.a in %s\n", name, pname) 339 } 340 if _, err := os.Stat(pname); err == nil { 341 return addlibpath(ctxt, "internal", "internal", pname, name, "") 342 } 343 } 344 345 ctxt.Logf("warning: unable to find %s.a\n", name) 346 return nil 347 } 348 349 // extld returns the current external linker. 350 func (ctxt *Link) extld() string { 351 if *flagExtld == "" { 352 *flagExtld = "gcc" 353 } 354 return *flagExtld 355 } 356 357 // findLibPathCmd uses cmd command to find gcc library libname. 358 // It returns library full path if found, or "none" if not found. 359 func (ctxt *Link) findLibPathCmd(cmd, libname string) string { 360 extld := ctxt.extld() 361 args := hostlinkArchArgs(ctxt.Arch) 362 args = append(args, cmd) 363 if ctxt.Debugvlog != 0 { 364 ctxt.Logf("%s %v\n", extld, args) 365 } 366 out, err := exec.Command(extld, args...).Output() 367 if err != nil { 368 if ctxt.Debugvlog != 0 { 369 ctxt.Logf("not using a %s file because compiler failed\n%v\n%s\n", libname, err, out) 370 } 371 return "none" 372 } 373 return strings.TrimSpace(string(out)) 374 } 375 376 // findLibPath searches for library libname. 377 // It returns library full path if found, or "none" if not found. 378 func (ctxt *Link) findLibPath(libname string) string { 379 return ctxt.findLibPathCmd("--print-file-name="+libname, libname) 380 } 381 382 func (ctxt *Link) loadlib() { 383 if *flagNewobj { 384 var flags uint32 385 switch *FlagStrictDups { 386 case 0: 387 // nothing to do 388 case 1, 2: 389 flags = loader.FlagStrictDups 390 default: 391 log.Fatalf("invalid -strictdups flag value %d", *FlagStrictDups) 392 } 393 ctxt.loader = loader.NewLoader(flags) 394 } 395 396 ctxt.cgo_export_static = make(map[string]bool) 397 ctxt.cgo_export_dynamic = make(map[string]bool) 398 399 // ctxt.Library grows during the loop, so not a range loop. 400 i := 0 401 for ; i < len(ctxt.Library); i++ { 402 lib := ctxt.Library[i] 403 if lib.Shlib == "" { 404 if ctxt.Debugvlog > 1 { 405 ctxt.Logf("autolib: %s (from %s)\n", lib.File, lib.Objref) 406 } 407 loadobjfile(ctxt, lib) 408 } 409 } 410 411 // load internal packages, if not already 412 if ctxt.Arch.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 loadinternal(ctxt, "runtime") 422 for ; i < len(ctxt.Library); i++ { 423 lib := ctxt.Library[i] 424 if lib.Shlib == "" { 425 loadobjfile(ctxt, lib) 426 } 427 } 428 429 if *flagNewobj { 430 iscgo = ctxt.loader.Lookup("x_cgo_init", 0) != 0 431 ctxt.canUsePlugins = ctxt.loader.Lookup("plugin.Open", sym.SymVerABIInternal) != 0 432 } else { 433 iscgo = ctxt.Syms.ROLookup("x_cgo_init", 0) != nil 434 ctxt.canUsePlugins = ctxt.Syms.ROLookup("plugin.Open", sym.SymVerABIInternal) != nil 435 } 436 437 // We now have enough information to determine the link mode. 438 determineLinkMode(ctxt) 439 440 if ctxt.LinkMode == LinkExternal && !iscgo && ctxt.LibraryByPkg["runtime/cgo"] == nil && !(objabi.GOOS == "darwin" && ctxt.BuildMode != BuildModePlugin && (ctxt.Arch.Family == sys.AMD64 || ctxt.Arch.Family == sys.I386)) { 441 // This indicates a user requested -linkmode=external. 442 // The startup code uses an import of runtime/cgo to decide 443 // whether to initialize the TLS. So give it one. This could 444 // be handled differently but it's an unusual case. 445 if lib := loadinternal(ctxt, "runtime/cgo"); lib != nil { 446 if lib.Shlib != "" { 447 ldshlibsyms(ctxt, lib.Shlib) 448 } else { 449 if ctxt.BuildMode == BuildModeShared || ctxt.linkShared { 450 Exitf("cannot implicitly include runtime/cgo in a shared library") 451 } 452 loadobjfile(ctxt, lib) 453 } 454 } 455 } 456 457 for _, lib := range ctxt.Library { 458 if lib.Shlib != "" { 459 if ctxt.Debugvlog > 1 { 460 ctxt.Logf("autolib: %s (from %s)\n", lib.Shlib, lib.Objref) 461 } 462 ldshlibsyms(ctxt, lib.Shlib) 463 } 464 } 465 466 if ctxt.LinkMode == LinkInternal && len(hostobj) != 0 { 467 if *flagNewobj { 468 // In newobj mode, we typically create sym.Symbols later therefore 469 // also set cgo attributes later. However, for internal cgo linking, 470 // the host object loaders still work with sym.Symbols (for now), 471 // and they need cgo attributes set to work properly. So process 472 // them now. 473 lookup := func(name string, ver int) *sym.Symbol { return ctxt.loader.LookupOrCreate(name, ver, ctxt.Syms) } 474 for _, d := range ctxt.cgodata { 475 setCgoAttr(ctxt, lookup, d.file, d.pkg, d.directives) 476 } 477 ctxt.cgodata = nil 478 } 479 480 // Drop all the cgo_import_static declarations. 481 // Turns out we won't be needing them. 482 for _, s := range ctxt.Syms.Allsym { 483 if s.Type == sym.SHOSTOBJ { 484 // If a symbol was marked both 485 // cgo_import_static and cgo_import_dynamic, 486 // then we want to make it cgo_import_dynamic 487 // now. 488 if s.Extname() != "" && s.Dynimplib() != "" && !s.Attr.CgoExport() { 489 s.Type = sym.SDYNIMPORT 490 } else { 491 s.Type = 0 492 } 493 } 494 } 495 } 496 497 // Conditionally load host objects, or setup for external linking. 498 hostobjs(ctxt) 499 hostlinksetup(ctxt) 500 501 if *flagNewobj { 502 // Add references of externally defined symbols. 503 ctxt.loader.LoadRefs(ctxt.Arch, ctxt.Syms) 504 } 505 506 // Now that we know the link mode, set the dynexp list. 507 if !*flagNewobj { // set this later in newobj mode 508 setupdynexp(ctxt) 509 } 510 511 if ctxt.LinkMode == LinkInternal && len(hostobj) != 0 { 512 // If we have any undefined symbols in external 513 // objects, try to read them from the libgcc file. 514 any := false 515 for _, s := range ctxt.Syms.Allsym { 516 for i := range s.R { 517 r := &s.R[i] // Copying sym.Reloc has measurable impact on performance 518 if r.Sym != nil && r.Sym.Type == sym.SXREF && r.Sym.Name != ".got" { 519 any = true 520 break 521 } 522 } 523 } 524 if any { 525 if *flagLibGCC == "" { 526 *flagLibGCC = ctxt.findLibPathCmd("--print-libgcc-file-name", "libgcc") 527 } 528 if runtime.GOOS == "openbsd" && *flagLibGCC == "libgcc.a" { 529 // On OpenBSD `clang --print-libgcc-file-name` returns "libgcc.a". 530 // In this case we fail to load libgcc.a and can encounter link 531 // errors - see if we can find libcompiler_rt.a instead. 532 *flagLibGCC = ctxt.findLibPathCmd("--print-file-name=libcompiler_rt.a", "libcompiler_rt") 533 } 534 if *flagLibGCC != "none" { 535 hostArchive(ctxt, *flagLibGCC) 536 } 537 if ctxt.HeadType == objabi.Hwindows { 538 if p := ctxt.findLibPath("libmingwex.a"); p != "none" { 539 hostArchive(ctxt, p) 540 } 541 if p := ctxt.findLibPath("libmingw32.a"); p != "none" { 542 hostArchive(ctxt, p) 543 } 544 // Link libmsvcrt.a to resolve '__acrt_iob_func' symbol 545 // (see https://golang.org/issue/23649 for details). 546 if p := ctxt.findLibPath("libmsvcrt.a"); p != "none" { 547 hostArchive(ctxt, p) 548 } 549 // TODO: maybe do something similar to peimporteddlls to collect all lib names 550 // and try link them all to final exe just like libmingwex.a and libmingw32.a: 551 /* 552 for: 553 #cgo windows LDFLAGS: -lmsvcrt -lm 554 import: 555 libmsvcrt.a libm.a 556 */ 557 } 558 } 559 } 560 561 // We've loaded all the code now. 562 ctxt.Loaded = true 563 564 importcycles() 565 566 if *flagNewobj { 567 strictDupMsgCount = ctxt.loader.NStrictDupMsgs() 568 } 569 } 570 571 // Set up dynexp list. 572 func setupdynexp(ctxt *Link) { 573 dynexpMap := ctxt.cgo_export_dynamic 574 if ctxt.LinkMode == LinkExternal { 575 dynexpMap = ctxt.cgo_export_static 576 } 577 dynexp = make([]*sym.Symbol, 0, len(dynexpMap)) 578 for exp := range dynexpMap { 579 s := ctxt.Syms.Lookup(exp, 0) 580 dynexp = append(dynexp, s) 581 } 582 sort.Sort(byName(dynexp)) 583 584 // Resolve ABI aliases in the list of cgo-exported functions. 585 // This is necessary because we load the ABI0 symbol for all 586 // cgo exports. 587 for i, s := range dynexp { 588 if s.Type != sym.SABIALIAS { 589 continue 590 } 591 t := resolveABIAlias(s) 592 t.Attr |= s.Attr 593 t.SetExtname(s.Extname()) 594 dynexp[i] = t 595 } 596 597 ctxt.cgo_export_static = nil 598 ctxt.cgo_export_dynamic = nil 599 } 600 601 // Set up flags and special symbols depending on the platform build mode. 602 func (ctxt *Link) linksetup() { 603 switch ctxt.BuildMode { 604 case BuildModeCShared, BuildModePlugin: 605 s := ctxt.Syms.Lookup("runtime.islibrary", 0) 606 s.Type = sym.SNOPTRDATA 607 s.Attr |= sym.AttrDuplicateOK 608 s.AddUint8(1) 609 case BuildModeCArchive: 610 s := ctxt.Syms.Lookup("runtime.isarchive", 0) 611 s.Type = sym.SNOPTRDATA 612 s.Attr |= sym.AttrDuplicateOK 613 s.AddUint8(1) 614 } 615 616 // Recalculate pe parameters now that we have ctxt.LinkMode set. 617 if ctxt.HeadType == objabi.Hwindows { 618 Peinit(ctxt) 619 } 620 621 if ctxt.HeadType == objabi.Hdarwin && ctxt.LinkMode == LinkExternal { 622 *FlagTextAddr = 0 623 } 624 625 // If there are no dynamic libraries needed, gcc disables dynamic linking. 626 // Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13) 627 // assumes that a dynamic binary always refers to at least one dynamic library. 628 // Rather than be a source of test cases for glibc, disable dynamic linking 629 // the same way that gcc would. 630 // 631 // Exception: on OS X, programs such as Shark only work with dynamic 632 // binaries, so leave it enabled on OS X (Mach-O) binaries. 633 // Also leave it enabled on Solaris which doesn't support 634 // statically linked binaries. 635 if ctxt.BuildMode == BuildModeExe { 636 if havedynamic == 0 && ctxt.HeadType != objabi.Hdarwin && ctxt.HeadType != objabi.Hsolaris { 637 *FlagD = true 638 } 639 } 640 641 if ctxt.LinkMode == LinkExternal && ctxt.Arch.Family == sys.PPC64 && objabi.GOOS != "aix" { 642 toc := ctxt.Syms.Lookup(".TOC.", 0) 643 toc.Type = sym.SDYNIMPORT 644 } 645 646 // The Android Q linker started to complain about underalignment of the our TLS 647 // section. We don't actually use the section on android, so dont't 648 // generate it. 649 if objabi.GOOS != "android" { 650 tlsg := ctxt.Syms.Lookup("runtime.tlsg", 0) 651 652 // runtime.tlsg is used for external linking on platforms that do not define 653 // a variable to hold g in assembly (currently only intel). 654 if tlsg.Type == 0 { 655 tlsg.Type = sym.STLSBSS 656 tlsg.Size = int64(ctxt.Arch.PtrSize) 657 } else if tlsg.Type != sym.SDYNIMPORT { 658 Errorf(nil, "runtime declared tlsg variable %v", tlsg.Type) 659 } 660 tlsg.Attr |= sym.AttrReachable 661 ctxt.Tlsg = tlsg 662 } 663 664 var moduledata *sym.Symbol 665 if ctxt.BuildMode == BuildModePlugin { 666 moduledata = ctxt.Syms.Lookup("local.pluginmoduledata", 0) 667 moduledata.Attr |= sym.AttrLocal 668 } else { 669 moduledata = ctxt.Syms.Lookup("runtime.firstmoduledata", 0) 670 } 671 if moduledata.Type != 0 && moduledata.Type != sym.SDYNIMPORT { 672 // If the module (toolchain-speak for "executable or shared 673 // library") we are linking contains the runtime package, it 674 // will define the runtime.firstmoduledata symbol and we 675 // truncate it back to 0 bytes so we can define its entire 676 // contents in symtab.go:symtab(). 677 moduledata.Size = 0 678 679 // In addition, on ARM, the runtime depends on the linker 680 // recording the value of GOARM. 681 if ctxt.Arch.Family == sys.ARM { 682 s := ctxt.Syms.Lookup("runtime.goarm", 0) 683 s.Type = sym.SDATA 684 s.Size = 0 685 s.AddUint8(uint8(objabi.GOARM)) 686 } 687 688 if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) { 689 s := ctxt.Syms.Lookup("runtime.framepointer_enabled", 0) 690 s.Type = sym.SDATA 691 s.Size = 0 692 s.AddUint8(1) 693 } 694 } else { 695 // If OTOH the module does not contain the runtime package, 696 // create a local symbol for the moduledata. 697 moduledata = ctxt.Syms.Lookup("local.moduledata", 0) 698 moduledata.Attr |= sym.AttrLocal 699 } 700 // In all cases way we mark the moduledata as noptrdata to hide it from 701 // the GC. 702 moduledata.Type = sym.SNOPTRDATA 703 moduledata.Attr |= sym.AttrReachable 704 ctxt.Moduledata = moduledata 705 706 // If package versioning is required, generate a hash of the 707 // packages used in the link. 708 if ctxt.BuildMode == BuildModeShared || ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() { 709 for _, lib := range ctxt.Library { 710 if lib.Shlib == "" { 711 genhash(ctxt, lib) 712 } 713 } 714 } 715 716 if ctxt.Arch == sys.Arch386 && ctxt.HeadType != objabi.Hwindows { 717 if (ctxt.BuildMode == BuildModeCArchive && ctxt.IsELF) || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE || ctxt.DynlinkingGo() { 718 got := ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0) 719 got.Type = sym.SDYNIMPORT 720 got.Attr |= sym.AttrReachable 721 } 722 } 723 } 724 725 // mangleTypeSym shortens the names of symbols that represent Go types 726 // if they are visible in the symbol table. 727 // 728 // As the names of these symbols are derived from the string of 729 // the type, they can run to many kilobytes long. So we shorten 730 // them using a SHA-1 when the name appears in the final binary. 731 // This also removes characters that upset external linkers. 732 // 733 // These are the symbols that begin with the prefix 'type.' and 734 // contain run-time type information used by the runtime and reflect 735 // packages. All Go binaries contain these symbols, but only 736 // those programs loaded dynamically in multiple parts need these 737 // symbols to have entries in the symbol table. 738 func (ctxt *Link) mangleTypeSym() { 739 if ctxt.BuildMode != BuildModeShared && !ctxt.linkShared && ctxt.BuildMode != BuildModePlugin && !ctxt.CanUsePlugins() { 740 return 741 } 742 743 for _, s := range ctxt.Syms.Allsym { 744 newName := typeSymbolMangle(s.Name) 745 if newName != s.Name { 746 ctxt.Syms.Rename(s.Name, newName, int(s.Version), ctxt.Reachparent) 747 } 748 } 749 } 750 751 // typeSymbolMangle mangles the given symbol name into something shorter. 752 // 753 // Keep the type.. prefix, which parts of the linker (like the 754 // DWARF generator) know means the symbol is not decodable. 755 // Leave type.runtime. symbols alone, because other parts of 756 // the linker manipulates them. 757 func typeSymbolMangle(name string) string { 758 if !strings.HasPrefix(name, "type.") { 759 return name 760 } 761 if strings.HasPrefix(name, "type.runtime.") { 762 return name 763 } 764 if len(name) <= 14 && !strings.Contains(name, "@") { // Issue 19529 765 return name 766 } 767 hash := sha1.Sum([]byte(name)) 768 prefix := "type." 769 if name[5] == '.' { 770 prefix = "type.." 771 } 772 return prefix + base64.StdEncoding.EncodeToString(hash[:6]) 773 } 774 775 /* 776 * look for the next file in an archive. 777 * adapted from libmach. 778 */ 779 func nextar(bp *bio.Reader, off int64, a *ArHdr) int64 { 780 if off&1 != 0 { 781 off++ 782 } 783 bp.MustSeek(off, 0) 784 var buf [SAR_HDR]byte 785 if n, err := io.ReadFull(bp, buf[:]); err != nil { 786 if n == 0 && err != io.EOF { 787 return -1 788 } 789 return 0 790 } 791 792 a.name = artrim(buf[0:16]) 793 a.date = artrim(buf[16:28]) 794 a.uid = artrim(buf[28:34]) 795 a.gid = artrim(buf[34:40]) 796 a.mode = artrim(buf[40:48]) 797 a.size = artrim(buf[48:58]) 798 a.fmag = artrim(buf[58:60]) 799 800 arsize := atolwhex(a.size) 801 if arsize&1 != 0 { 802 arsize++ 803 } 804 return arsize + SAR_HDR 805 } 806 807 func genhash(ctxt *Link, lib *sym.Library) { 808 f, err := bio.Open(lib.File) 809 if err != nil { 810 Errorf(nil, "cannot open file %s for hash generation: %v", lib.File, err) 811 return 812 } 813 defer f.Close() 814 815 var magbuf [len(ARMAG)]byte 816 if _, err := io.ReadFull(f, magbuf[:]); err != nil { 817 Exitf("file %s too short", lib.File) 818 } 819 820 if string(magbuf[:]) != ARMAG { 821 Exitf("%s is not an archive file", lib.File) 822 } 823 824 var arhdr ArHdr 825 l := nextar(f, f.Offset(), &arhdr) 826 if l <= 0 { 827 Errorf(nil, "%s: short read on archive file symbol header", lib.File) 828 return 829 } 830 if arhdr.name != pkgdef { 831 Errorf(nil, "%s: missing package data entry", lib.File) 832 return 833 } 834 835 h := sha1.New() 836 837 // To compute the hash of a package, we hash the first line of 838 // __.PKGDEF (which contains the toolchain version and any 839 // GOEXPERIMENT flags) and the export data (which is between 840 // the first two occurrences of "\n$$"). 841 842 pkgDefBytes := make([]byte, atolwhex(arhdr.size)) 843 _, err = io.ReadFull(f, pkgDefBytes) 844 if err != nil { 845 Errorf(nil, "%s: error reading package data: %v", lib.File, err) 846 return 847 } 848 firstEOL := bytes.IndexByte(pkgDefBytes, '\n') 849 if firstEOL < 0 { 850 Errorf(nil, "cannot parse package data of %s for hash generation, no newline found", lib.File) 851 return 852 } 853 firstDoubleDollar := bytes.Index(pkgDefBytes, []byte("\n$$")) 854 if firstDoubleDollar < 0 { 855 Errorf(nil, "cannot parse package data of %s for hash generation, no \\n$$ found", lib.File) 856 return 857 } 858 secondDoubleDollar := bytes.Index(pkgDefBytes[firstDoubleDollar+1:], []byte("\n$$")) 859 if secondDoubleDollar < 0 { 860 Errorf(nil, "cannot parse package data of %s for hash generation, only one \\n$$ found", lib.File) 861 return 862 } 863 h.Write(pkgDefBytes[0:firstEOL]) 864 h.Write(pkgDefBytes[firstDoubleDollar : firstDoubleDollar+secondDoubleDollar]) 865 lib.Hash = hex.EncodeToString(h.Sum(nil)) 866 } 867 868 func loadobjfile(ctxt *Link, lib *sym.Library) { 869 pkg := objabi.PathToPrefix(lib.Pkg) 870 871 if ctxt.Debugvlog > 1 { 872 ctxt.Logf("ldobj: %s (%s)\n", lib.File, pkg) 873 } 874 f, err := bio.Open(lib.File) 875 if err != nil { 876 Exitf("cannot open file %s: %v", lib.File, err) 877 } 878 defer f.Close() 879 defer func() { 880 if pkg == "main" && !lib.Main { 881 Exitf("%s: not package main", lib.File) 882 } 883 884 // Ideally, we'd check that *all* object files within 885 // the archive were marked safe, but here we settle 886 // for *any*. 887 // 888 // Historically, cmd/link only checked the __.PKGDEF 889 // file, which in turn came from the first object 890 // file, typically produced by cmd/compile. The 891 // remaining object files are normally produced by 892 // cmd/asm, which doesn't support marking files as 893 // safe anyway. So at least in practice, this matches 894 // how safe mode has always worked. 895 if *flagU && !lib.Safe { 896 Exitf("%s: load of unsafe package %s", lib.File, pkg) 897 } 898 }() 899 900 for i := 0; i < len(ARMAG); i++ { 901 if c, err := f.ReadByte(); err == nil && c == ARMAG[i] { 902 continue 903 } 904 905 /* load it as a regular file */ 906 l := f.MustSeek(0, 2) 907 f.MustSeek(0, 0) 908 ldobj(ctxt, f, lib, l, lib.File, lib.File) 909 return 910 } 911 912 /* 913 * load all the object files from the archive now. 914 * this gives us sequential file access and keeps us 915 * from needing to come back later to pick up more 916 * objects. it breaks the usual C archive model, but 917 * this is Go, not C. the common case in Go is that 918 * we need to load all the objects, and then we throw away 919 * the individual symbols that are unused. 920 * 921 * loading every object will also make it possible to 922 * load foreign objects not referenced by __.PKGDEF. 923 */ 924 var arhdr ArHdr 925 off := f.Offset() 926 for { 927 l := nextar(f, off, &arhdr) 928 if l == 0 { 929 break 930 } 931 if l < 0 { 932 Exitf("%s: malformed archive", lib.File) 933 } 934 off += l 935 936 // __.PKGDEF isn't a real Go object file, and it's 937 // absent in -linkobj builds anyway. Skipping it 938 // ensures consistency between -linkobj and normal 939 // build modes. 940 if arhdr.name == pkgdef { 941 continue 942 } 943 944 // Skip other special (non-object-file) sections that 945 // build tools may have added. Such sections must have 946 // short names so that the suffix is not truncated. 947 if len(arhdr.name) < 16 { 948 if ext := filepath.Ext(arhdr.name); ext != ".o" && ext != ".syso" { 949 continue 950 } 951 } 952 953 pname := fmt.Sprintf("%s(%s)", lib.File, arhdr.name) 954 l = atolwhex(arhdr.size) 955 ldobj(ctxt, f, lib, l, pname, lib.File) 956 } 957 } 958 959 type Hostobj struct { 960 ld func(*Link, *bio.Reader, string, int64, string) 961 pkg string 962 pn string 963 file string 964 off int64 965 length int64 966 } 967 968 var hostobj []Hostobj 969 970 // These packages can use internal linking mode. 971 // Others trigger external mode. 972 var internalpkg = []string{ 973 "crypto/x509", 974 "net", 975 "os/user", 976 "runtime/cgo", 977 "runtime/race", 978 "runtime/msan", 979 } 980 981 func ldhostobj(ld func(*Link, *bio.Reader, string, int64, string), headType objabi.HeadType, f *bio.Reader, pkg string, length int64, pn string, file string) *Hostobj { 982 isinternal := false 983 for _, intpkg := range internalpkg { 984 if pkg == intpkg { 985 isinternal = true 986 break 987 } 988 } 989 990 // DragonFly declares errno with __thread, which results in a symbol 991 // type of R_386_TLS_GD or R_X86_64_TLSGD. The Go linker does not 992 // currently know how to handle TLS relocations, hence we have to 993 // force external linking for any libraries that link in code that 994 // uses errno. This can be removed if the Go linker ever supports 995 // these relocation types. 996 if headType == objabi.Hdragonfly { 997 if pkg == "net" || pkg == "os/user" { 998 isinternal = false 999 } 1000 } 1001 1002 if !isinternal { 1003 externalobj = true 1004 } 1005 1006 hostobj = append(hostobj, Hostobj{}) 1007 h := &hostobj[len(hostobj)-1] 1008 h.ld = ld 1009 h.pkg = pkg 1010 h.pn = pn 1011 h.file = file 1012 h.off = f.Offset() 1013 h.length = length 1014 return h 1015 } 1016 1017 func hostobjs(ctxt *Link) { 1018 if ctxt.LinkMode != LinkInternal { 1019 return 1020 } 1021 var h *Hostobj 1022 1023 for i := 0; i < len(hostobj); i++ { 1024 h = &hostobj[i] 1025 f, err := bio.Open(h.file) 1026 if err != nil { 1027 Exitf("cannot reopen %s: %v", h.pn, err) 1028 } 1029 1030 f.MustSeek(h.off, 0) 1031 h.ld(ctxt, f, h.pkg, h.length, h.pn) 1032 f.Close() 1033 } 1034 } 1035 1036 func hostlinksetup(ctxt *Link) { 1037 if ctxt.LinkMode != LinkExternal { 1038 return 1039 } 1040 1041 // For external link, record that we need to tell the external linker -s, 1042 // and turn off -s internally: the external linker needs the symbol 1043 // information for its final link. 1044 debug_s = *FlagS 1045 *FlagS = false 1046 1047 // create temporary directory and arrange cleanup 1048 if *flagTmpdir == "" { 1049 dir, err := ioutil.TempDir("", "go-link-") 1050 if err != nil { 1051 log.Fatal(err) 1052 } 1053 *flagTmpdir = dir 1054 ownTmpDir = true 1055 AtExit(func() { 1056 ctxt.Out.f.Close() 1057 os.RemoveAll(*flagTmpdir) 1058 }) 1059 } 1060 1061 // change our output to temporary object file 1062 ctxt.Out.f.Close() 1063 mayberemoveoutfile() 1064 1065 p := filepath.Join(*flagTmpdir, "go.o") 1066 var err error 1067 f, err := os.OpenFile(p, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775) 1068 if err != nil { 1069 Exitf("cannot create %s: %v", p, err) 1070 } 1071 1072 ctxt.Out.w = bufio.NewWriter(f) 1073 ctxt.Out.f = f 1074 ctxt.Out.off = 0 1075 } 1076 1077 // hostobjCopy creates a copy of the object files in hostobj in a 1078 // temporary directory. 1079 func hostobjCopy() (paths []string) { 1080 var wg sync.WaitGroup 1081 sema := make(chan struct{}, runtime.NumCPU()) // limit open file descriptors 1082 for i, h := range hostobj { 1083 h := h 1084 dst := filepath.Join(*flagTmpdir, fmt.Sprintf("%06d.o", i)) 1085 paths = append(paths, dst) 1086 1087 wg.Add(1) 1088 go func() { 1089 sema <- struct{}{} 1090 defer func() { 1091 <-sema 1092 wg.Done() 1093 }() 1094 f, err := os.Open(h.file) 1095 if err != nil { 1096 Exitf("cannot reopen %s: %v", h.pn, err) 1097 } 1098 defer f.Close() 1099 if _, err := f.Seek(h.off, 0); err != nil { 1100 Exitf("cannot seek %s: %v", h.pn, err) 1101 } 1102 1103 w, err := os.Create(dst) 1104 if err != nil { 1105 Exitf("cannot create %s: %v", dst, err) 1106 } 1107 if _, err := io.CopyN(w, f, h.length); err != nil { 1108 Exitf("cannot write %s: %v", dst, err) 1109 } 1110 if err := w.Close(); err != nil { 1111 Exitf("cannot close %s: %v", dst, err) 1112 } 1113 }() 1114 } 1115 wg.Wait() 1116 return paths 1117 } 1118 1119 // writeGDBLinkerScript creates gcc linker script file in temp 1120 // directory. writeGDBLinkerScript returns created file path. 1121 // The script is used to work around gcc bug 1122 // (see https://golang.org/issue/20183 for details). 1123 func writeGDBLinkerScript() string { 1124 name := "fix_debug_gdb_scripts.ld" 1125 path := filepath.Join(*flagTmpdir, name) 1126 src := `SECTIONS 1127 { 1128 .debug_gdb_scripts BLOCK(__section_alignment__) (NOLOAD) : 1129 { 1130 *(.debug_gdb_scripts) 1131 } 1132 } 1133 INSERT AFTER .debug_types; 1134 ` 1135 err := ioutil.WriteFile(path, []byte(src), 0666) 1136 if err != nil { 1137 Errorf(nil, "WriteFile %s failed: %v", name, err) 1138 } 1139 return path 1140 } 1141 1142 // archive builds a .a archive from the hostobj object files. 1143 func (ctxt *Link) archive() { 1144 if ctxt.BuildMode != BuildModeCArchive { 1145 return 1146 } 1147 1148 exitIfErrors() 1149 1150 if *flagExtar == "" { 1151 *flagExtar = "ar" 1152 } 1153 1154 mayberemoveoutfile() 1155 1156 // Force the buffer to flush here so that external 1157 // tools will see a complete file. 1158 ctxt.Out.Flush() 1159 if err := ctxt.Out.f.Close(); err != nil { 1160 Exitf("close: %v", err) 1161 } 1162 ctxt.Out.f = nil 1163 1164 argv := []string{*flagExtar, "-q", "-c", "-s"} 1165 if ctxt.HeadType == objabi.Haix { 1166 argv = append(argv, "-X64") 1167 } 1168 argv = append(argv, *flagOutfile) 1169 argv = append(argv, filepath.Join(*flagTmpdir, "go.o")) 1170 argv = append(argv, hostobjCopy()...) 1171 1172 if ctxt.Debugvlog != 0 { 1173 ctxt.Logf("archive: %s\n", strings.Join(argv, " ")) 1174 } 1175 1176 // If supported, use syscall.Exec() to invoke the archive command, 1177 // which should be the final remaining step needed for the link. 1178 // This will reduce peak RSS for the link (and speed up linking of 1179 // large applications), since when the archive command runs we 1180 // won't be holding onto all of the linker's live memory. 1181 if syscallExecSupported && !ownTmpDir { 1182 runAtExitFuncs() 1183 ctxt.execArchive(argv) 1184 panic("should not get here") 1185 } 1186 1187 // Otherwise invoke 'ar' in the usual way (fork + exec). 1188 if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil { 1189 Exitf("running %s failed: %v\n%s", argv[0], err, out) 1190 } 1191 } 1192 1193 func (ctxt *Link) hostlink() { 1194 if ctxt.LinkMode != LinkExternal || nerrors > 0 { 1195 return 1196 } 1197 if ctxt.BuildMode == BuildModeCArchive { 1198 return 1199 } 1200 1201 var argv []string 1202 argv = append(argv, ctxt.extld()) 1203 argv = append(argv, hostlinkArchArgs(ctxt.Arch)...) 1204 1205 if *FlagS || debug_s { 1206 if ctxt.HeadType == objabi.Hdarwin { 1207 // Recent versions of macOS print 1208 // ld: warning: option -s is obsolete and being ignored 1209 // so do not pass any arguments. 1210 } else { 1211 argv = append(argv, "-s") 1212 } 1213 } 1214 1215 switch ctxt.HeadType { 1216 case objabi.Hdarwin: 1217 if machoPlatform == PLATFORM_MACOS { 1218 // -headerpad is incompatible with -fembed-bitcode. 1219 argv = append(argv, "-Wl,-headerpad,1144") 1220 } 1221 if ctxt.DynlinkingGo() && !ctxt.Arch.InFamily(sys.ARM, sys.ARM64) { 1222 argv = append(argv, "-Wl,-flat_namespace") 1223 } 1224 case objabi.Hopenbsd: 1225 argv = append(argv, "-Wl,-nopie") 1226 case objabi.Hwindows: 1227 if windowsgui { 1228 argv = append(argv, "-mwindows") 1229 } else { 1230 argv = append(argv, "-mconsole") 1231 } 1232 // Mark as having awareness of terminal services, to avoid 1233 // ancient compatibility hacks. 1234 argv = append(argv, "-Wl,--tsaware") 1235 1236 // Enable DEP 1237 argv = append(argv, "-Wl,--nxcompat") 1238 1239 argv = append(argv, fmt.Sprintf("-Wl,--major-os-version=%d", PeMinimumTargetMajorVersion)) 1240 argv = append(argv, fmt.Sprintf("-Wl,--minor-os-version=%d", PeMinimumTargetMinorVersion)) 1241 argv = append(argv, fmt.Sprintf("-Wl,--major-subsystem-version=%d", PeMinimumTargetMajorVersion)) 1242 argv = append(argv, fmt.Sprintf("-Wl,--minor-subsystem-version=%d", PeMinimumTargetMinorVersion)) 1243 case objabi.Haix: 1244 argv = append(argv, "-pthread") 1245 // prevent ld to reorder .text functions to keep the same 1246 // first/last functions for moduledata. 1247 argv = append(argv, "-Wl,-bnoobjreorder") 1248 // mcmodel=large is needed for every gcc generated files, but 1249 // ld still need -bbigtoc in order to allow larger TOC. 1250 argv = append(argv, "-mcmodel=large") 1251 argv = append(argv, "-Wl,-bbigtoc") 1252 } 1253 1254 switch ctxt.BuildMode { 1255 case BuildModeExe: 1256 if ctxt.HeadType == objabi.Hdarwin { 1257 if machoPlatform == PLATFORM_MACOS { 1258 argv = append(argv, "-Wl,-no_pie") 1259 argv = append(argv, "-Wl,-pagezero_size,4000000") 1260 } 1261 } 1262 case BuildModePIE: 1263 // ELF. 1264 if ctxt.HeadType != objabi.Hdarwin && ctxt.HeadType != objabi.Haix { 1265 if ctxt.UseRelro() { 1266 argv = append(argv, "-Wl,-z,relro") 1267 } 1268 argv = append(argv, "-pie") 1269 } 1270 case BuildModeCShared: 1271 if ctxt.HeadType == objabi.Hdarwin { 1272 argv = append(argv, "-dynamiclib") 1273 if ctxt.Arch.Family != sys.AMD64 { 1274 argv = append(argv, "-Wl,-read_only_relocs,suppress") 1275 } 1276 } else { 1277 // ELF. 1278 argv = append(argv, "-Wl,-Bsymbolic") 1279 if ctxt.UseRelro() { 1280 argv = append(argv, "-Wl,-z,relro") 1281 } 1282 argv = append(argv, "-shared") 1283 if ctxt.HeadType != objabi.Hwindows { 1284 // Pass -z nodelete to mark the shared library as 1285 // non-closeable: a dlclose will do nothing. 1286 argv = append(argv, "-Wl,-z,nodelete") 1287 } 1288 } 1289 case BuildModeShared: 1290 if ctxt.UseRelro() { 1291 argv = append(argv, "-Wl,-z,relro") 1292 } 1293 argv = append(argv, "-shared") 1294 case BuildModePlugin: 1295 if ctxt.HeadType == objabi.Hdarwin { 1296 argv = append(argv, "-dynamiclib") 1297 } else { 1298 if ctxt.UseRelro() { 1299 argv = append(argv, "-Wl,-z,relro") 1300 } 1301 argv = append(argv, "-shared") 1302 } 1303 } 1304 1305 if ctxt.IsELF && ctxt.DynlinkingGo() { 1306 // We force all symbol resolution to be done at program startup 1307 // because lazy PLT resolution can use large amounts of stack at 1308 // times we cannot allow it to do so. 1309 argv = append(argv, "-Wl,-znow") 1310 1311 // Do not let the host linker generate COPY relocations. These 1312 // can move symbols out of sections that rely on stable offsets 1313 // from the beginning of the section (like sym.STYPE). 1314 argv = append(argv, "-Wl,-znocopyreloc") 1315 1316 if ctxt.Arch.InFamily(sys.ARM, sys.ARM64) && objabi.GOOS == "linux" { 1317 // On ARM, the GNU linker will generate COPY relocations 1318 // even with -znocopyreloc set. 1319 // https://sourceware.org/bugzilla/show_bug.cgi?id=19962 1320 // 1321 // On ARM64, the GNU linker will fail instead of 1322 // generating COPY relocations. 1323 // 1324 // In both cases, switch to gold. 1325 argv = append(argv, "-fuse-ld=gold") 1326 1327 // If gold is not installed, gcc will silently switch 1328 // back to ld.bfd. So we parse the version information 1329 // and provide a useful error if gold is missing. 1330 cmd := exec.Command(*flagExtld, "-fuse-ld=gold", "-Wl,--version") 1331 if out, err := cmd.CombinedOutput(); err == nil { 1332 if !bytes.Contains(out, []byte("GNU gold")) { 1333 log.Fatalf("ARM external linker must be gold (issue #15696), but is not: %s", out) 1334 } 1335 } 1336 } 1337 } 1338 1339 if ctxt.Arch.Family == sys.ARM64 && objabi.GOOS == "freebsd" { 1340 // Switch to ld.bfd on freebsd/arm64. 1341 argv = append(argv, "-fuse-ld=bfd") 1342 1343 // Provide a useful error if ld.bfd is missing. 1344 cmd := exec.Command(*flagExtld, "-fuse-ld=bfd", "-Wl,--version") 1345 if out, err := cmd.CombinedOutput(); err == nil { 1346 if !bytes.Contains(out, []byte("GNU ld")) { 1347 log.Fatalf("ARM64 external linker must be ld.bfd (issue #35197), please install devel/binutils") 1348 } 1349 } 1350 } 1351 1352 if ctxt.IsELF && len(buildinfo) > 0 { 1353 argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo)) 1354 } 1355 1356 // On Windows, given -o foo, GCC will append ".exe" to produce 1357 // "foo.exe". We have decided that we want to honor the -o 1358 // option. To make this work, we append a '.' so that GCC 1359 // will decide that the file already has an extension. We 1360 // only want to do this when producing a Windows output file 1361 // on a Windows host. 1362 outopt := *flagOutfile 1363 if objabi.GOOS == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" { 1364 outopt += "." 1365 } 1366 argv = append(argv, "-o") 1367 argv = append(argv, outopt) 1368 1369 if rpath.val != "" { 1370 argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val)) 1371 } 1372 1373 // Force global symbols to be exported for dlopen, etc. 1374 if ctxt.IsELF { 1375 argv = append(argv, "-rdynamic") 1376 } 1377 if ctxt.HeadType == objabi.Haix { 1378 fileName := xcoffCreateExportFile(ctxt) 1379 argv = append(argv, "-Wl,-bE:"+fileName) 1380 } 1381 1382 if strings.Contains(argv[0], "clang") { 1383 argv = append(argv, "-Qunused-arguments") 1384 } 1385 1386 const compressDWARF = "-Wl,--compress-debug-sections=zlib-gnu" 1387 if ctxt.compressDWARF && linkerFlagSupported(argv[0], compressDWARF) { 1388 argv = append(argv, compressDWARF) 1389 } 1390 1391 argv = append(argv, filepath.Join(*flagTmpdir, "go.o")) 1392 argv = append(argv, hostobjCopy()...) 1393 if ctxt.HeadType == objabi.Haix { 1394 // We want to have C files after Go files to remove 1395 // trampolines csects made by ld. 1396 argv = append(argv, "-nostartfiles") 1397 argv = append(argv, "/lib/crt0_64.o") 1398 1399 extld := ctxt.extld() 1400 // Get starting files. 1401 getPathFile := func(file string) string { 1402 args := []string{"-maix64", "--print-file-name=" + file} 1403 out, err := exec.Command(extld, args...).CombinedOutput() 1404 if err != nil { 1405 log.Fatalf("running %s failed: %v\n%s", extld, err, out) 1406 } 1407 return strings.Trim(string(out), "\n") 1408 } 1409 argv = append(argv, getPathFile("crtcxa.o")) 1410 argv = append(argv, getPathFile("crtdbase.o")) 1411 } 1412 1413 if ctxt.linkShared { 1414 seenDirs := make(map[string]bool) 1415 seenLibs := make(map[string]bool) 1416 addshlib := func(path string) { 1417 dir, base := filepath.Split(path) 1418 if !seenDirs[dir] { 1419 argv = append(argv, "-L"+dir) 1420 if !rpath.set { 1421 argv = append(argv, "-Wl,-rpath="+dir) 1422 } 1423 seenDirs[dir] = true 1424 } 1425 base = strings.TrimSuffix(base, ".so") 1426 base = strings.TrimPrefix(base, "lib") 1427 if !seenLibs[base] { 1428 argv = append(argv, "-l"+base) 1429 seenLibs[base] = true 1430 } 1431 } 1432 for _, shlib := range ctxt.Shlibs { 1433 addshlib(shlib.Path) 1434 for _, dep := range shlib.Deps { 1435 if dep == "" { 1436 continue 1437 } 1438 libpath := findshlib(ctxt, dep) 1439 if libpath != "" { 1440 addshlib(libpath) 1441 } 1442 } 1443 } 1444 } 1445 1446 // clang, unlike GCC, passes -rdynamic to the linker 1447 // even when linking with -static, causing a linker 1448 // error when using GNU ld. So take out -rdynamic if 1449 // we added it. We do it in this order, rather than 1450 // only adding -rdynamic later, so that -*extldflags 1451 // can override -rdynamic without using -static. 1452 checkStatic := func(arg string) { 1453 if ctxt.IsELF && arg == "-static" { 1454 for i := range argv { 1455 if argv[i] == "-rdynamic" { 1456 argv[i] = "-static" 1457 } 1458 } 1459 } 1460 } 1461 1462 for _, p := range ldflag { 1463 argv = append(argv, p) 1464 checkStatic(p) 1465 } 1466 1467 // When building a program with the default -buildmode=exe the 1468 // gc compiler generates code requires DT_TEXTREL in a 1469 // position independent executable (PIE). On systems where the 1470 // toolchain creates PIEs by default, and where DT_TEXTREL 1471 // does not work, the resulting programs will not run. See 1472 // issue #17847. To avoid this problem pass -no-pie to the 1473 // toolchain if it is supported. 1474 if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared { 1475 // GCC uses -no-pie, clang uses -nopie. 1476 for _, nopie := range []string{"-no-pie", "-nopie"} { 1477 if linkerFlagSupported(argv[0], nopie) { 1478 argv = append(argv, nopie) 1479 break 1480 } 1481 } 1482 } 1483 1484 for _, p := range strings.Fields(*flagExtldflags) { 1485 argv = append(argv, p) 1486 checkStatic(p) 1487 } 1488 if ctxt.HeadType == objabi.Hwindows { 1489 // use gcc linker script to work around gcc bug 1490 // (see https://golang.org/issue/20183 for details). 1491 p := writeGDBLinkerScript() 1492 argv = append(argv, "-Wl,-T,"+p) 1493 // libmingw32 and libmingwex have some inter-dependencies, 1494 // so must use linker groups. 1495 argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group") 1496 argv = append(argv, peimporteddlls()...) 1497 } 1498 1499 if ctxt.Debugvlog != 0 { 1500 ctxt.Logf("host link:") 1501 for _, v := range argv { 1502 ctxt.Logf(" %q", v) 1503 } 1504 ctxt.Logf("\n") 1505 } 1506 1507 out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput() 1508 if err != nil { 1509 Exitf("running %s failed: %v\n%s", argv[0], err, out) 1510 } 1511 1512 // Filter out useless linker warnings caused by bugs outside Go. 1513 // See also cmd/go/internal/work/exec.go's gccld method. 1514 var save [][]byte 1515 var skipLines int 1516 for _, line := range bytes.SplitAfter(out, []byte("\n")) { 1517 // golang.org/issue/26073 - Apple Xcode bug 1518 if bytes.Contains(line, []byte("ld: warning: text-based stub file")) { 1519 continue 1520 } 1521 1522 if skipLines > 0 { 1523 skipLines-- 1524 continue 1525 } 1526 1527 // Remove TOC overflow warning on AIX. 1528 if bytes.Contains(line, []byte("ld: 0711-783")) { 1529 skipLines = 2 1530 continue 1531 } 1532 1533 save = append(save, line) 1534 } 1535 out = bytes.Join(save, nil) 1536 1537 if len(out) > 0 { 1538 // always print external output even if the command is successful, so that we don't 1539 // swallow linker warnings (see https://golang.org/issue/17935). 1540 ctxt.Logf("%s", out) 1541 } 1542 1543 if !*FlagS && !*FlagW && !debug_s && ctxt.HeadType == objabi.Hdarwin { 1544 dsym := filepath.Join(*flagTmpdir, "go.dwarf") 1545 if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil { 1546 Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out) 1547 } 1548 // Skip combining if `dsymutil` didn't generate a file. See #11994. 1549 if _, err := os.Stat(dsym); os.IsNotExist(err) { 1550 return 1551 } 1552 // For os.Rename to work reliably, must be in same directory as outfile. 1553 combinedOutput := *flagOutfile + "~" 1554 exef, err := os.Open(*flagOutfile) 1555 if err != nil { 1556 Exitf("%s: combining dwarf failed: %v", os.Args[0], err) 1557 } 1558 defer exef.Close() 1559 exem, err := macho.NewFile(exef) 1560 if err != nil { 1561 Exitf("%s: parsing Mach-O header failed: %v", os.Args[0], err) 1562 } 1563 // Only macOS supports unmapped segments such as our __DWARF segment. 1564 if machoPlatform == PLATFORM_MACOS { 1565 if err := machoCombineDwarf(ctxt, exef, exem, dsym, combinedOutput); err != nil { 1566 Exitf("%s: combining dwarf failed: %v", os.Args[0], err) 1567 } 1568 os.Remove(*flagOutfile) 1569 if err := os.Rename(combinedOutput, *flagOutfile); err != nil { 1570 Exitf("%s: %v", os.Args[0], err) 1571 } 1572 } 1573 } 1574 } 1575 1576 var createTrivialCOnce sync.Once 1577 1578 func linkerFlagSupported(linker, flag string) bool { 1579 createTrivialCOnce.Do(func() { 1580 src := filepath.Join(*flagTmpdir, "trivial.c") 1581 if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil { 1582 Errorf(nil, "WriteFile trivial.c failed: %v", err) 1583 } 1584 }) 1585 1586 flagsWithNextArgSkip := []string{ 1587 "-F", 1588 "-l", 1589 "-L", 1590 "-framework", 1591 "-Wl,-framework", 1592 "-Wl,-rpath", 1593 "-Wl,-undefined", 1594 } 1595 flagsWithNextArgKeep := []string{ 1596 "-arch", 1597 "-isysroot", 1598 "--sysroot", 1599 "-target", 1600 } 1601 prefixesToKeep := []string{ 1602 "-f", 1603 "-m", 1604 "-p", 1605 "-Wl,", 1606 "-arch", 1607 "-isysroot", 1608 "--sysroot", 1609 "-target", 1610 } 1611 1612 var flags []string 1613 keep := false 1614 skip := false 1615 extldflags := strings.Fields(*flagExtldflags) 1616 for _, f := range append(extldflags, ldflag...) { 1617 if keep { 1618 flags = append(flags, f) 1619 keep = false 1620 } else if skip { 1621 skip = false 1622 } else if f == "" || f[0] != '-' { 1623 } else if contains(flagsWithNextArgSkip, f) { 1624 skip = true 1625 } else if contains(flagsWithNextArgKeep, f) { 1626 flags = append(flags, f) 1627 keep = true 1628 } else { 1629 for _, p := range prefixesToKeep { 1630 if strings.HasPrefix(f, p) { 1631 flags = append(flags, f) 1632 break 1633 } 1634 } 1635 } 1636 } 1637 1638 flags = append(flags, flag, "trivial.c") 1639 1640 cmd := exec.Command(linker, flags...) 1641 cmd.Dir = *flagTmpdir 1642 cmd.Env = append([]string{"LC_ALL=C"}, os.Environ()...) 1643 out, err := cmd.CombinedOutput() 1644 // GCC says "unrecognized command line option ‘-no-pie’" 1645 // clang says "unknown argument: '-no-pie'" 1646 return err == nil && !bytes.Contains(out, []byte("unrecognized")) && !bytes.Contains(out, []byte("unknown")) 1647 } 1648 1649 // hostlinkArchArgs returns arguments to pass to the external linker 1650 // based on the architecture. 1651 func hostlinkArchArgs(arch *sys.Arch) []string { 1652 switch arch.Family { 1653 case sys.I386: 1654 return []string{"-m32"} 1655 case sys.AMD64, sys.S390X: 1656 return []string{"-m64"} 1657 case sys.ARM: 1658 return []string{"-marm"} 1659 case sys.ARM64: 1660 // nothing needed 1661 case sys.MIPS64: 1662 return []string{"-mabi=64"} 1663 case sys.MIPS: 1664 return []string{"-mabi=32"} 1665 case sys.PPC64: 1666 if objabi.GOOS == "aix" { 1667 return []string{"-maix64"} 1668 } else { 1669 return []string{"-m64"} 1670 } 1671 1672 } 1673 return nil 1674 } 1675 1676 // ldobj loads an input object. If it is a host object (an object 1677 // compiled by a non-Go compiler) it returns the Hostobj pointer. If 1678 // it is a Go object, it returns nil. 1679 func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, file string) *Hostobj { 1680 pkg := objabi.PathToPrefix(lib.Pkg) 1681 1682 eof := f.Offset() + length 1683 start := f.Offset() 1684 c1 := bgetc(f) 1685 c2 := bgetc(f) 1686 c3 := bgetc(f) 1687 c4 := bgetc(f) 1688 f.MustSeek(start, 0) 1689 1690 unit := &sym.CompilationUnit{Lib: lib} 1691 lib.Units = append(lib.Units, unit) 1692 1693 magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4) 1694 if magic == 0x7f454c46 { // \x7F E L F 1695 if *flagNewobj { 1696 ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { 1697 textp, flags, err := loadelf.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn, ehdr.flags) 1698 if err != nil { 1699 Errorf(nil, "%v", err) 1700 return 1701 } 1702 ehdr.flags = flags 1703 ctxt.Textp = append(ctxt.Textp, textp...) 1704 } 1705 return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file) 1706 } else { 1707 ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { 1708 textp, flags, err := loadelf.LoadOld(ctxt.Arch, ctxt.Syms, f, pkg, length, pn, ehdr.flags) 1709 if err != nil { 1710 Errorf(nil, "%v", err) 1711 return 1712 } 1713 ehdr.flags = flags 1714 ctxt.Textp = append(ctxt.Textp, textp...) 1715 } 1716 return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file) 1717 } 1718 } 1719 1720 if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe { 1721 if *flagNewobj { 1722 ldmacho := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { 1723 textp, err := loadmacho.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn) 1724 if err != nil { 1725 Errorf(nil, "%v", err) 1726 return 1727 } 1728 ctxt.Textp = append(ctxt.Textp, textp...) 1729 } 1730 return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file) 1731 } else { 1732 ldmacho := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { 1733 textp, err := loadmacho.LoadOld(ctxt.Arch, ctxt.Syms, f, pkg, length, pn) 1734 if err != nil { 1735 Errorf(nil, "%v", err) 1736 return 1737 } 1738 ctxt.Textp = append(ctxt.Textp, textp...) 1739 } 1740 return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file) 1741 } 1742 } 1743 1744 if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 { 1745 if *flagNewobj { 1746 ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { 1747 textp, rsrc, err := loadpe.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn) 1748 if err != nil { 1749 Errorf(nil, "%v", err) 1750 return 1751 } 1752 if rsrc != nil { 1753 setpersrc(ctxt, rsrc) 1754 } 1755 ctxt.Textp = append(ctxt.Textp, textp...) 1756 } 1757 return ldhostobj(ldpe, ctxt.HeadType, f, pkg, length, pn, file) 1758 } else { 1759 ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { 1760 textp, rsrc, err := loadpe.LoadOld(ctxt.Arch, ctxt.Syms, f, pkg, length, pn) 1761 if err != nil { 1762 Errorf(nil, "%v", err) 1763 return 1764 } 1765 if rsrc != nil { 1766 setpersrc(ctxt, rsrc) 1767 } 1768 ctxt.Textp = append(ctxt.Textp, textp...) 1769 } 1770 return ldhostobj(ldpe, ctxt.HeadType, f, pkg, length, pn, file) 1771 } 1772 } 1773 1774 if c1 == 0x01 && (c2 == 0xD7 || c2 == 0xF7) { 1775 if *flagNewobj { 1776 ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { 1777 textp, err := loadxcoff.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn) 1778 if err != nil { 1779 Errorf(nil, "%v", err) 1780 return 1781 } 1782 ctxt.Textp = append(ctxt.Textp, textp...) 1783 } 1784 return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file) 1785 } else { 1786 ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { 1787 textp, err := loadxcoff.LoadOld(ctxt.Arch, ctxt.Syms, f, pkg, length, pn) 1788 if err != nil { 1789 Errorf(nil, "%v", err) 1790 return 1791 } 1792 ctxt.Textp = append(ctxt.Textp, textp...) 1793 } 1794 return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file) 1795 } 1796 } 1797 1798 /* check the header */ 1799 line, err := f.ReadString('\n') 1800 if err != nil { 1801 Errorf(nil, "truncated object file: %s: %v", pn, err) 1802 return nil 1803 } 1804 1805 if !strings.HasPrefix(line, "go object ") { 1806 if strings.HasSuffix(pn, ".go") { 1807 Exitf("%s: uncompiled .go source file", pn) 1808 return nil 1809 } 1810 1811 if line == ctxt.Arch.Name { 1812 // old header format: just $GOOS 1813 Errorf(nil, "%s: stale object file", pn) 1814 return nil 1815 } 1816 1817 Errorf(nil, "%s: not an object file", pn) 1818 return nil 1819 } 1820 1821 // First, check that the basic GOOS, GOARCH, and Version match. 1822 t := fmt.Sprintf("%s %s %s ", objabi.GOOS, objabi.GOARCH, objabi.Version) 1823 1824 line = strings.TrimRight(line, "\n") 1825 if !strings.HasPrefix(line[10:]+" ", t) && !*flagF { 1826 Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], t) 1827 return nil 1828 } 1829 1830 // Second, check that longer lines match each other exactly, 1831 // so that the Go compiler and write additional information 1832 // that must be the same from run to run. 1833 if len(line) >= len(t)+10 { 1834 if theline == "" { 1835 theline = line[10:] 1836 } else if theline != line[10:] { 1837 Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], theline) 1838 return nil 1839 } 1840 } 1841 1842 // Skip over exports and other info -- ends with \n!\n. 1843 // 1844 // Note: It's possible for "\n!\n" to appear within the binary 1845 // package export data format. To avoid truncating the package 1846 // definition prematurely (issue 21703), we keep track of 1847 // how many "$$" delimiters we've seen. 1848 1849 import0 := f.Offset() 1850 1851 c1 = '\n' // the last line ended in \n 1852 c2 = bgetc(f) 1853 c3 = bgetc(f) 1854 markers := 0 1855 for { 1856 if c1 == '\n' { 1857 if markers%2 == 0 && c2 == '!' && c3 == '\n' { 1858 break 1859 } 1860 if c2 == '$' && c3 == '$' { 1861 markers++ 1862 } 1863 } 1864 1865 c1 = c2 1866 c2 = c3 1867 c3 = bgetc(f) 1868 if c3 == -1 { 1869 Errorf(nil, "truncated object file: %s", pn) 1870 return nil 1871 } 1872 } 1873 1874 import1 := f.Offset() 1875 1876 f.MustSeek(import0, 0) 1877 ldpkg(ctxt, f, lib, import1-import0-2, pn) // -2 for !\n 1878 f.MustSeek(import1, 0) 1879 1880 flags := 0 1881 switch *FlagStrictDups { 1882 case 0: 1883 break 1884 case 1: 1885 flags = objfile.StrictDupsWarnFlag 1886 case 2: 1887 flags = objfile.StrictDupsErrFlag 1888 default: 1889 log.Fatalf("invalid -strictdups flag value %d", *FlagStrictDups) 1890 } 1891 var c int 1892 if *flagNewobj { 1893 ctxt.loader.Preload(ctxt.Arch, ctxt.Syms, f, lib, unit, eof-f.Offset(), pn, flags) 1894 } else { 1895 c = objfile.Load(ctxt.Arch, ctxt.Syms, f, lib, unit, eof-f.Offset(), pn, flags) 1896 } 1897 strictDupMsgCount += c 1898 addImports(ctxt, lib, pn) 1899 return nil 1900 } 1901 1902 func readelfsymboldata(ctxt *Link, f *elf.File, sym *elf.Symbol) []byte { 1903 data := make([]byte, sym.Size) 1904 sect := f.Sections[sym.Section] 1905 if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE { 1906 Errorf(nil, "reading %s from non-data section", sym.Name) 1907 } 1908 n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr)) 1909 if uint64(n) != sym.Size { 1910 Errorf(nil, "reading contents of %s: %v", sym.Name, err) 1911 } 1912 return data 1913 } 1914 1915 func readwithpad(r io.Reader, sz int32) ([]byte, error) { 1916 data := make([]byte, Rnd(int64(sz), 4)) 1917 _, err := io.ReadFull(r, data) 1918 if err != nil { 1919 return nil, err 1920 } 1921 data = data[:sz] 1922 return data, nil 1923 } 1924 1925 func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) { 1926 for _, sect := range f.Sections { 1927 if sect.Type != elf.SHT_NOTE { 1928 continue 1929 } 1930 r := sect.Open() 1931 for { 1932 var namesize, descsize, noteType int32 1933 err := binary.Read(r, f.ByteOrder, &namesize) 1934 if err != nil { 1935 if err == io.EOF { 1936 break 1937 } 1938 return nil, fmt.Errorf("read namesize failed: %v", err) 1939 } 1940 err = binary.Read(r, f.ByteOrder, &descsize) 1941 if err != nil { 1942 return nil, fmt.Errorf("read descsize failed: %v", err) 1943 } 1944 err = binary.Read(r, f.ByteOrder, ¬eType) 1945 if err != nil { 1946 return nil, fmt.Errorf("read type failed: %v", err) 1947 } 1948 noteName, err := readwithpad(r, namesize) 1949 if err != nil { 1950 return nil, fmt.Errorf("read name failed: %v", err) 1951 } 1952 desc, err := readwithpad(r, descsize) 1953 if err != nil { 1954 return nil, fmt.Errorf("read desc failed: %v", err) 1955 } 1956 if string(name) == string(noteName) && typ == noteType { 1957 return desc, nil 1958 } 1959 } 1960 } 1961 return nil, nil 1962 } 1963 1964 func findshlib(ctxt *Link, shlib string) string { 1965 if filepath.IsAbs(shlib) { 1966 return shlib 1967 } 1968 for _, libdir := range ctxt.Libdir { 1969 libpath := filepath.Join(libdir, shlib) 1970 if _, err := os.Stat(libpath); err == nil { 1971 return libpath 1972 } 1973 } 1974 Errorf(nil, "cannot find shared library: %s", shlib) 1975 return "" 1976 } 1977 1978 func ldshlibsyms(ctxt *Link, shlib string) { 1979 var libpath string 1980 if filepath.IsAbs(shlib) { 1981 libpath = shlib 1982 shlib = filepath.Base(shlib) 1983 } else { 1984 libpath = findshlib(ctxt, shlib) 1985 if libpath == "" { 1986 return 1987 } 1988 } 1989 for _, processedlib := range ctxt.Shlibs { 1990 if processedlib.Path == libpath { 1991 return 1992 } 1993 } 1994 if ctxt.Debugvlog > 1 { 1995 ctxt.Logf("ldshlibsyms: found library with name %s at %s\n", shlib, libpath) 1996 } 1997 1998 f, err := elf.Open(libpath) 1999 if err != nil { 2000 Errorf(nil, "cannot open shared library: %s", libpath) 2001 return 2002 } 2003 defer f.Close() 2004 2005 hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG) 2006 if err != nil { 2007 Errorf(nil, "cannot read ABI hash from shared library %s: %v", libpath, err) 2008 return 2009 } 2010 2011 depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG) 2012 if err != nil { 2013 Errorf(nil, "cannot read dep list from shared library %s: %v", libpath, err) 2014 return 2015 } 2016 var deps []string 2017 for _, dep := range strings.Split(string(depsbytes), "\n") { 2018 if dep == "" { 2019 continue 2020 } 2021 if !filepath.IsAbs(dep) { 2022 // If the dep can be interpreted as a path relative to the shlib 2023 // in which it was found, do that. Otherwise, we will leave it 2024 // to be resolved by libdir lookup. 2025 abs := filepath.Join(filepath.Dir(libpath), dep) 2026 if _, err := os.Stat(abs); err == nil { 2027 dep = abs 2028 } 2029 } 2030 deps = append(deps, dep) 2031 } 2032 2033 syms, err := f.DynamicSymbols() 2034 if err != nil { 2035 Errorf(nil, "cannot read symbols from shared library: %s", libpath) 2036 return 2037 } 2038 gcdataLocations := make(map[uint64]*sym.Symbol) 2039 for _, elfsym := range syms { 2040 if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION { 2041 continue 2042 } 2043 2044 // Symbols whose names start with "type." are compiler 2045 // generated, so make functions with that prefix internal. 2046 ver := 0 2047 if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type.") { 2048 ver = sym.SymVerABIInternal 2049 } 2050 2051 var lsym *sym.Symbol 2052 if *flagNewobj { 2053 i := ctxt.loader.AddExtSym(elfsym.Name, ver) 2054 if i == 0 { 2055 continue 2056 } 2057 lsym = ctxt.Syms.Newsym(elfsym.Name, ver) 2058 ctxt.loader.Syms[i] = lsym 2059 } else { 2060 lsym = ctxt.Syms.Lookup(elfsym.Name, ver) 2061 } 2062 // Because loadlib above loads all .a files before loading any shared 2063 // libraries, any non-dynimport symbols we find that duplicate symbols 2064 // already loaded should be ignored (the symbols from the .a files 2065 // "win"). 2066 if lsym.Type != 0 && lsym.Type != sym.SDYNIMPORT { 2067 continue 2068 } 2069 lsym.Type = sym.SDYNIMPORT 2070 lsym.SetElfType(elf.ST_TYPE(elfsym.Info)) 2071 lsym.Size = int64(elfsym.Size) 2072 if elfsym.Section != elf.SHN_UNDEF { 2073 // Set .File for the library that actually defines the symbol. 2074 lsym.File = libpath 2075 // The decodetype_* functions in decodetype.go need access to 2076 // the type data. 2077 if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") { 2078 lsym.P = readelfsymboldata(ctxt, f, &elfsym) 2079 gcdataLocations[elfsym.Value+2*uint64(ctxt.Arch.PtrSize)+8+1*uint64(ctxt.Arch.PtrSize)] = lsym 2080 } 2081 } 2082 // For function symbols, we don't know what ABI is 2083 // available, so alias it under both ABIs. 2084 // 2085 // TODO(austin): This is almost certainly wrong once 2086 // the ABIs are actually different. We might have to 2087 // mangle Go function names in the .so to include the 2088 // ABI. 2089 if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && ver == 0 { 2090 var alias *sym.Symbol 2091 if *flagNewobj { 2092 i := ctxt.loader.AddExtSym(elfsym.Name, sym.SymVerABIInternal) 2093 if i == 0 { 2094 continue 2095 } 2096 alias = ctxt.Syms.Newsym(elfsym.Name, sym.SymVerABIInternal) 2097 ctxt.loader.Syms[i] = alias 2098 } else { 2099 alias = ctxt.Syms.Lookup(elfsym.Name, sym.SymVerABIInternal) 2100 } 2101 if alias.Type != 0 { 2102 continue 2103 } 2104 alias.Type = sym.SABIALIAS 2105 alias.R = []sym.Reloc{{Sym: lsym}} 2106 } 2107 } 2108 gcdataAddresses := make(map[*sym.Symbol]uint64) 2109 if ctxt.Arch.Family == sys.ARM64 { 2110 for _, sect := range f.Sections { 2111 if sect.Type == elf.SHT_RELA { 2112 var rela elf.Rela64 2113 rdr := sect.Open() 2114 for { 2115 err := binary.Read(rdr, f.ByteOrder, &rela) 2116 if err == io.EOF { 2117 break 2118 } else if err != nil { 2119 Errorf(nil, "reading relocation failed %v", err) 2120 return 2121 } 2122 t := elf.R_AARCH64(rela.Info & 0xffff) 2123 if t != elf.R_AARCH64_RELATIVE { 2124 continue 2125 } 2126 if lsym, ok := gcdataLocations[rela.Off]; ok { 2127 gcdataAddresses[lsym] = uint64(rela.Addend) 2128 } 2129 } 2130 } 2131 } 2132 } 2133 2134 ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdataAddresses: gcdataAddresses}) 2135 } 2136 2137 func addsection(arch *sys.Arch, seg *sym.Segment, name string, rwx int) *sym.Section { 2138 sect := new(sym.Section) 2139 sect.Rwx = uint8(rwx) 2140 sect.Name = name 2141 sect.Seg = seg 2142 sect.Align = int32(arch.PtrSize) // everything is at least pointer-aligned 2143 seg.Sections = append(seg.Sections, sect) 2144 return sect 2145 } 2146 2147 type chain struct { 2148 sym *sym.Symbol 2149 up *chain 2150 limit int // limit on entry to sym 2151 } 2152 2153 var morestack *sym.Symbol 2154 2155 // TODO: Record enough information in new object files to 2156 // allow stack checks here. 2157 2158 func haslinkregister(ctxt *Link) bool { 2159 return ctxt.FixedFrameSize() != 0 2160 } 2161 2162 func callsize(ctxt *Link) int { 2163 if haslinkregister(ctxt) { 2164 return 0 2165 } 2166 return ctxt.Arch.RegSize 2167 } 2168 2169 func (ctxt *Link) dostkcheck() { 2170 var ch chain 2171 2172 morestack = ctxt.Syms.Lookup("runtime.morestack", 0) 2173 2174 // Every splitting function ensures that there are at least StackLimit 2175 // bytes available below SP when the splitting prologue finishes. 2176 // If the splitting function calls F, then F begins execution with 2177 // at least StackLimit - callsize() bytes available. 2178 // Check that every function behaves correctly with this amount 2179 // of stack, following direct calls in order to piece together chains 2180 // of non-splitting functions. 2181 ch.up = nil 2182 2183 ch.limit = objabi.StackLimit - callsize(ctxt) 2184 if objabi.GOARCH == "arm64" { 2185 // need extra 8 bytes below SP to save FP 2186 ch.limit -= 8 2187 } 2188 2189 // Check every function, but do the nosplit functions in a first pass, 2190 // to make the printed failure chains as short as possible. 2191 for _, s := range ctxt.Textp { 2192 // runtime.racesymbolizethunk is called from gcc-compiled C 2193 // code running on the operating system thread stack. 2194 // It uses more than the usual amount of stack but that's okay. 2195 if s.Name == "runtime.racesymbolizethunk" { 2196 continue 2197 } 2198 2199 if s.Attr.NoSplit() { 2200 ch.sym = s 2201 stkcheck(ctxt, &ch, 0) 2202 } 2203 } 2204 2205 for _, s := range ctxt.Textp { 2206 if !s.Attr.NoSplit() { 2207 ch.sym = s 2208 stkcheck(ctxt, &ch, 0) 2209 } 2210 } 2211 } 2212 2213 func stkcheck(ctxt *Link, up *chain, depth int) int { 2214 limit := up.limit 2215 s := up.sym 2216 2217 // Don't duplicate work: only need to consider each 2218 // function at top of safe zone once. 2219 top := limit == objabi.StackLimit-callsize(ctxt) 2220 if top { 2221 if s.Attr.StackCheck() { 2222 return 0 2223 } 2224 s.Attr |= sym.AttrStackCheck 2225 } 2226 2227 if depth > 500 { 2228 Errorf(s, "nosplit stack check too deep") 2229 stkbroke(ctxt, up, 0) 2230 return -1 2231 } 2232 2233 if s.Attr.External() || s.FuncInfo == nil { 2234 // external function. 2235 // should never be called directly. 2236 // onlyctxt.Diagnose the direct caller. 2237 // TODO(mwhudson): actually think about this. 2238 // TODO(khr): disabled for now. Calls to external functions can only happen on the g0 stack. 2239 // See the trampolines in src/runtime/sys_darwin_$ARCH.go. 2240 if depth == 1 && s.Type != sym.SXREF && !ctxt.DynlinkingGo() && 2241 ctxt.BuildMode != BuildModeCArchive && ctxt.BuildMode != BuildModePIE && ctxt.BuildMode != BuildModeCShared && ctxt.BuildMode != BuildModePlugin { 2242 //Errorf(s, "call to external function") 2243 } 2244 return -1 2245 } 2246 2247 if limit < 0 { 2248 stkbroke(ctxt, up, limit) 2249 return -1 2250 } 2251 2252 // morestack looks like it calls functions, 2253 // but it switches the stack pointer first. 2254 if s == morestack { 2255 return 0 2256 } 2257 2258 var ch chain 2259 ch.up = up 2260 2261 if !s.Attr.NoSplit() { 2262 // Ensure we have enough stack to call morestack. 2263 ch.limit = limit - callsize(ctxt) 2264 ch.sym = morestack 2265 if stkcheck(ctxt, &ch, depth+1) < 0 { 2266 return -1 2267 } 2268 if !top { 2269 return 0 2270 } 2271 // Raise limit to allow frame. 2272 locals := int32(0) 2273 if s.FuncInfo != nil { 2274 locals = s.FuncInfo.Locals 2275 } 2276 limit = objabi.StackLimit + int(locals) + int(ctxt.FixedFrameSize()) 2277 } 2278 2279 // Walk through sp adjustments in function, consuming relocs. 2280 ri := 0 2281 2282 endr := len(s.R) 2283 var ch1 chain 2284 pcsp := obj.NewPCIter(uint32(ctxt.Arch.MinLC)) 2285 var r *sym.Reloc 2286 for pcsp.Init(s.FuncInfo.Pcsp.P); !pcsp.Done; pcsp.Next() { 2287 // pcsp.value is in effect for [pcsp.pc, pcsp.nextpc). 2288 2289 // Check stack size in effect for this span. 2290 if int32(limit)-pcsp.Value < 0 { 2291 stkbroke(ctxt, up, int(int32(limit)-pcsp.Value)) 2292 return -1 2293 } 2294 2295 // Process calls in this span. 2296 for ; ri < endr && uint32(s.R[ri].Off) < pcsp.NextPC; ri++ { 2297 r = &s.R[ri] 2298 switch { 2299 case r.Type.IsDirectCall(): 2300 ch.limit = int(int32(limit) - pcsp.Value - int32(callsize(ctxt))) 2301 ch.sym = r.Sym 2302 if stkcheck(ctxt, &ch, depth+1) < 0 { 2303 return -1 2304 } 2305 2306 // Indirect call. Assume it is a call to a splitting function, 2307 // so we have to make sure it can call morestack. 2308 // Arrange the data structures to report both calls, so that 2309 // if there is an error, stkprint shows all the steps involved. 2310 case r.Type == objabi.R_CALLIND: 2311 ch.limit = int(int32(limit) - pcsp.Value - int32(callsize(ctxt))) 2312 ch.sym = nil 2313 ch1.limit = ch.limit - callsize(ctxt) // for morestack in called prologue 2314 ch1.up = &ch 2315 ch1.sym = morestack 2316 if stkcheck(ctxt, &ch1, depth+2) < 0 { 2317 return -1 2318 } 2319 } 2320 } 2321 } 2322 2323 return 0 2324 } 2325 2326 func stkbroke(ctxt *Link, ch *chain, limit int) { 2327 Errorf(ch.sym, "nosplit stack overflow") 2328 stkprint(ctxt, ch, limit) 2329 } 2330 2331 func stkprint(ctxt *Link, ch *chain, limit int) { 2332 var name string 2333 2334 if ch.sym != nil { 2335 name = ch.sym.Name 2336 if ch.sym.Attr.NoSplit() { 2337 name += " (nosplit)" 2338 } 2339 } else { 2340 name = "function pointer" 2341 } 2342 2343 if ch.up == nil { 2344 // top of chain. ch->sym != nil. 2345 if ch.sym.Attr.NoSplit() { 2346 fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name) 2347 } else { 2348 fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name) 2349 } 2350 } else { 2351 stkprint(ctxt, ch.up, ch.limit+callsize(ctxt)) 2352 if !haslinkregister(ctxt) { 2353 fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name) 2354 } 2355 } 2356 2357 if ch.limit != limit { 2358 fmt.Printf("\t%d\tafter %s uses %d\n", limit, name, ch.limit-limit) 2359 } 2360 } 2361 2362 func usage() { 2363 fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n") 2364 objabi.Flagprint(os.Stderr) 2365 Exit(2) 2366 } 2367 2368 type SymbolType int8 2369 2370 const ( 2371 // see also https://9p.io/magic/man2html/1/nm 2372 TextSym SymbolType = 'T' 2373 DataSym SymbolType = 'D' 2374 BSSSym SymbolType = 'B' 2375 UndefinedSym SymbolType = 'U' 2376 TLSSym SymbolType = 't' 2377 FrameSym SymbolType = 'm' 2378 ParamSym SymbolType = 'p' 2379 AutoSym SymbolType = 'a' 2380 2381 // Deleted auto (not a real sym, just placeholder for type) 2382 DeletedAutoSym = 'x' 2383 ) 2384 2385 func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int64, *sym.Symbol)) { 2386 // These symbols won't show up in the first loop below because we 2387 // skip sym.STEXT symbols. Normal sym.STEXT symbols are emitted by walking textp. 2388 s := ctxt.Syms.Lookup("runtime.text", 0) 2389 if s.Type == sym.STEXT { 2390 // We've already included this symbol in ctxt.Textp 2391 // if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin or 2392 // on AIX with external linker. 2393 // See data.go:/textaddress 2394 if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) && !(ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) { 2395 put(ctxt, s, s.Name, TextSym, s.Value, nil) 2396 } 2397 } 2398 2399 n := 0 2400 2401 // Generate base addresses for all text sections if there are multiple 2402 for _, sect := range Segtext.Sections { 2403 if n == 0 { 2404 n++ 2405 continue 2406 } 2407 if sect.Name != ".text" || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) { 2408 // On AIX, runtime.text.X are symbols already in the symtab. 2409 break 2410 } 2411 s = ctxt.Syms.ROLookup(fmt.Sprintf("runtime.text.%d", n), 0) 2412 if s == nil { 2413 break 2414 } 2415 if s.Type == sym.STEXT { 2416 put(ctxt, s, s.Name, TextSym, s.Value, nil) 2417 } 2418 n++ 2419 } 2420 2421 s = ctxt.Syms.Lookup("runtime.etext", 0) 2422 if s.Type == sym.STEXT { 2423 // We've already included this symbol in ctxt.Textp 2424 // if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin or 2425 // on AIX with external linker. 2426 // See data.go:/textaddress 2427 if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) && !(ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) { 2428 put(ctxt, s, s.Name, TextSym, s.Value, nil) 2429 } 2430 } 2431 2432 shouldBeInSymbolTable := func(s *sym.Symbol) bool { 2433 if s.Attr.NotInSymbolTable() { 2434 return false 2435 } 2436 if ctxt.HeadType == objabi.Haix && s.Name == ".go.buildinfo" { 2437 // On AIX, .go.buildinfo must be in the symbol table as 2438 // it has relocations. 2439 return true 2440 } 2441 if (s.Name == "" || s.Name[0] == '.') && !s.IsFileLocal() && s.Name != ".rathole" && s.Name != ".TOC." { 2442 return false 2443 } 2444 return true 2445 } 2446 2447 for _, s := range ctxt.Syms.Allsym { 2448 if !shouldBeInSymbolTable(s) { 2449 continue 2450 } 2451 switch s.Type { 2452 case sym.SCONST, 2453 sym.SRODATA, 2454 sym.SSYMTAB, 2455 sym.SPCLNTAB, 2456 sym.SINITARR, 2457 sym.SDATA, 2458 sym.SNOPTRDATA, 2459 sym.SELFROSECT, 2460 sym.SMACHOGOT, 2461 sym.STYPE, 2462 sym.SSTRING, 2463 sym.SGOSTRING, 2464 sym.SGOFUNC, 2465 sym.SGCBITS, 2466 sym.STYPERELRO, 2467 sym.SSTRINGRELRO, 2468 sym.SGOSTRINGRELRO, 2469 sym.SGOFUNCRELRO, 2470 sym.SGCBITSRELRO, 2471 sym.SRODATARELRO, 2472 sym.STYPELINK, 2473 sym.SITABLINK, 2474 sym.SWINDOWS: 2475 if !s.Attr.Reachable() { 2476 continue 2477 } 2478 put(ctxt, s, s.Name, DataSym, Symaddr(s), s.Gotype) 2479 2480 case sym.SBSS, sym.SNOPTRBSS, sym.SLIBFUZZER_EXTRA_COUNTER: 2481 if !s.Attr.Reachable() { 2482 continue 2483 } 2484 if len(s.P) > 0 { 2485 Errorf(s, "should not be bss (size=%d type=%v special=%v)", len(s.P), s.Type, s.Attr.Special()) 2486 } 2487 put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype) 2488 2489 case sym.SUNDEFEXT: 2490 if ctxt.HeadType == objabi.Hwindows || ctxt.HeadType == objabi.Haix || ctxt.IsELF { 2491 put(ctxt, s, s.Name, UndefinedSym, s.Value, nil) 2492 } 2493 2494 case sym.SHOSTOBJ: 2495 if !s.Attr.Reachable() { 2496 continue 2497 } 2498 if ctxt.HeadType == objabi.Hwindows || ctxt.IsELF { 2499 put(ctxt, s, s.Name, UndefinedSym, s.Value, nil) 2500 } 2501 2502 case sym.SDYNIMPORT: 2503 if !s.Attr.Reachable() { 2504 continue 2505 } 2506 put(ctxt, s, s.Extname(), UndefinedSym, 0, nil) 2507 2508 case sym.STLSBSS: 2509 if ctxt.LinkMode == LinkExternal { 2510 put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype) 2511 } 2512 } 2513 } 2514 2515 for _, s := range ctxt.Textp { 2516 put(ctxt, s, s.Name, TextSym, s.Value, s.Gotype) 2517 2518 locals := int32(0) 2519 if s.FuncInfo != nil { 2520 locals = s.FuncInfo.Locals 2521 } 2522 // NOTE(ality): acid can't produce a stack trace without .frame symbols 2523 put(ctxt, nil, ".frame", FrameSym, int64(locals)+int64(ctxt.Arch.PtrSize), nil) 2524 2525 if s.FuncInfo == nil { 2526 continue 2527 } 2528 } 2529 2530 if ctxt.Debugvlog != 0 || *flagN { 2531 ctxt.Logf("symsize = %d\n", uint32(Symsize)) 2532 } 2533 } 2534 2535 func Symaddr(s *sym.Symbol) int64 { 2536 if !s.Attr.Reachable() { 2537 Errorf(s, "unreachable symbol in symaddr") 2538 } 2539 return s.Value 2540 } 2541 2542 func (ctxt *Link) xdefine(p string, t sym.SymKind, v int64) { 2543 s := ctxt.Syms.Lookup(p, 0) 2544 s.Type = t 2545 s.Value = v 2546 s.Attr |= sym.AttrReachable 2547 s.Attr |= sym.AttrSpecial 2548 s.Attr |= sym.AttrLocal 2549 } 2550 2551 func datoff(s *sym.Symbol, addr int64) int64 { 2552 if uint64(addr) >= Segdata.Vaddr { 2553 return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff) 2554 } 2555 if uint64(addr) >= Segtext.Vaddr { 2556 return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff) 2557 } 2558 Errorf(s, "invalid datoff %#x", addr) 2559 return 0 2560 } 2561 2562 func Entryvalue(ctxt *Link) int64 { 2563 a := *flagEntrySymbol 2564 if a[0] >= '0' && a[0] <= '9' { 2565 return atolwhex(a) 2566 } 2567 s := ctxt.Syms.Lookup(a, 0) 2568 if s.Type == 0 { 2569 return *FlagTextAddr 2570 } 2571 if ctxt.HeadType != objabi.Haix && s.Type != sym.STEXT { 2572 Errorf(s, "entry not text") 2573 } 2574 return s.Value 2575 } 2576 2577 func undefsym(ctxt *Link, s *sym.Symbol) { 2578 var r *sym.Reloc 2579 2580 for i := 0; i < len(s.R); i++ { 2581 r = &s.R[i] 2582 if r.Sym == nil { // happens for some external ARM relocs 2583 continue 2584 } 2585 // TODO(mwhudson): the test of VisibilityHidden here probably doesn't make 2586 // sense and should be removed when someone has thought about it properly. 2587 if (r.Sym.Type == sym.Sxxx || r.Sym.Type == sym.SXREF) && !r.Sym.Attr.VisibilityHidden() { 2588 Errorf(s, "undefined: %q", r.Sym.Name) 2589 } 2590 if !r.Sym.Attr.Reachable() && r.Type != objabi.R_WEAKADDROFF { 2591 Errorf(s, "relocation target %q", r.Sym.Name) 2592 } 2593 } 2594 } 2595 2596 func (ctxt *Link) undef() { 2597 // undefsym performs checks (almost) identical to checks 2598 // that report undefined relocations in relocsym. 2599 // Both undefsym and relocsym can report same symbol as undefined, 2600 // which results in error message duplication (see #10978). 2601 // 2602 // The undef is run after Arch.Asmb and could detect some 2603 // programming errors there, but if object being linked is already 2604 // failed with errors, it is better to avoid duplicated errors. 2605 if nerrors > 0 { 2606 return 2607 } 2608 2609 for _, s := range ctxt.Textp { 2610 undefsym(ctxt, s) 2611 } 2612 for _, s := range datap { 2613 undefsym(ctxt, s) 2614 } 2615 if nerrors > 0 { 2616 errorexit() 2617 } 2618 } 2619 2620 func (ctxt *Link) callgraph() { 2621 if !*FlagC { 2622 return 2623 } 2624 2625 var i int 2626 var r *sym.Reloc 2627 for _, s := range ctxt.Textp { 2628 for i = 0; i < len(s.R); i++ { 2629 r = &s.R[i] 2630 if r.Sym == nil { 2631 continue 2632 } 2633 if r.Type.IsDirectCall() && r.Sym.Type == sym.STEXT { 2634 ctxt.Logf("%s calls %s\n", s.Name, r.Sym.Name) 2635 } 2636 } 2637 } 2638 } 2639 2640 func Rnd(v int64, r int64) int64 { 2641 if r <= 0 { 2642 return v 2643 } 2644 v += r - 1 2645 c := v % r 2646 if c < 0 { 2647 c += r 2648 } 2649 v -= c 2650 return v 2651 } 2652 2653 func bgetc(r *bio.Reader) int { 2654 c, err := r.ReadByte() 2655 if err != nil { 2656 if err != io.EOF { 2657 log.Fatalf("reading input: %v", err) 2658 } 2659 return -1 2660 } 2661 return int(c) 2662 } 2663 2664 type markKind uint8 // for postorder traversal 2665 const ( 2666 _ markKind = iota 2667 visiting 2668 visited 2669 ) 2670 2671 func postorder(libs []*sym.Library) []*sym.Library { 2672 order := make([]*sym.Library, 0, len(libs)) // hold the result 2673 mark := make(map[*sym.Library]markKind, len(libs)) 2674 for _, lib := range libs { 2675 dfs(lib, mark, &order) 2676 } 2677 return order 2678 } 2679 2680 func dfs(lib *sym.Library, mark map[*sym.Library]markKind, order *[]*sym.Library) { 2681 if mark[lib] == visited { 2682 return 2683 } 2684 if mark[lib] == visiting { 2685 panic("found import cycle while visiting " + lib.Pkg) 2686 } 2687 mark[lib] = visiting 2688 for _, i := range lib.Imports { 2689 dfs(i, mark, order) 2690 } 2691 mark[lib] = visited 2692 *order = append(*order, lib) 2693 } 2694 2695 func (ctxt *Link) loadlibfull() { 2696 // Load full symbol contents, resolve indexed references. 2697 ctxt.loader.LoadFull(ctxt.Arch, ctxt.Syms) 2698 2699 // Pull the symbols out. 2700 ctxt.loader.ExtractSymbols(ctxt.Syms) 2701 2702 // Load cgo directives. 2703 for _, d := range ctxt.cgodata { 2704 setCgoAttr(ctxt, ctxt.Syms.Lookup, d.file, d.pkg, d.directives) 2705 } 2706 2707 setupdynexp(ctxt) 2708 2709 // Populate ctxt.Reachparent if appropriate. 2710 if ctxt.Reachparent != nil { 2711 for i := 0; i < len(ctxt.loader.Reachparent); i++ { 2712 p := ctxt.loader.Reachparent[i] 2713 if p == 0 { 2714 continue 2715 } 2716 if p == loader.Sym(i) { 2717 panic("self-cycle in reachparent") 2718 } 2719 sym := ctxt.loader.Syms[i] 2720 psym := ctxt.loader.Syms[p] 2721 ctxt.Reachparent[sym] = psym 2722 } 2723 } 2724 2725 // Drop the reference. 2726 ctxt.loader = nil 2727 ctxt.cgodata = nil 2728 2729 addToTextp(ctxt) 2730 } 2731 2732 func (ctxt *Link) dumpsyms() { 2733 for _, s := range ctxt.Syms.Allsym { 2734 fmt.Printf("%s %s %p %v %v\n", s, s.Type, s, s.Attr.Reachable(), s.Attr.OnList()) 2735 for i := range s.R { 2736 fmt.Println("\t", s.R[i].Type, s.R[i].Sym) 2737 } 2738 } 2739 }