1// Inferno utils/8l/asm.c 2// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/8l/asm.c 3// 4// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 5// Portions Copyright © 1995-1997 C H Forsyth ([email protected]) 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 ([email protected]) 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 31package ld 32 33import ( 34 "bytes" 35 "debug/elf" 36 "debug/macho" 37 "encoding/base64" 38 "encoding/binary" 39 "fmt" 40 "internal/buildcfg" 41 "io" 42 "log" 43 "os" 44 "os/exec" 45 "path/filepath" 46 "runtime" 47 "sort" 48 "strings" 49 "sync" 50 "time" 51 52 "cmd/internal/bio" 53 "cmd/internal/goobj" 54 "cmd/internal/notsha256" 55 "cmd/internal/objabi" 56 "cmd/internal/sys" 57 "cmd/link/internal/loadelf" 58 "cmd/link/internal/loader" 59 "cmd/link/internal/loadmacho" 60 "cmd/link/internal/loadpe" 61 "cmd/link/internal/loadxcoff" 62 "cmd/link/internal/sym" 63) 64 65// Data layout and relocation. 66 67// Derived from Inferno utils/6l/l.h 68// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6l/l.h 69// 70// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 71// Portions Copyright © 1995-1997 C H Forsyth ([email protected]) 72// Portions Copyright © 1997-1999 Vita Nuova Limited 73// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 74// Portions Copyright © 2004,2006 Bruce Ellis 75// Portions Copyright © 2005-2007 C H Forsyth ([email protected]) 76// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 77// Portions Copyright © 2009 The Go Authors. All rights reserved. 78// 79// Permission is hereby granted, free of charge, to any person obtaining a copy 80// of this software and associated documentation files (the "Software"), to deal 81// in the Software without restriction, including without limitation the rights 82// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 83// copies of the Software, and to permit persons to whom the Software is 84// furnished to do so, subject to the following conditions: 85// 86// The above copyright notice and this permission notice shall be included in 87// all copies or substantial portions of the Software. 88// 89// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 90// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 91// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 92// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 93// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 94// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 95// THE SOFTWARE. 96 97// ArchSyms holds a number of architecture specific symbols used during 98// relocation. Rather than allowing them universal access to all symbols, 99// we keep a subset for relocation application. 100type ArchSyms struct { 101 Rel loader.Sym 102 Rela loader.Sym 103 RelPLT loader.Sym 104 RelaPLT loader.Sym 105 106 LinkEditGOT loader.Sym 107 LinkEditPLT loader.Sym 108 109 TOC loader.Sym 110 DotTOC []loader.Sym // for each version 111 112 GOT loader.Sym 113 PLT loader.Sym 114 GOTPLT loader.Sym 115 116 Tlsg loader.Sym 117 Tlsoffset int 118 119 Dynamic loader.Sym 120 DynSym loader.Sym 121 DynStr loader.Sym 122 123 unreachableMethod loader.Sym 124 125 // Symbol containing a list of all the inittasks that need 126 // to be run at startup. 127 mainInittasks loader.Sym 128} 129 130// mkArchSym is a helper for setArchSyms, to set up a special symbol. 131func (ctxt *Link) mkArchSym(name string, ver int, ls *loader.Sym) { 132 *ls = ctxt.loader.LookupOrCreateSym(name, ver) 133 ctxt.loader.SetAttrReachable(*ls, true) 134} 135 136// mkArchSymVec is similar to setArchSyms, but operates on elements within 137// a slice, where each element corresponds to some symbol version. 138func (ctxt *Link) mkArchSymVec(name string, ver int, ls []loader.Sym) { 139 ls[ver] = ctxt.loader.LookupOrCreateSym(name, ver) 140 ctxt.loader.SetAttrReachable(ls[ver], true) 141} 142 143// setArchSyms sets up the ArchSyms structure, and must be called before 144// relocations are applied. 145func (ctxt *Link) setArchSyms() { 146 ctxt.mkArchSym(".got", 0, &ctxt.GOT) 147 ctxt.mkArchSym(".plt", 0, &ctxt.PLT) 148 ctxt.mkArchSym(".got.plt", 0, &ctxt.GOTPLT) 149 ctxt.mkArchSym(".dynamic", 0, &ctxt.Dynamic) 150 ctxt.mkArchSym(".dynsym", 0, &ctxt.DynSym) 151 ctxt.mkArchSym(".dynstr", 0, &ctxt.DynStr) 152 ctxt.mkArchSym("runtime.unreachableMethod", abiInternalVer, &ctxt.unreachableMethod) 153 154 if ctxt.IsPPC64() { 155 ctxt.mkArchSym("TOC", 0, &ctxt.TOC) 156 157 ctxt.DotTOC = make([]loader.Sym, ctxt.MaxVersion()+1) 158 for i := 0; i <= ctxt.MaxVersion(); i++ { 159 if i >= sym.SymVerABICount && i < sym.SymVerStatic { // these versions are not used currently 160 continue 161 } 162 ctxt.mkArchSymVec(".TOC.", i, ctxt.DotTOC) 163 } 164 } 165 if ctxt.IsElf() { 166 ctxt.mkArchSym(".rel", 0, &ctxt.Rel) 167 ctxt.mkArchSym(".rela", 0, &ctxt.Rela) 168 ctxt.mkArchSym(".rel.plt", 0, &ctxt.RelPLT) 169 ctxt.mkArchSym(".rela.plt", 0, &ctxt.RelaPLT) 170 } 171 if ctxt.IsDarwin() { 172 ctxt.mkArchSym(".linkedit.got", 0, &ctxt.LinkEditGOT) 173 ctxt.mkArchSym(".linkedit.plt", 0, &ctxt.LinkEditPLT) 174 } 175} 176 177type Arch struct { 178 Funcalign int 179 Maxalign int 180 Minalign int 181 Dwarfregsp int 182 Dwarfreglr int 183 184 // Threshold of total text size, used for trampoline insertion. If the total 185 // text size is smaller than TrampLimit, we won't need to insert trampolines. 186 // It is pretty close to the offset range of a direct CALL machine instruction. 187 // We leave some room for extra stuff like PLT stubs. 188 TrampLimit uint64 189 190 // Empty spaces between codeblocks will be padded with this value. 191 // For example an architecture might want to pad with a trap instruction to 192 // catch wayward programs. Architectures that do not define a padding value 193 // are padded with zeros. 194 CodePad []byte 195 196 // Plan 9 variables. 197 Plan9Magic uint32 198 Plan9_64Bit bool 199 200 Adddynrel func(*Target, *loader.Loader, *ArchSyms, loader.Sym, loader.Reloc, int) bool 201 Archinit func(*Link) 202 // Archreloc is an arch-specific hook that assists in relocation processing 203 // (invoked by 'relocsym'); it handles target-specific relocation tasks. 204 // Here "rel" is the current relocation being examined, "sym" is the symbol 205 // containing the chunk of data to which the relocation applies, and "off" 206 // is the contents of the to-be-relocated data item (from sym.P). Return 207 // value is the appropriately relocated value (to be written back to the 208 // same spot in sym.P), number of external _host_ relocations needed (i.e. 209 // ELF/Mach-O/etc. relocations, not Go relocations, this must match ELF.Reloc1, 210 // etc.), and a boolean indicating success/failure (a failing value indicates 211 // a fatal error). 212 Archreloc func(*Target, *loader.Loader, *ArchSyms, loader.Reloc, loader.Sym, 213 int64) (relocatedOffset int64, nExtReloc int, ok bool) 214 // Archrelocvariant is a second arch-specific hook used for 215 // relocation processing; it handles relocations where r.Type is 216 // insufficient to describe the relocation (r.Variant != 217 // sym.RV_NONE). Here "rel" is the relocation being applied, "sym" 218 // is the symbol containing the chunk of data to which the 219 // relocation applies, and "off" is the contents of the 220 // to-be-relocated data item (from sym.P). Return is an updated 221 // offset value. 222 Archrelocvariant func(target *Target, ldr *loader.Loader, rel loader.Reloc, 223 rv sym.RelocVariant, sym loader.Sym, offset int64, data []byte) (relocatedOffset int64) 224 225 // Generate a trampoline for a call from s to rs if necessary. ri is 226 // index of the relocation. 227 Trampoline func(ctxt *Link, ldr *loader.Loader, ri int, rs, s loader.Sym) 228 229 // Assembling the binary breaks into two phases, writing the code/data/ 230 // dwarf information (which is rather generic), and some more architecture 231 // specific work like setting up the elf headers/dynamic relocations, etc. 232 // The phases are called "Asmb" and "Asmb2". Asmb2 needs to be defined for 233 // every architecture, but only if architecture has an Asmb function will 234 // it be used for assembly. Otherwise a generic assembly Asmb function is 235 // used. 236 Asmb func(*Link, *loader.Loader) 237 Asmb2 func(*Link, *loader.Loader) 238 239 // Extreloc is an arch-specific hook that converts a Go relocation to an 240 // external relocation. Return the external relocation and whether it is 241 // needed. 242 Extreloc func(*Target, *loader.Loader, loader.Reloc, loader.Sym) (loader.ExtReloc, bool) 243 244 Gentext func(*Link, *loader.Loader) // Generate text before addressing has been performed. 245 Machoreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool 246 MachorelocSize uint32 // size of an Mach-O relocation record, must match Machoreloc1. 247 PEreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool 248 Xcoffreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool 249 250 // Generate additional symbols for the native symbol table just prior to 251 // code generation. 252 GenSymsLate func(*Link, *loader.Loader) 253 254 // TLSIEtoLE converts a TLS Initial Executable relocation to 255 // a TLS Local Executable relocation. 256 // 257 // This is possible when a TLS IE relocation refers to a local 258 // symbol in an executable, which is typical when internally 259 // linking PIE binaries. 260 TLSIEtoLE func(P []byte, off, size int) 261 262 // optional override for assignAddress 263 AssignAddress func(ldr *loader.Loader, sect *sym.Section, n int, s loader.Sym, va uint64, isTramp bool) (*sym.Section, int, uint64) 264 265 // ELF specific information. 266 ELF ELFArch 267} 268 269var ( 270 thearch Arch 271 lcSize int32 272 rpath Rpath 273 spSize int32 274 symSize int32 275) 276 277// Symbol version of ABIInternal symbols. It is sym.SymVerABIInternal if ABI wrappers 278// are used, 0 otherwise. 279var abiInternalVer = sym.SymVerABIInternal 280 281// DynlinkingGo reports whether we are producing Go code that can live 282// in separate shared libraries linked together at runtime. 283func (ctxt *Link) DynlinkingGo() bool { 284 if !ctxt.Loaded { 285 panic("DynlinkingGo called before all symbols loaded") 286 } 287 return ctxt.BuildMode == BuildModeShared || ctxt.linkShared || ctxt.BuildMode == BuildModePlugin || ctxt.canUsePlugins 288} 289 290// CanUsePlugins reports whether a plugins can be used 291func (ctxt *Link) CanUsePlugins() bool { 292 if !ctxt.Loaded { 293 panic("CanUsePlugins called before all symbols loaded") 294 } 295 return ctxt.canUsePlugins 296} 297 298// NeedCodeSign reports whether we need to code-sign the output binary. 299func (ctxt *Link) NeedCodeSign() bool { 300 return ctxt.IsDarwin() && ctxt.IsARM64() 301} 302 303var ( 304 dynlib []string 305 ldflag []string 306 havedynamic int 307 Funcalign int 308 iscgo bool 309 elfglobalsymndx int 310 interpreter string 311 312 debug_s bool // backup old value of debug['s'] 313 HEADR int32 314 315 nerrors int 316 liveness int64 // size of liveness data (funcdata), printed if -v 317 318 // See -strictdups command line flag. 319 checkStrictDups int // 0=off 1=warning 2=error 320 strictDupMsgCount int 321) 322 323var ( 324 Segtext sym.Segment 325 Segrodata sym.Segment 326 Segrelrodata sym.Segment 327 Segdata sym.Segment 328 Segdwarf sym.Segment 329 Segpdata sym.Segment // windows-only 330 Segxdata sym.Segment // windows-only 331 332 Segments = []*sym.Segment{&Segtext, &Segrodata, &Segrelrodata, &Segdata, &Segdwarf, &Segpdata, &Segxdata} 333) 334 335const pkgdef = "__.PKGDEF" 336 337var ( 338 // externalobj is set to true if we see an object compiled by 339 // the host compiler that is not from a package that is known 340 // to support internal linking mode. 341 externalobj = false 342 343 // dynimportfail is a list of packages for which generating 344 // the dynimport file, _cgo_import.go, failed. If there are 345 // any of these objects, we must link externally. Issue 52863. 346 dynimportfail []string 347 348 // preferlinkext is a list of packages for which the Go command 349 // noticed use of peculiar C flags. If we see any of these, 350 // default to linking externally unless overridden by the 351 // user. See issues #58619, #58620, and #58848. 352 preferlinkext []string 353 354 // unknownObjFormat is set to true if we see an object whose 355 // format we don't recognize. 356 unknownObjFormat = false 357 358 theline string 359) 360 361func Lflag(ctxt *Link, arg string) { 362 ctxt.Libdir = append(ctxt.Libdir, arg) 363} 364 365/* 366 * Unix doesn't like it when we write to a running (or, sometimes, 367 * recently run) binary, so remove the output file before writing it. 368 * On Windows 7, remove() can force a subsequent create() to fail. 369 * S_ISREG() does not exist on Plan 9. 370 */ 371func mayberemoveoutfile() { 372 if fi, err := os.Lstat(*flagOutfile); err == nil && !fi.Mode().IsRegular() { 373 return 374 } 375 os.Remove(*flagOutfile) 376} 377 378func libinit(ctxt *Link) { 379 Funcalign = thearch.Funcalign 380 381 // add goroot to the end of the libdir list. 382 suffix := "" 383 384 suffixsep := "" 385 if *flagInstallSuffix != "" { 386 suffixsep = "_" 387 suffix = *flagInstallSuffix 388 } else if *flagRace { 389 suffixsep = "_" 390 suffix = "race" 391 } else if *flagMsan { 392 suffixsep = "_" 393 suffix = "msan" 394 } else if *flagAsan { 395 suffixsep = "_" 396 suffix = "asan" 397 } 398 399 if buildcfg.GOROOT != "" { 400 Lflag(ctxt, filepath.Join(buildcfg.GOROOT, "pkg", fmt.Sprintf("%s_%s%s%s", buildcfg.GOOS, buildcfg.GOARCH, suffixsep, suffix))) 401 } 402 403 mayberemoveoutfile() 404 405 if err := ctxt.Out.Open(*flagOutfile); err != nil { 406 Exitf("cannot create %s: %v", *flagOutfile, err) 407 } 408 409 if *flagEntrySymbol == "" { 410 switch ctxt.BuildMode { 411 case BuildModeCShared, BuildModeCArchive: 412 *flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s_lib", buildcfg.GOARCH, buildcfg.GOOS) 413 case BuildModeExe, BuildModePIE: 414 *flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s", buildcfg.GOARCH, buildcfg.GOOS) 415 case BuildModeShared, BuildModePlugin: 416 // No *flagEntrySymbol for -buildmode=shared and plugin 417 default: 418 Errorf(nil, "unknown *flagEntrySymbol for buildmode %v", ctxt.BuildMode) 419 } 420 } 421} 422 423func exitIfErrors() { 424 if nerrors != 0 || checkStrictDups > 1 && strictDupMsgCount > 0 { 425 mayberemoveoutfile() 426 Exit(2) 427 } 428 429} 430 431func errorexit() { 432 exitIfErrors() 433 Exit(0) 434} 435 436func loadinternal(ctxt *Link, name string) *sym.Library { 437 zerofp := goobj.FingerprintType{} 438 if ctxt.linkShared && ctxt.PackageShlib != nil { 439 if shlib := ctxt.PackageShlib[name]; shlib != "" { 440 return addlibpath(ctxt, "internal", "internal", "", name, shlib, zerofp) 441 } 442 } 443 if ctxt.PackageFile != nil { 444 if pname := ctxt.PackageFile[name]; pname != "" { 445 return addlibpath(ctxt, "internal", "internal", pname, name, "", zerofp) 446 } 447 ctxt.Logf("loadinternal: cannot find %s\n", name) 448 return nil 449 } 450 451 for _, libdir := range ctxt.Libdir { 452 if ctxt.linkShared { 453 shlibname := filepath.Join(libdir, name+".shlibname") 454 if ctxt.Debugvlog != 0 { 455 ctxt.Logf("searching for %s.a in %s\n", name, shlibname) 456 } 457 if _, err := os.Stat(shlibname); err == nil { 458 return addlibpath(ctxt, "internal", "internal", "", name, shlibname, zerofp) 459 } 460 } 461 pname := filepath.Join(libdir, name+".a") 462 if ctxt.Debugvlog != 0 { 463 ctxt.Logf("searching for %s.a in %s\n", name, pname) 464 } 465 if _, err := os.Stat(pname); err == nil { 466 return addlibpath(ctxt, "internal", "internal", pname, name, "", zerofp) 467 } 468 } 469 470 if name == "runtime" { 471 Exitf("error: unable to find runtime.a") 472 } 473 ctxt.Logf("warning: unable to find %s.a\n", name) 474 return nil 475} 476 477// extld returns the current external linker. 478func (ctxt *Link) extld() []string { 479 if len(flagExtld) == 0 { 480 // Return the default external linker for the platform. 481 // This only matters when link tool is called directly without explicit -extld, 482 // go tool already passes the correct linker in other cases. 483 switch buildcfg.GOOS { 484 case "darwin", "freebsd", "openbsd": 485 flagExtld = []string{"clang"} 486 default: 487 flagExtld = []string{"gcc"} 488 } 489 } 490 return flagExtld 491} 492 493// findLibPathCmd uses cmd command to find gcc library libname. 494// It returns library full path if found, or "none" if not found. 495func (ctxt *Link) findLibPathCmd(cmd, libname string) string { 496 extld := ctxt.extld() 497 name, args := extld[0], extld[1:] 498 args = append(args, hostlinkArchArgs(ctxt.Arch)...) 499 args = append(args, cmd) 500 if ctxt.Debugvlog != 0 { 501 ctxt.Logf("%s %v\n", extld, args) 502 } 503 out, err := exec.Command(name, args...).Output() 504 if err != nil { 505 if ctxt.Debugvlog != 0 { 506 ctxt.Logf("not using a %s file because compiler failed\n%v\n%s\n", libname, err, out) 507 } 508 return "none" 509 } 510 return strings.TrimSpace(string(out)) 511} 512 513// findLibPath searches for library libname. 514// It returns library full path if found, or "none" if not found. 515func (ctxt *Link) findLibPath(libname string) string { 516 return ctxt.findLibPathCmd("--print-file-name="+libname, libname) 517} 518 519func (ctxt *Link) loadlib() { 520 var flags uint32 521 if *flagCheckLinkname { 522 flags |= loader.FlagCheckLinkname 523 } 524 switch *FlagStrictDups { 525 case 0: 526 // nothing to do 527 case 1, 2: 528 flags |= loader.FlagStrictDups 529 default: 530 log.Fatalf("invalid -strictdups flag value %d", *FlagStrictDups) 531 } 532 ctxt.loader = loader.NewLoader(flags, &ctxt.ErrorReporter.ErrorReporter) 533 ctxt.ErrorReporter.SymName = func(s loader.Sym) string { 534 return ctxt.loader.SymName(s) 535 } 536 537 // ctxt.Library grows during the loop, so not a range loop. 538 i := 0 539 for ; i < len(ctxt.Library); i++ { 540 lib := ctxt.Library[i] 541 if lib.Shlib == "" { 542 if ctxt.Debugvlog > 1 { 543 ctxt.Logf("autolib: %s (from %s)\n", lib.File, lib.Objref) 544 } 545 loadobjfile(ctxt, lib) 546 } 547 } 548 549 // load internal packages, if not already 550 if *flagRace { 551 loadinternal(ctxt, "runtime/race") 552 } 553 if *flagMsan { 554 loadinternal(ctxt, "runtime/msan") 555 } 556 if *flagAsan { 557 loadinternal(ctxt, "runtime/asan") 558 } 559 loadinternal(ctxt, "runtime") 560 for ; i < len(ctxt.Library); i++ { 561 lib := ctxt.Library[i] 562 if lib.Shlib == "" { 563 loadobjfile(ctxt, lib) 564 } 565 } 566 // At this point, the Go objects are "preloaded". Not all the symbols are 567 // added to the symbol table (only defined package symbols are). Looking 568 // up symbol by name may not get expected result. 569 570 iscgo = ctxt.LibraryByPkg["runtime/cgo"] != nil 571 572 // Plugins a require cgo support to function. Similarly, plugins may require additional 573 // internal linker support on some platforms which may not be implemented. 574 ctxt.canUsePlugins = ctxt.LibraryByPkg["plugin"] != nil && iscgo 575 576 // We now have enough information to determine the link mode. 577 determineLinkMode(ctxt) 578 579 if ctxt.LinkMode == LinkExternal && !iscgo && !(buildcfg.GOOS == "darwin" && ctxt.BuildMode != BuildModePlugin && ctxt.Arch.Family == sys.AMD64) { 580 // This indicates a user requested -linkmode=external. 581 // The startup code uses an import of runtime/cgo to decide 582 // whether to initialize the TLS. So give it one. This could 583 // be handled differently but it's an unusual case. 584 if lib := loadinternal(ctxt, "runtime/cgo"); lib != nil && lib.Shlib == "" { 585 if ctxt.BuildMode == BuildModeShared || ctxt.linkShared { 586 Exitf("cannot implicitly include runtime/cgo in a shared library") 587 } 588 for ; i < len(ctxt.Library); i++ { 589 lib := ctxt.Library[i] 590 if lib.Shlib == "" { 591 loadobjfile(ctxt, lib) 592 } 593 } 594 } 595 } 596 597 // Add non-package symbols and references of externally defined symbols. 598 ctxt.loader.LoadSyms(ctxt.Arch) 599 600 // Load symbols from shared libraries, after all Go object symbols are loaded. 601 for _, lib := range ctxt.Library { 602 if lib.Shlib != "" { 603 if ctxt.Debugvlog > 1 { 604 ctxt.Logf("autolib: %s (from %s)\n", lib.Shlib, lib.Objref) 605 } 606 ldshlibsyms(ctxt, lib.Shlib) 607 } 608 } 609 610 // Process cgo directives (has to be done before host object loading). 611 ctxt.loadcgodirectives() 612 613 // Conditionally load host objects, or setup for external linking. 614 hostobjs(ctxt) 615 hostlinksetup(ctxt) 616 617 if ctxt.LinkMode == LinkInternal && len(hostobj) != 0 { 618 // If we have any undefined symbols in external 619 // objects, try to read them from the libgcc file. 620 any := false 621 undefs, froms := ctxt.loader.UndefinedRelocTargets(1) 622 if len(undefs) > 0 { 623 any = true 624 if ctxt.Debugvlog > 1 { 625 ctxt.Logf("loadlib: first unresolved is %s [%d] from %s [%d]\n", 626 ctxt.loader.SymName(undefs[0]), undefs[0], 627 ctxt.loader.SymName(froms[0]), froms[0]) 628 } 629 } 630 if any { 631 if *flagLibGCC == "" { 632 *flagLibGCC = ctxt.findLibPathCmd("--print-libgcc-file-name", "libgcc") 633 } 634 if runtime.GOOS == "openbsd" && *flagLibGCC == "libgcc.a" { 635 // On OpenBSD `clang --print-libgcc-file-name` returns "libgcc.a". 636 // In this case we fail to load libgcc.a and can encounter link 637 // errors - see if we can find libcompiler_rt.a instead. 638 *flagLibGCC = ctxt.findLibPathCmd("--print-file-name=libcompiler_rt.a", "libcompiler_rt") 639 } 640 if ctxt.HeadType == objabi.Hwindows { 641 loadWindowsHostArchives(ctxt) 642 } 643 if *flagLibGCC != "none" { 644 hostArchive(ctxt, *flagLibGCC) 645 } 646 // For glibc systems, the linker setup used by GCC 647 // looks like 648 // 649 // GROUP ( /lib/x86_64-linux-gnu/libc.so.6 650 // /usr/lib/x86_64-linux-gnu/libc_nonshared.a 651 // AS_NEEDED ( /lib64/ld-linux-x86-64.so.2 ) ) 652 // 653 // where libc_nonshared.a contains a small set of 654 // symbols including "__stack_chk_fail_local" and a 655 // few others. Thus if we are doing internal linking 656 // and "__stack_chk_fail_local" is unresolved (most 657 // likely due to the use of -fstack-protector), try 658 // loading libc_nonshared.a to resolve it. 659 // 660 // On Alpine Linux (musl-based), the library providing 661 // this symbol is called libssp_nonshared.a. 662 isunresolved := symbolsAreUnresolved(ctxt, []string{"__stack_chk_fail_local"}) 663 if isunresolved[0] { 664 if p := ctxt.findLibPath("libc_nonshared.a"); p != "none" { 665 hostArchive(ctxt, p) 666 } 667 if p := ctxt.findLibPath("libssp_nonshared.a"); p != "none" { 668 hostArchive(ctxt, p) 669 } 670 } 671 } 672 } 673 674 // We've loaded all the code now. 675 ctxt.Loaded = true 676 677 strictDupMsgCount = ctxt.loader.NStrictDupMsgs() 678} 679 680// loadWindowsHostArchives loads in host archives and objects when 681// doing internal linking on windows. Older toolchains seem to require 682// just a single pass through the various archives, but some modern 683// toolchains when linking a C program with mingw pass library paths 684// multiple times to the linker, e.g. "... -lmingwex -lmingw32 ... 685// -lmingwex -lmingw32 ...". To accommodate this behavior, we make two 686// passes over the host archives below. 687func loadWindowsHostArchives(ctxt *Link) { 688 any := true 689 for i := 0; any && i < 2; i++ { 690 // Link crt2.o (if present) to resolve "atexit" when 691 // using LLVM-based compilers. 692 isunresolved := symbolsAreUnresolved(ctxt, []string{"atexit"}) 693 if isunresolved[0] { 694 if p := ctxt.findLibPath("crt2.o"); p != "none" { 695 hostObject(ctxt, "crt2", p) 696 } 697 } 698 if *flagRace { 699 if p := ctxt.findLibPath("libsynchronization.a"); p != "none" { 700 hostArchive(ctxt, p) 701 } 702 } 703 if p := ctxt.findLibPath("libmingwex.a"); p != "none" { 704 hostArchive(ctxt, p) 705 } 706 if p := ctxt.findLibPath("libmingw32.a"); p != "none" { 707 hostArchive(ctxt, p) 708 } 709 // Link libmsvcrt.a to resolve '__acrt_iob_func' symbol 710 // (see https://golang.org/issue/23649 for details). 711 if p := ctxt.findLibPath("libmsvcrt.a"); p != "none" { 712 hostArchive(ctxt, p) 713 } 714 any = false 715 undefs, froms := ctxt.loader.UndefinedRelocTargets(1) 716 if len(undefs) > 0 { 717 any = true 718 if ctxt.Debugvlog > 1 { 719 ctxt.Logf("loadWindowsHostArchives: remaining unresolved is %s [%d] from %s [%d]\n", 720 ctxt.loader.SymName(undefs[0]), undefs[0], 721 ctxt.loader.SymName(froms[0]), froms[0]) 722 } 723 } 724 } 725 // If needed, create the __CTOR_LIST__ and __DTOR_LIST__ 726 // symbols (referenced by some of the mingw support library 727 // routines). Creation of these symbols is normally done by the 728 // linker if not already present. 729 want := []string{"__CTOR_LIST__", "__DTOR_LIST__"} 730 isunresolved := symbolsAreUnresolved(ctxt, want) 731 for k, w := range want { 732 if isunresolved[k] { 733 sb := ctxt.loader.CreateSymForUpdate(w, 0) 734 sb.SetType(sym.SDATA) 735 sb.AddUint64(ctxt.Arch, 0) 736 sb.SetReachable(true) 737 ctxt.loader.SetAttrSpecial(sb.Sym(), true) 738 } 739 } 740 741 // Fix up references to DLL import symbols now that we're done 742 // pulling in new objects. 743 if err := loadpe.PostProcessImports(); err != nil { 744 Errorf(nil, "%v", err) 745 } 746 747 // TODO: maybe do something similar to peimporteddlls to collect 748 // all lib names and try link them all to final exe just like 749 // libmingwex.a and libmingw32.a: 750 /* 751 for: 752 #cgo windows LDFLAGS: -lmsvcrt -lm 753 import: 754 libmsvcrt.a libm.a 755 */ 756} 757 758// loadcgodirectives reads the previously discovered cgo directives, creating 759// symbols in preparation for host object loading or use later in the link. 760func (ctxt *Link) loadcgodirectives() { 761 l := ctxt.loader 762 hostObjSyms := make(map[loader.Sym]struct{}) 763 for _, d := range ctxt.cgodata { 764 setCgoAttr(ctxt, d.file, d.pkg, d.directives, hostObjSyms) 765 } 766 ctxt.cgodata = nil 767 768 if ctxt.LinkMode == LinkInternal { 769 // Drop all the cgo_import_static declarations. 770 // Turns out we won't be needing them. 771 for symIdx := range hostObjSyms { 772 if l.SymType(symIdx) == sym.SHOSTOBJ { 773 // If a symbol was marked both 774 // cgo_import_static and cgo_import_dynamic, 775 // then we want to make it cgo_import_dynamic 776 // now. 777 su := l.MakeSymbolUpdater(symIdx) 778 if l.SymExtname(symIdx) != "" && l.SymDynimplib(symIdx) != "" && !(l.AttrCgoExportStatic(symIdx) || l.AttrCgoExportDynamic(symIdx)) { 779 su.SetType(sym.SDYNIMPORT) 780 } else { 781 su.SetType(0) 782 } 783 } 784 } 785 } 786} 787 788// Set up flags and special symbols depending on the platform build mode. 789// This version works with loader.Loader. 790func (ctxt *Link) linksetup() { 791 switch ctxt.BuildMode { 792 case BuildModeCShared, BuildModePlugin: 793 symIdx := ctxt.loader.LookupOrCreateSym("runtime.islibrary", 0) 794 sb := ctxt.loader.MakeSymbolUpdater(symIdx) 795 sb.SetType(sym.SNOPTRDATA) 796 sb.AddUint8(1) 797 case BuildModeCArchive: 798 symIdx := ctxt.loader.LookupOrCreateSym("runtime.isarchive", 0) 799 sb := ctxt.loader.MakeSymbolUpdater(symIdx) 800 sb.SetType(sym.SNOPTRDATA) 801 sb.AddUint8(1) 802 } 803 804 // Recalculate pe parameters now that we have ctxt.LinkMode set. 805 if ctxt.HeadType == objabi.Hwindows { 806 Peinit(ctxt) 807 } 808 809 if ctxt.LinkMode == LinkExternal { 810 // When external linking, we are creating an object file. The 811 // absolute address is irrelevant. 812 *FlagTextAddr = 0 813 } 814 815 // If there are no dynamic libraries needed, gcc disables dynamic linking. 816 // Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13) 817 // assumes that a dynamic binary always refers to at least one dynamic library. 818 // Rather than be a source of test cases for glibc, disable dynamic linking 819 // the same way that gcc would. 820 // 821 // Exception: on OS X, programs such as Shark only work with dynamic 822 // binaries, so leave it enabled on OS X (Mach-O) binaries. 823 // Also leave it enabled on Solaris which doesn't support 824 // statically linked binaries. 825 if ctxt.BuildMode == BuildModeExe { 826 if havedynamic == 0 && ctxt.HeadType != objabi.Hdarwin && ctxt.HeadType != objabi.Hsolaris { 827 *FlagD = true 828 } 829 } 830 831 if ctxt.LinkMode == LinkExternal && ctxt.Arch.Family == sys.PPC64 && buildcfg.GOOS != "aix" { 832 toc := ctxt.loader.LookupOrCreateSym(".TOC.", 0) 833 sb := ctxt.loader.MakeSymbolUpdater(toc) 834 sb.SetType(sym.SDYNIMPORT) 835 } 836 837 // The Android Q linker started to complain about underalignment of the our TLS 838 // section. We don't actually use the section on android, so don't 839 // generate it. 840 if buildcfg.GOOS != "android" { 841 tlsg := ctxt.loader.LookupOrCreateSym("runtime.tlsg", 0) 842 sb := ctxt.loader.MakeSymbolUpdater(tlsg) 843 844 // runtime.tlsg is used for external linking on platforms that do not define 845 // a variable to hold g in assembly (currently only intel). 846 if sb.Type() == 0 { 847 sb.SetType(sym.STLSBSS) 848 sb.SetSize(int64(ctxt.Arch.PtrSize)) 849 } else if sb.Type() != sym.SDYNIMPORT { 850 Errorf(nil, "runtime declared tlsg variable %v", sb.Type()) 851 } 852 ctxt.loader.SetAttrReachable(tlsg, true) 853 ctxt.Tlsg = tlsg 854 } 855 856 var moduledata loader.Sym 857 var mdsb *loader.SymbolBuilder 858 if ctxt.BuildMode == BuildModePlugin { 859 moduledata = ctxt.loader.LookupOrCreateSym("local.pluginmoduledata", 0) 860 mdsb = ctxt.loader.MakeSymbolUpdater(moduledata) 861 ctxt.loader.SetAttrLocal(moduledata, true) 862 } else { 863 moduledata = ctxt.loader.LookupOrCreateSym("runtime.firstmoduledata", 0) 864 mdsb = ctxt.loader.MakeSymbolUpdater(moduledata) 865 } 866 if mdsb.Type() != 0 && mdsb.Type() != sym.SDYNIMPORT { 867 // If the module (toolchain-speak for "executable or shared 868 // library") we are linking contains the runtime package, it 869 // will define the runtime.firstmoduledata symbol and we 870 // truncate it back to 0 bytes so we can define its entire 871 // contents in symtab.go:symtab(). 872 mdsb.SetSize(0) 873 874 // In addition, on ARM, the runtime depends on the linker 875 // recording the value of GOARM. 876 if ctxt.Arch.Family == sys.ARM { 877 goarm := ctxt.loader.LookupOrCreateSym("runtime.goarm", 0) 878 sb := ctxt.loader.MakeSymbolUpdater(goarm) 879 sb.SetType(sym.SDATA) 880 sb.SetSize(0) 881 sb.AddUint8(uint8(buildcfg.GOARM.Version)) 882 883 goarmsoftfp := ctxt.loader.LookupOrCreateSym("runtime.goarmsoftfp", 0) 884 sb2 := ctxt.loader.MakeSymbolUpdater(goarmsoftfp) 885 sb2.SetType(sym.SDATA) 886 sb2.SetSize(0) 887 if buildcfg.GOARM.SoftFloat { 888 sb2.AddUint8(1) 889 } else { 890 sb2.AddUint8(0) 891 } 892 } 893 894 // Set runtime.disableMemoryProfiling bool if 895 // runtime.memProfileInternal is not retained in the binary after 896 // deadcode (and we're not dynamically linking). 897 memProfile := ctxt.loader.Lookup("runtime.memProfileInternal", abiInternalVer) 898 if memProfile != 0 && !ctxt.loader.AttrReachable(memProfile) && !ctxt.DynlinkingGo() { 899 memProfSym := ctxt.loader.LookupOrCreateSym("runtime.disableMemoryProfiling", 0) 900 sb := ctxt.loader.MakeSymbolUpdater(memProfSym) 901 sb.SetType(sym.SDATA) 902 sb.SetSize(0) 903 sb.AddUint8(1) // true bool 904 } 905 } else { 906 // If OTOH the module does not contain the runtime package, 907 // create a local symbol for the moduledata. 908 moduledata = ctxt.loader.LookupOrCreateSym("local.moduledata", 0) 909 mdsb = ctxt.loader.MakeSymbolUpdater(moduledata) 910 ctxt.loader.SetAttrLocal(moduledata, true) 911 } 912 // In all cases way we mark the moduledata as noptrdata to hide it from 913 // the GC. 914 mdsb.SetType(sym.SNOPTRDATA) 915 ctxt.loader.SetAttrReachable(moduledata, true) 916 ctxt.Moduledata = moduledata 917 918 if ctxt.Arch == sys.Arch386 && ctxt.HeadType != objabi.Hwindows { 919 if (ctxt.BuildMode == BuildModeCArchive && ctxt.IsELF) || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE || ctxt.DynlinkingGo() { 920 got := ctxt.loader.LookupOrCreateSym("_GLOBAL_OFFSET_TABLE_", 0) 921 sb := ctxt.loader.MakeSymbolUpdater(got) 922 sb.SetType(sym.SDYNIMPORT) 923 ctxt.loader.SetAttrReachable(got, true) 924 } 925 } 926 927 // DWARF-gen and other phases require that the unit Textp slices 928 // be populated, so that it can walk the functions in each unit. 929 // Call into the loader to do this (requires that we collect the 930 // set of internal libraries first). NB: might be simpler if we 931 // moved isRuntimeDepPkg to cmd/internal and then did the test in 932 // loader.AssignTextSymbolOrder. 933 ctxt.Library = postorder(ctxt.Library) 934 intlibs := []bool{} 935 for _, lib := range ctxt.Library { 936 intlibs = append(intlibs, isRuntimeDepPkg(lib.Pkg)) 937 } 938 ctxt.Textp = ctxt.loader.AssignTextSymbolOrder(ctxt.Library, intlibs, ctxt.Textp) 939} 940 941// mangleTypeSym shortens the names of symbols that represent Go types 942// if they are visible in the symbol table. 943// 944// As the names of these symbols are derived from the string of 945// the type, they can run to many kilobytes long. So we shorten 946// them using a SHA-1 when the name appears in the final binary. 947// This also removes characters that upset external linkers. 948// 949// These are the symbols that begin with the prefix 'type.' and 950// contain run-time type information used by the runtime and reflect 951// packages. All Go binaries contain these symbols, but only 952// those programs loaded dynamically in multiple parts need these 953// symbols to have entries in the symbol table. 954func (ctxt *Link) mangleTypeSym() { 955 if ctxt.BuildMode != BuildModeShared && !ctxt.linkShared && ctxt.BuildMode != BuildModePlugin && !ctxt.CanUsePlugins() { 956 return 957 } 958 959 ldr := ctxt.loader 960 for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ { 961 if !ldr.AttrReachable(s) && !ctxt.linkShared { 962 // If -linkshared, the GCProg generation code may need to reach 963 // out to the shared library for the type descriptor's data, even 964 // the type descriptor itself is not actually needed at run time 965 // (therefore not reachable). We still need to mangle its name, 966 // so it is consistent with the one stored in the shared library. 967 continue 968 } 969 name := ldr.SymName(s) 970 newName := typeSymbolMangle(name) 971 if newName != name { 972 ldr.SetSymExtname(s, newName) 973 974 // When linking against a shared library, the Go object file may 975 // have reference to the original symbol name whereas the shared 976 // library provides a symbol with the mangled name. We need to 977 // copy the payload of mangled to original. 978 // XXX maybe there is a better way to do this. 979 dup := ldr.Lookup(newName, ldr.SymVersion(s)) 980 if dup != 0 { 981 st := ldr.SymType(s) 982 dt := ldr.SymType(dup) 983 if st == sym.Sxxx && dt != sym.Sxxx { 984 ldr.CopySym(dup, s) 985 } 986 } 987 } 988 } 989} 990 991// typeSymbolMangle mangles the given symbol name into something shorter. 992// 993// Keep the type:. prefix, which parts of the linker (like the 994// DWARF generator) know means the symbol is not decodable. 995// Leave type:runtime. symbols alone, because other parts of 996// the linker manipulates them. 997func typeSymbolMangle(name string) string { 998 isType := strings.HasPrefix(name, "type:") 999 if !isType && !strings.Contains(name, "@") { 1000 // Issue 58800: instantiated symbols may include a type name, which may contain "@" 1001 return name 1002 } 1003 if strings.HasPrefix(name, "type:runtime.") { 1004 return name 1005 } 1006 if strings.HasPrefix(name, "go:string.") { 1007 // String symbols will be grouped to a single go:string.* symbol. 1008 // No need to mangle individual symbol names. 1009 return name 1010 } 1011 if len(name) <= 14 && !strings.Contains(name, "@") { // Issue 19529 1012 return name 1013 } 1014 if isType { 1015 hash := notsha256.Sum256([]byte(name[5:])) 1016 prefix := "type:" 1017 if name[5] == '.' { 1018 prefix = "type:." 1019 } 1020 return prefix + base64.StdEncoding.EncodeToString(hash[:6]) 1021 } 1022 // instantiated symbol, replace type name in [] 1023 i := strings.IndexByte(name, '[') 1024 j := strings.LastIndexByte(name, ']') 1025 if j == -1 || j <= i { 1026 j = len(name) 1027 } 1028 hash := notsha256.Sum256([]byte(name[i+1 : j])) 1029 return name[:i+1] + base64.StdEncoding.EncodeToString(hash[:6]) + name[j:] 1030} 1031 1032/* 1033 * look for the next file in an archive. 1034 * adapted from libmach. 1035 */ 1036func nextar(bp *bio.Reader, off int64, a *ArHdr) int64 { 1037 if off&1 != 0 { 1038 off++ 1039 } 1040 bp.MustSeek(off, 0) 1041 var buf [SAR_HDR]byte 1042 if n, err := io.ReadFull(bp, buf[:]); err != nil { 1043 if n == 0 && err != io.EOF { 1044 return -1 1045 } 1046 return 0 1047 } 1048 1049 a.name = artrim(buf[0:16]) 1050 a.date = artrim(buf[16:28]) 1051 a.uid = artrim(buf[28:34]) 1052 a.gid = artrim(buf[34:40]) 1053 a.mode = artrim(buf[40:48]) 1054 a.size = artrim(buf[48:58]) 1055 a.fmag = artrim(buf[58:60]) 1056 1057 arsize := atolwhex(a.size) 1058 if arsize&1 != 0 { 1059 arsize++ 1060 } 1061 return arsize + SAR_HDR 1062} 1063 1064func loadobjfile(ctxt *Link, lib *sym.Library) { 1065 pkg := objabi.PathToPrefix(lib.Pkg) 1066 1067 if ctxt.Debugvlog > 1 { 1068 ctxt.Logf("ldobj: %s (%s)\n", lib.File, pkg) 1069 } 1070 f, err := bio.Open(lib.File) 1071 if err != nil { 1072 Exitf("cannot open file %s: %v", lib.File, err) 1073 } 1074 defer f.Close() 1075 defer func() { 1076 if pkg == "main" && !lib.Main { 1077 Exitf("%s: not package main", lib.File) 1078 } 1079 }() 1080 1081 for i := 0; i < len(ARMAG); i++ { 1082 if c, err := f.ReadByte(); err == nil && c == ARMAG[i] { 1083 continue 1084 } 1085 1086 /* load it as a regular file */ 1087 l := f.MustSeek(0, 2) 1088 f.MustSeek(0, 0) 1089 ldobj(ctxt, f, lib, l, lib.File, lib.File) 1090 return 1091 } 1092 1093 /* 1094 * load all the object files from the archive now. 1095 * this gives us sequential file access and keeps us 1096 * from needing to come back later to pick up more 1097 * objects. it breaks the usual C archive model, but 1098 * this is Go, not C. the common case in Go is that 1099 * we need to load all the objects, and then we throw away 1100 * the individual symbols that are unused. 1101 * 1102 * loading every object will also make it possible to 1103 * load foreign objects not referenced by __.PKGDEF. 1104 */ 1105 var arhdr ArHdr 1106 off := f.Offset() 1107 for { 1108 l := nextar(f, off, &arhdr) 1109 if l == 0 { 1110 break 1111 } 1112 if l < 0 { 1113 Exitf("%s: malformed archive", lib.File) 1114 } 1115 off += l 1116 1117 // __.PKGDEF isn't a real Go object file, and it's 1118 // absent in -linkobj builds anyway. Skipping it 1119 // ensures consistency between -linkobj and normal 1120 // build modes. 1121 if arhdr.name == pkgdef { 1122 continue 1123 } 1124 1125 if arhdr.name == "dynimportfail" { 1126 dynimportfail = append(dynimportfail, lib.Pkg) 1127 } 1128 if arhdr.name == "preferlinkext" { 1129 // Ignore this directive if -linkmode has been 1130 // set explicitly. 1131 if ctxt.LinkMode == LinkAuto { 1132 preferlinkext = append(preferlinkext, lib.Pkg) 1133 } 1134 } 1135 1136 // Skip other special (non-object-file) sections that 1137 // build tools may have added. Such sections must have 1138 // short names so that the suffix is not truncated. 1139 if len(arhdr.name) < 16 { 1140 if ext := filepath.Ext(arhdr.name); ext != ".o" && ext != ".syso" { 1141 continue 1142 } 1143 } 1144 1145 pname := fmt.Sprintf("%s(%s)", lib.File, arhdr.name) 1146 l = atolwhex(arhdr.size) 1147 ldobj(ctxt, f, lib, l, pname, lib.File) 1148 } 1149} 1150 1151type Hostobj struct { 1152 ld func(*Link, *bio.Reader, string, int64, string) 1153 pkg string 1154 pn string 1155 file string 1156 off int64 1157 length int64 1158} 1159 1160var hostobj []Hostobj 1161 1162// These packages can use internal linking mode. 1163// Others trigger external mode. 1164var internalpkg = []string{ 1165 "crypto/internal/boring", 1166 "crypto/internal/boring/syso", 1167 "crypto/x509", 1168 "net", 1169 "os/user", 1170 "runtime/cgo", 1171 "runtime/race", 1172 "runtime/race/internal/amd64v1", 1173 "runtime/race/internal/amd64v3", 1174 "runtime/msan", 1175 "runtime/asan", 1176} 1177 1178func ldhostobj(ld func(*Link, *bio.Reader, string, int64, string), headType objabi.HeadType, f *bio.Reader, pkg string, length int64, pn string, file string) *Hostobj { 1179 isinternal := false 1180 for _, intpkg := range internalpkg { 1181 if pkg == intpkg { 1182 isinternal = true 1183 break 1184 } 1185 } 1186 1187 // DragonFly declares errno with __thread, which results in a symbol 1188 // type of R_386_TLS_GD or R_X86_64_TLSGD. The Go linker does not 1189 // currently know how to handle TLS relocations, hence we have to 1190 // force external linking for any libraries that link in code that 1191 // uses errno. This can be removed if the Go linker ever supports 1192 // these relocation types. 1193 if headType == objabi.Hdragonfly { 1194 if pkg == "net" || pkg == "os/user" { 1195 isinternal = false 1196 } 1197 } 1198 1199 if !isinternal { 1200 externalobj = true 1201 } 1202 1203 hostobj = append(hostobj, Hostobj{}) 1204 h := &hostobj[len(hostobj)-1] 1205 h.ld = ld 1206 h.pkg = pkg 1207 h.pn = pn 1208 h.file = file 1209 h.off = f.Offset() 1210 h.length = length 1211 return h 1212} 1213 1214func hostobjs(ctxt *Link) { 1215 if ctxt.LinkMode != LinkInternal { 1216 return 1217 } 1218 var h *Hostobj 1219 1220 for i := 0; i < len(hostobj); i++ { 1221 h = &hostobj[i] 1222 f, err := bio.Open(h.file) 1223 if err != nil { 1224 Exitf("cannot reopen %s: %v", h.pn, err) 1225 } 1226 f.MustSeek(h.off, 0) 1227 if h.ld == nil { 1228 Errorf(nil, "%s: unrecognized object file format", h.pn) 1229 continue 1230 } 1231 h.ld(ctxt, f, h.pkg, h.length, h.pn) 1232 if *flagCaptureHostObjs != "" { 1233 captureHostObj(h) 1234 } 1235 f.Close() 1236 } 1237} 1238 1239func hostlinksetup(ctxt *Link) { 1240 if ctxt.LinkMode != LinkExternal { 1241 return 1242 } 1243 1244 // For external link, record that we need to tell the external linker -s, 1245 // and turn off -s internally: the external linker needs the symbol 1246 // information for its final link. 1247 debug_s = *FlagS 1248 *FlagS = false 1249 1250 // create temporary directory and arrange cleanup 1251 if *flagTmpdir == "" { 1252 dir, err := os.MkdirTemp("", "go-link-") 1253 if err != nil { 1254 log.Fatal(err) 1255 } 1256 *flagTmpdir = dir 1257 ownTmpDir = true 1258 AtExit(func() { 1259 os.RemoveAll(*flagTmpdir) 1260 }) 1261 } 1262 1263 // change our output to temporary object file 1264 if err := ctxt.Out.Close(); err != nil { 1265 Exitf("error closing output file") 1266 } 1267 mayberemoveoutfile() 1268 1269 p := filepath.Join(*flagTmpdir, "go.o") 1270 if err := ctxt.Out.Open(p); err != nil { 1271 Exitf("cannot create %s: %v", p, err) 1272 } 1273} 1274 1275// cleanTimeStamps resets the timestamps for the specified list of 1276// existing files to the Unix epoch (1970-01-01 00:00:00 +0000 UTC). 1277// We take this step in order to help preserve reproducible builds; 1278// this seems to be primarily needed for external linking on on Darwin 1279// with later versions of xcode, which (unfortunately) seem to want to 1280// incorporate object file times into the final output file's build 1281// ID. See issue 64947 for the unpleasant details. 1282func cleanTimeStamps(files []string) { 1283 epocht := time.Unix(0, 0) 1284 for _, f := range files { 1285 if err := os.Chtimes(f, epocht, epocht); err != nil { 1286 Exitf("cannot chtimes %s: %v", f, err) 1287 } 1288 } 1289} 1290 1291// hostobjCopy creates a copy of the object files in hostobj in a 1292// temporary directory. 1293func (ctxt *Link) hostobjCopy() (paths []string) { 1294 var wg sync.WaitGroup 1295 sema := make(chan struct{}, runtime.NumCPU()) // limit open file descriptors 1296 for i, h := range hostobj { 1297 h := h 1298 dst := filepath.Join(*flagTmpdir, fmt.Sprintf("%06d.o", i)) 1299 paths = append(paths, dst) 1300 if ctxt.Debugvlog != 0 { 1301 ctxt.Logf("host obj copy: %s from pkg %s -> %s\n", h.pn, h.pkg, dst) 1302 } 1303 1304 wg.Add(1) 1305 go func() { 1306 sema <- struct{}{} 1307 defer func() { 1308 <-sema 1309 wg.Done() 1310 }() 1311 f, err := os.Open(h.file) 1312 if err != nil { 1313 Exitf("cannot reopen %s: %v", h.pn, err) 1314 } 1315 defer f.Close() 1316 if _, err := f.Seek(h.off, 0); err != nil { 1317 Exitf("cannot seek %s: %v", h.pn, err) 1318 } 1319 1320 w, err := os.Create(dst) 1321 if err != nil { 1322 Exitf("cannot create %s: %v", dst, err) 1323 } 1324 if _, err := io.CopyN(w, f, h.length); err != nil { 1325 Exitf("cannot write %s: %v", dst, err) 1326 } 1327 if err := w.Close(); err != nil { 1328 Exitf("cannot close %s: %v", dst, err) 1329 } 1330 }() 1331 } 1332 wg.Wait() 1333 return paths 1334} 1335 1336// writeGDBLinkerScript creates gcc linker script file in temp 1337// directory. writeGDBLinkerScript returns created file path. 1338// The script is used to work around gcc bug 1339// (see https://golang.org/issue/20183 for details). 1340func writeGDBLinkerScript() string { 1341 name := "fix_debug_gdb_scripts.ld" 1342 path := filepath.Join(*flagTmpdir, name) 1343 src := `SECTIONS 1344{ 1345 .debug_gdb_scripts BLOCK(__section_alignment__) (NOLOAD) : 1346 { 1347 *(.debug_gdb_scripts) 1348 } 1349} 1350INSERT AFTER .debug_types; 1351` 1352 err := os.WriteFile(path, []byte(src), 0666) 1353 if err != nil { 1354 Errorf(nil, "WriteFile %s failed: %v", name, err) 1355 } 1356 return path 1357} 1358 1359type machoUpdateFunc func(ctxt *Link, exef *os.File, exem *macho.File, outexe string) error 1360 1361// archive builds a .a archive from the hostobj object files. 1362func (ctxt *Link) archive() { 1363 if ctxt.BuildMode != BuildModeCArchive { 1364 return 1365 } 1366 1367 exitIfErrors() 1368 1369 if *flagExtar == "" { 1370 const printProgName = "--print-prog-name=ar" 1371 cc := ctxt.extld() 1372 *flagExtar = "ar" 1373 if linkerFlagSupported(ctxt.Arch, cc[0], "", printProgName) { 1374 *flagExtar = ctxt.findExtLinkTool("ar") 1375 } 1376 } 1377 1378 mayberemoveoutfile() 1379 1380 // Force the buffer to flush here so that external 1381 // tools will see a complete file. 1382 if err := ctxt.Out.Close(); err != nil { 1383 Exitf("error closing %v", *flagOutfile) 1384 } 1385 1386 argv := []string{*flagExtar, "-q", "-c", "-s"} 1387 if ctxt.HeadType == objabi.Haix { 1388 argv = append(argv, "-X64") 1389 } 1390 godotopath := filepath.Join(*flagTmpdir, "go.o") 1391 cleanTimeStamps([]string{godotopath}) 1392 hostObjCopyPaths := ctxt.hostobjCopy() 1393 cleanTimeStamps(hostObjCopyPaths) 1394 1395 argv = append(argv, *flagOutfile) 1396 argv = append(argv, godotopath) 1397 argv = append(argv, hostObjCopyPaths...) 1398 1399 if ctxt.Debugvlog != 0 { 1400 ctxt.Logf("archive: %s\n", strings.Join(argv, " ")) 1401 } 1402 1403 // If supported, use syscall.Exec() to invoke the archive command, 1404 // which should be the final remaining step needed for the link. 1405 // This will reduce peak RSS for the link (and speed up linking of 1406 // large applications), since when the archive command runs we 1407 // won't be holding onto all of the linker's live memory. 1408 if syscallExecSupported && !ownTmpDir { 1409 runAtExitFuncs() 1410 ctxt.execArchive(argv) 1411 panic("should not get here") 1412 } 1413 1414 // Otherwise invoke 'ar' in the usual way (fork + exec). 1415 if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil { 1416 Exitf("running %s failed: %v\n%s", argv[0], err, out) 1417 } 1418} 1419 1420func (ctxt *Link) hostlink() { 1421 if ctxt.LinkMode != LinkExternal || nerrors > 0 { 1422 return 1423 } 1424 if ctxt.BuildMode == BuildModeCArchive { 1425 return 1426 } 1427 1428 var argv []string 1429 argv = append(argv, ctxt.extld()...) 1430 argv = append(argv, hostlinkArchArgs(ctxt.Arch)...) 1431 1432 if *FlagS || debug_s { 1433 if ctxt.HeadType == objabi.Hdarwin { 1434 // Recent versions of macOS print 1435 // ld: warning: option -s is obsolete and being ignored 1436 // so do not pass any arguments (but we strip symbols below). 1437 } else { 1438 argv = append(argv, "-s") 1439 } 1440 } 1441 1442 // On darwin, whether to combine DWARF into executable. 1443 // Only macOS supports unmapped segments such as our __DWARF segment. 1444 combineDwarf := ctxt.IsDarwin() && !*FlagW && machoPlatform == PLATFORM_MACOS 1445 1446 switch ctxt.HeadType { 1447 case objabi.Hdarwin: 1448 if combineDwarf { 1449 // Leave room for DWARF combining. 1450 // -headerpad is incompatible with -fembed-bitcode. 1451 argv = append(argv, "-Wl,-headerpad,1144") 1452 } 1453 if ctxt.DynlinkingGo() && buildcfg.GOOS != "ios" { 1454 // -flat_namespace is deprecated on iOS. 1455 // It is useful for supporting plugins. We don't support plugins on iOS. 1456 // -flat_namespace may cause the dynamic linker to hang at forkExec when 1457 // resolving a lazy binding. See issue 38824. 1458 // Force eager resolution to work around. 1459 argv = append(argv, "-Wl,-flat_namespace", "-Wl,-bind_at_load") 1460 } 1461 if !combineDwarf { 1462 argv = append(argv, "-Wl,-S") // suppress STAB (symbolic debugging) symbols 1463 if debug_s { 1464 // We are generating a binary with symbol table suppressed. 1465 // Suppress local symbols. We need to keep dynamically exported 1466 // and referenced symbols so the dynamic linker can resolve them. 1467 argv = append(argv, "-Wl,-x") 1468 } 1469 } 1470 case objabi.Hopenbsd: 1471 argv = append(argv, "-pthread") 1472 if ctxt.BuildMode != BuildModePIE { 1473 argv = append(argv, "-Wl,-nopie") 1474 } 1475 if linkerFlagSupported(ctxt.Arch, argv[0], "", "-Wl,-z,nobtcfi") { 1476 // -Wl,-z,nobtcfi is only supported on OpenBSD 7.4+, remove guard 1477 // when OpenBSD 7.5 is released and 7.3 is no longer supported. 1478 argv = append(argv, "-Wl,-z,nobtcfi") 1479 } 1480 if ctxt.Arch.InFamily(sys.ARM64) { 1481 // Disable execute-only on openbsd/arm64 - the Go arm64 assembler 1482 // currently stores constants in the text section rather than in rodata. 1483 // See issue #59615. 1484 argv = append(argv, "-Wl,--no-execute-only") 1485 } 1486 case objabi.Hwindows: 1487 if windowsgui { 1488 argv = append(argv, "-mwindows") 1489 } else { 1490 argv = append(argv, "-mconsole") 1491 } 1492 // Mark as having awareness of terminal services, to avoid 1493 // ancient compatibility hacks. 1494 argv = append(argv, "-Wl,--tsaware") 1495 1496 // Enable DEP 1497 argv = append(argv, "-Wl,--nxcompat") 1498 1499 argv = append(argv, fmt.Sprintf("-Wl,--major-os-version=%d", PeMinimumTargetMajorVersion)) 1500 argv = append(argv, fmt.Sprintf("-Wl,--minor-os-version=%d", PeMinimumTargetMinorVersion)) 1501 argv = append(argv, fmt.Sprintf("-Wl,--major-subsystem-version=%d", PeMinimumTargetMajorVersion)) 1502 argv = append(argv, fmt.Sprintf("-Wl,--minor-subsystem-version=%d", PeMinimumTargetMinorVersion)) 1503 case objabi.Haix: 1504 argv = append(argv, "-pthread") 1505 // prevent ld to reorder .text functions to keep the same 1506 // first/last functions for moduledata. 1507 argv = append(argv, "-Wl,-bnoobjreorder") 1508 // mcmodel=large is needed for every gcc generated files, but 1509 // ld still need -bbigtoc in order to allow larger TOC. 1510 argv = append(argv, "-mcmodel=large") 1511 argv = append(argv, "-Wl,-bbigtoc") 1512 } 1513 1514 // On PPC64, verify the external toolchain supports Power10. This is needed when 1515 // PC relative relocations might be generated by Go. Only targets compiling ELF 1516 // binaries might generate these relocations. 1517 if ctxt.IsPPC64() && ctxt.IsElf() && buildcfg.GOPPC64 >= 10 { 1518 if !linkerFlagSupported(ctxt.Arch, argv[0], "", "-mcpu=power10") { 1519 Exitf("The external toolchain does not support -mcpu=power10. " + 1520 " This is required to externally link GOPPC64 >= power10") 1521 } 1522 } 1523 1524 // Enable/disable ASLR on Windows. 1525 addASLRargs := func(argv []string, val bool) []string { 1526 // Old/ancient versions of GCC support "--dynamicbase" and 1527 // "--high-entropy-va" but don't enable it by default. In 1528 // addition, they don't accept "--disable-dynamicbase" or 1529 // "--no-dynamicbase", so the only way to disable ASLR is to 1530 // not pass any flags at all. 1531 // 1532 // More modern versions of GCC (and also clang) enable ASLR 1533 // by default. With these compilers, however you can turn it 1534 // off if you want using "--disable-dynamicbase" or 1535 // "--no-dynamicbase". 1536 // 1537 // The strategy below is to try using "--disable-dynamicbase"; 1538 // if this succeeds, then assume we're working with more 1539 // modern compilers and act accordingly. If it fails, assume 1540 // an ancient compiler with ancient defaults. 1541 var dbopt string 1542 var heopt string 1543 dbon := "--dynamicbase" 1544 heon := "--high-entropy-va" 1545 dboff := "--disable-dynamicbase" 1546 heoff := "--disable-high-entropy-va" 1547 if val { 1548 dbopt = dbon 1549 heopt = heon 1550 } else { 1551 // Test to see whether "--disable-dynamicbase" works. 1552 newer := linkerFlagSupported(ctxt.Arch, argv[0], "", "-Wl,"+dboff) 1553 if newer { 1554 // Newer compiler, which supports both on/off options. 1555 dbopt = dboff 1556 heopt = heoff 1557 } else { 1558 // older toolchain: we have to say nothing in order to 1559 // get a no-ASLR binary. 1560 dbopt = "" 1561 heopt = "" 1562 } 1563 } 1564 if dbopt != "" { 1565 argv = append(argv, "-Wl,"+dbopt) 1566 } 1567 // enable high-entropy ASLR on 64-bit. 1568 if ctxt.Arch.PtrSize >= 8 && heopt != "" { 1569 argv = append(argv, "-Wl,"+heopt) 1570 } 1571 return argv 1572 } 1573 1574 switch ctxt.BuildMode { 1575 case BuildModeExe: 1576 if ctxt.HeadType == objabi.Hdarwin { 1577 if machoPlatform == PLATFORM_MACOS && ctxt.IsAMD64() { 1578 argv = append(argv, "-Wl,-no_pie") 1579 } 1580 } 1581 if *flagRace && ctxt.HeadType == objabi.Hwindows { 1582 // Current windows/amd64 race detector tsan support 1583 // library can't handle PIE mode (see #53539 for more details). 1584 // For now, explicitly disable PIE (since some compilers 1585 // default to it) if -race is in effect. 1586 argv = addASLRargs(argv, false) 1587 } 1588 case BuildModePIE: 1589 switch ctxt.HeadType { 1590 case objabi.Hdarwin, objabi.Haix: 1591 case objabi.Hwindows: 1592 if *flagAslr && *flagRace { 1593 // Current windows/amd64 race detector tsan support 1594 // library can't handle PIE mode (see #53539 for more details). 1595 // Disable alsr if -race in effect. 1596 *flagAslr = false 1597 } 1598 argv = addASLRargs(argv, *flagAslr) 1599 default: 1600 // ELF. 1601 if ctxt.UseRelro() { 1602 argv = append(argv, "-Wl,-z,relro") 1603 } 1604 argv = append(argv, "-pie") 1605 } 1606 case BuildModeCShared: 1607 if ctxt.HeadType == objabi.Hdarwin { 1608 argv = append(argv, "-dynamiclib") 1609 } else { 1610 if ctxt.UseRelro() { 1611 argv = append(argv, "-Wl,-z,relro") 1612 } 1613 argv = append(argv, "-shared") 1614 if ctxt.HeadType == objabi.Hwindows { 1615 argv = addASLRargs(argv, *flagAslr) 1616 } else { 1617 // Pass -z nodelete to mark the shared library as 1618 // non-closeable: a dlclose will do nothing. 1619 argv = append(argv, "-Wl,-z,nodelete") 1620 // Only pass Bsymbolic on non-Windows. 1621 argv = append(argv, "-Wl,-Bsymbolic") 1622 } 1623 } 1624 case BuildModeShared: 1625 if ctxt.UseRelro() { 1626 argv = append(argv, "-Wl,-z,relro") 1627 } 1628 argv = append(argv, "-shared") 1629 case BuildModePlugin: 1630 if ctxt.HeadType == objabi.Hdarwin { 1631 argv = append(argv, "-dynamiclib") 1632 } else { 1633 if ctxt.UseRelro() { 1634 argv = append(argv, "-Wl,-z,relro") 1635 } 1636 argv = append(argv, "-shared") 1637 } 1638 } 1639 1640 var altLinker string 1641 if ctxt.IsELF && (ctxt.DynlinkingGo() || *flagBindNow) { 1642 // For ELF targets, when producing dynamically linked Go code 1643 // or when immediate binding is explicitly requested, 1644 // we force all symbol resolution to be done at program startup 1645 // because lazy PLT resolution can use large amounts of stack at 1646 // times we cannot allow it to do so. 1647 argv = append(argv, "-Wl,-z,now") 1648 } 1649 1650 if ctxt.IsELF && ctxt.DynlinkingGo() { 1651 // Do not let the host linker generate COPY relocations. These 1652 // can move symbols out of sections that rely on stable offsets 1653 // from the beginning of the section (like sym.STYPE). 1654 argv = append(argv, "-Wl,-z,nocopyreloc") 1655 1656 if buildcfg.GOOS == "android" { 1657 // Use lld to avoid errors from default linker (issue #38838) 1658 altLinker = "lld" 1659 } 1660 1661 if ctxt.Arch.InFamily(sys.ARM64) && buildcfg.GOOS == "linux" { 1662 // On ARM64, the GNU linker will fail with 1663 // -znocopyreloc if it thinks a COPY relocation is 1664 // required. Switch to gold. 1665 // https://sourceware.org/bugzilla/show_bug.cgi?id=19962 1666 // https://go.dev/issue/22040 1667 altLinker = "gold" 1668 1669 // If gold is not installed, gcc will silently switch 1670 // back to ld.bfd. So we parse the version information 1671 // and provide a useful error if gold is missing. 1672 name, args := flagExtld[0], flagExtld[1:] 1673 args = append(args, "-fuse-ld=gold", "-Wl,--version") 1674 cmd := exec.Command(name, args...) 1675 if out, err := cmd.CombinedOutput(); err == nil { 1676 if !bytes.Contains(out, []byte("GNU gold")) { 1677 log.Fatalf("ARM64 external linker must be gold (issue #15696, 22040), but is not: %s", out) 1678 } 1679 } 1680 } 1681 } 1682 if ctxt.Arch.Family == sys.ARM64 && buildcfg.GOOS == "freebsd" { 1683 // Switch to ld.bfd on freebsd/arm64. 1684 altLinker = "bfd" 1685 1686 // Provide a useful error if ld.bfd is missing. 1687 name, args := flagExtld[0], flagExtld[1:] 1688 args = append(args, "-fuse-ld=bfd", "-Wl,--version") 1689 cmd := exec.Command(name, args...) 1690 if out, err := cmd.CombinedOutput(); err == nil { 1691 if !bytes.Contains(out, []byte("GNU ld")) { 1692 log.Fatalf("ARM64 external linker must be ld.bfd (issue #35197), please install devel/binutils") 1693 } 1694 } 1695 } 1696 if altLinker != "" { 1697 argv = append(argv, "-fuse-ld="+altLinker) 1698 } 1699 1700 if ctxt.IsELF && len(buildinfo) > 0 { 1701 argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo)) 1702 } 1703 1704 // On Windows, given -o foo, GCC will append ".exe" to produce 1705 // "foo.exe". We have decided that we want to honor the -o 1706 // option. To make this work, we append a '.' so that GCC 1707 // will decide that the file already has an extension. We 1708 // only want to do this when producing a Windows output file 1709 // on a Windows host. 1710 outopt := *flagOutfile 1711 if buildcfg.GOOS == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" { 1712 outopt += "." 1713 } 1714 argv = append(argv, "-o") 1715 argv = append(argv, outopt) 1716 1717 if rpath.val != "" { 1718 argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val)) 1719 } 1720 1721 if *flagInterpreter != "" { 1722 // Many linkers support both -I and the --dynamic-linker flags 1723 // to set the ELF interpreter, but lld only supports 1724 // --dynamic-linker so prefer that (ld on very old Solaris only 1725 // supports -I but that seems less important). 1726 argv = append(argv, fmt.Sprintf("-Wl,--dynamic-linker,%s", *flagInterpreter)) 1727 } 1728 1729 // Force global symbols to be exported for dlopen, etc. 1730 if ctxt.IsELF { 1731 if ctxt.DynlinkingGo() || ctxt.BuildMode == BuildModeCShared || !linkerFlagSupported(ctxt.Arch, argv[0], altLinker, "-Wl,--export-dynamic-symbol=main") { 1732 argv = append(argv, "-rdynamic") 1733 } else { 1734 var exports []string 1735 ctxt.loader.ForAllCgoExportDynamic(func(s loader.Sym) { 1736 exports = append(exports, "-Wl,--export-dynamic-symbol="+ctxt.loader.SymExtname(s)) 1737 }) 1738 sort.Strings(exports) 1739 argv = append(argv, exports...) 1740 } 1741 } 1742 if ctxt.HeadType == objabi.Haix { 1743 fileName := xcoffCreateExportFile(ctxt) 1744 argv = append(argv, "-Wl,-bE:"+fileName) 1745 } 1746 1747 const unusedArguments = "-Qunused-arguments" 1748 if linkerFlagSupported(ctxt.Arch, argv[0], altLinker, unusedArguments) { 1749 argv = append(argv, unusedArguments) 1750 } 1751 1752 if ctxt.IsWindows() { 1753 // Suppress generation of the PE file header timestamp, 1754 // so as to avoid spurious build ID differences between 1755 // linked binaries that are otherwise identical other than 1756 // the date/time they were linked. 1757 const noTimeStamp = "-Wl,--no-insert-timestamp" 1758 if linkerFlagSupported(ctxt.Arch, argv[0], altLinker, noTimeStamp) { 1759 argv = append(argv, noTimeStamp) 1760 } 1761 } 1762 1763 const compressDWARF = "-Wl,--compress-debug-sections=zlib" 1764 if ctxt.compressDWARF && linkerFlagSupported(ctxt.Arch, argv[0], altLinker, compressDWARF) { 1765 argv = append(argv, compressDWARF) 1766 } 1767 1768 hostObjCopyPaths := ctxt.hostobjCopy() 1769 cleanTimeStamps(hostObjCopyPaths) 1770 godotopath := filepath.Join(*flagTmpdir, "go.o") 1771 cleanTimeStamps([]string{godotopath}) 1772 1773 argv = append(argv, godotopath) 1774 argv = append(argv, hostObjCopyPaths...) 1775 if ctxt.HeadType == objabi.Haix { 1776 // We want to have C files after Go files to remove 1777 // trampolines csects made by ld. 1778 argv = append(argv, "-nostartfiles") 1779 argv = append(argv, "/lib/crt0_64.o") 1780 1781 extld := ctxt.extld() 1782 name, args := extld[0], extld[1:] 1783 // Get starting files. 1784 getPathFile := func(file string) string { 1785 args := append(args, "-maix64", "--print-file-name="+file) 1786 out, err := exec.Command(name, args...).CombinedOutput() 1787 if err != nil { 1788 log.Fatalf("running %s failed: %v\n%s", extld, err, out) 1789 } 1790 return strings.Trim(string(out), "\n") 1791 } 1792 // Since GCC version 11, the 64-bit version of GCC starting files 1793 // are now suffixed by "_64". Even under "-maix64" multilib directory 1794 // "crtcxa.o" is 32-bit. 1795 crtcxa := getPathFile("crtcxa_64.o") 1796 if !filepath.IsAbs(crtcxa) { 1797 crtcxa = getPathFile("crtcxa.o") 1798 } 1799 crtdbase := getPathFile("crtdbase_64.o") 1800 if !filepath.IsAbs(crtdbase) { 1801 crtdbase = getPathFile("crtdbase.o") 1802 } 1803 argv = append(argv, crtcxa) 1804 argv = append(argv, crtdbase) 1805 } 1806 1807 if ctxt.linkShared { 1808 seenDirs := make(map[string]bool) 1809 seenLibs := make(map[string]bool) 1810 addshlib := func(path string) { 1811 dir, base := filepath.Split(path) 1812 if !seenDirs[dir] { 1813 argv = append(argv, "-L"+dir) 1814 if !rpath.set { 1815 argv = append(argv, "-Wl,-rpath="+dir) 1816 } 1817 seenDirs[dir] = true 1818 } 1819 base = strings.TrimSuffix(base, ".so") 1820 base = strings.TrimPrefix(base, "lib") 1821 if !seenLibs[base] { 1822 argv = append(argv, "-l"+base) 1823 seenLibs[base] = true 1824 } 1825 } 1826 for _, shlib := range ctxt.Shlibs { 1827 addshlib(shlib.Path) 1828 for _, dep := range shlib.Deps { 1829 if dep == "" { 1830 continue 1831 } 1832 libpath := findshlib(ctxt, dep) 1833 if libpath != "" { 1834 addshlib(libpath) 1835 } 1836 } 1837 } 1838 } 1839 1840 // clang, unlike GCC, passes -rdynamic to the linker 1841 // even when linking with -static, causing a linker 1842 // error when using GNU ld. So take out -rdynamic if 1843 // we added it. We do it in this order, rather than 1844 // only adding -rdynamic later, so that -extldflags 1845 // can override -rdynamic without using -static. 1846 // Similarly for -Wl,--dynamic-linker. 1847 checkStatic := func(arg string) { 1848 if ctxt.IsELF && arg == "-static" { 1849 for i := range argv { 1850 if argv[i] == "-rdynamic" || strings.HasPrefix(argv[i], "-Wl,--dynamic-linker,") { 1851 argv[i] = "-static" 1852 } 1853 } 1854 } 1855 } 1856 1857 for _, p := range ldflag { 1858 argv = append(argv, p) 1859 checkStatic(p) 1860 } 1861 1862 // When building a program with the default -buildmode=exe the 1863 // gc compiler generates code requires DT_TEXTREL in a 1864 // position independent executable (PIE). On systems where the 1865 // toolchain creates PIEs by default, and where DT_TEXTREL 1866 // does not work, the resulting programs will not run. See 1867 // issue #17847. To avoid this problem pass -no-pie to the 1868 // toolchain if it is supported. 1869 if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared && !(ctxt.IsDarwin() && ctxt.IsARM64()) { 1870 // GCC uses -no-pie, clang uses -nopie. 1871 for _, nopie := range []string{"-no-pie", "-nopie"} { 1872 if linkerFlagSupported(ctxt.Arch, argv[0], altLinker, nopie) { 1873 argv = append(argv, nopie) 1874 break 1875 } 1876 } 1877 } 1878 1879 for _, p := range flagExtldflags { 1880 argv = append(argv, p) 1881 checkStatic(p) 1882 } 1883 if ctxt.HeadType == objabi.Hwindows { 1884 // Determine which linker we're using. Add in the extldflags in 1885 // case used has specified "-fuse-ld=...". 1886 extld := ctxt.extld() 1887 name, args := extld[0], extld[1:] 1888 args = append(args, trimLinkerArgv(flagExtldflags)...) 1889 args = append(args, "-Wl,--version") 1890 cmd := exec.Command(name, args...) 1891 usingLLD := false 1892 if out, err := cmd.CombinedOutput(); err == nil { 1893 if bytes.Contains(out, []byte("LLD ")) { 1894 usingLLD = true 1895 } 1896 } 1897 1898 // use gcc linker script to work around gcc bug 1899 // (see https://golang.org/issue/20183 for details). 1900 if !usingLLD { 1901 p := writeGDBLinkerScript() 1902 argv = append(argv, "-Wl,-T,"+p) 1903 } 1904 if *flagRace { 1905 if p := ctxt.findLibPath("libsynchronization.a"); p != "libsynchronization.a" { 1906 argv = append(argv, "-lsynchronization") 1907 } 1908 } 1909 // libmingw32 and libmingwex have some inter-dependencies, 1910 // so must use linker groups. 1911 argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group") 1912 argv = append(argv, peimporteddlls()...) 1913 } 1914 1915 argv = ctxt.passLongArgsInResponseFile(argv, altLinker) 1916 1917 if ctxt.Debugvlog != 0 { 1918 ctxt.Logf("host link:") 1919 for _, v := range argv { 1920 ctxt.Logf(" %q", v) 1921 } 1922 ctxt.Logf("\n") 1923 } 1924 1925 cmd := exec.Command(argv[0], argv[1:]...) 1926 out, err := cmd.CombinedOutput() 1927 if err != nil { 1928 Exitf("running %s failed: %v\n%s\n%s", argv[0], err, cmd, out) 1929 } 1930 1931 // Filter out useless linker warnings caused by bugs outside Go. 1932 // See also cmd/go/internal/work/exec.go's gccld method. 1933 var save [][]byte 1934 var skipLines int 1935 for _, line := range bytes.SplitAfter(out, []byte("\n")) { 1936 // golang.org/issue/26073 - Apple Xcode bug 1937 if bytes.Contains(line, []byte("ld: warning: text-based stub file")) { 1938 continue 1939 } 1940 1941 if skipLines > 0 { 1942 skipLines-- 1943 continue 1944 } 1945 1946 // Remove TOC overflow warning on AIX. 1947 if bytes.Contains(line, []byte("ld: 0711-783")) { 1948 skipLines = 2 1949 continue 1950 } 1951 1952 save = append(save, line) 1953 } 1954 out = bytes.Join(save, nil) 1955 1956 if len(out) > 0 { 1957 // always print external output even if the command is successful, so that we don't 1958 // swallow linker warnings (see https://golang.org/issue/17935). 1959 if ctxt.IsDarwin() && ctxt.IsAMD64() { 1960 const noPieWarning = "ld: warning: -no_pie is deprecated when targeting new OS versions\n" 1961 if i := bytes.Index(out, []byte(noPieWarning)); i >= 0 { 1962 // swallow -no_pie deprecation warning, issue 54482 1963 out = append(out[:i], out[i+len(noPieWarning):]...) 1964 } 1965 } 1966 if ctxt.IsDarwin() { 1967 const bindAtLoadWarning = "ld: warning: -bind_at_load is deprecated on macOS\n" 1968 if i := bytes.Index(out, []byte(bindAtLoadWarning)); i >= 0 { 1969 // -bind_at_load is deprecated with ld-prime, but needed for 1970 // correctness with older versions of ld64. Swallow the warning. 1971 // TODO: maybe pass -bind_at_load conditionally based on C 1972 // linker version. 1973 out = append(out[:i], out[i+len(bindAtLoadWarning):]...) 1974 } 1975 } 1976 ctxt.Logf("%s", out) 1977 } 1978 1979 // Helper for updating a Macho binary in some way (shared between 1980 // dwarf combining and UUID update). 1981 updateMachoOutFile := func(op string, updateFunc machoUpdateFunc) { 1982 // For os.Rename to work reliably, must be in same directory as outfile. 1983 rewrittenOutput := *flagOutfile + "~" 1984 exef, err := os.Open(*flagOutfile) 1985 if err != nil { 1986 Exitf("%s: %s failed: %v", os.Args[0], op, err) 1987 } 1988 defer exef.Close() 1989 exem, err := macho.NewFile(exef) 1990 if err != nil { 1991 Exitf("%s: parsing Mach-O header failed: %v", os.Args[0], err) 1992 } 1993 if err := updateFunc(ctxt, exef, exem, rewrittenOutput); err != nil { 1994 Exitf("%s: %s failed: %v", os.Args[0], op, err) 1995 } 1996 os.Remove(*flagOutfile) 1997 if err := os.Rename(rewrittenOutput, *flagOutfile); err != nil { 1998 Exitf("%s: %v", os.Args[0], err) 1999 } 2000 } 2001 2002 uuidUpdated := false 2003 if combineDwarf { 2004 // Find "dsymutils" and "strip" tools using CC --print-prog-name. 2005 dsymutilCmd := ctxt.findExtLinkTool("dsymutil") 2006 stripCmd := ctxt.findExtLinkTool("strip") 2007 2008 dsym := filepath.Join(*flagTmpdir, "go.dwarf") 2009 cmd := exec.Command(dsymutilCmd, "-f", *flagOutfile, "-o", dsym) 2010 // dsymutil may not clean up its temp directory at exit. 2011 // Set DSYMUTIL_REPRODUCER_PATH to work around. see issue 59026. 2012 // dsymutil (Apple LLVM version 16.0.0) deletes the directory 2013 // even if it is not empty. We still need our tmpdir, so give a 2014 // subdirectory to dsymutil. 2015 dsymDir := filepath.Join(*flagTmpdir, "dsymutil") 2016 err := os.MkdirAll(dsymDir, 0777) 2017 if err != nil { 2018 Exitf("fail to create temp dir: %v", err) 2019 } 2020 cmd.Env = append(os.Environ(), "DSYMUTIL_REPRODUCER_PATH="+dsymDir) 2021 if ctxt.Debugvlog != 0 { 2022 ctxt.Logf("host link dsymutil:") 2023 for _, v := range cmd.Args { 2024 ctxt.Logf(" %q", v) 2025 } 2026 ctxt.Logf("\n") 2027 } 2028 if out, err := cmd.CombinedOutput(); err != nil { 2029 Exitf("%s: running dsymutil failed: %v\n%s\n%s", os.Args[0], err, cmd, out) 2030 } 2031 // Remove STAB (symbolic debugging) symbols after we are done with them (by dsymutil). 2032 // They contain temporary file paths and make the build not reproducible. 2033 var stripArgs = []string{"-S"} 2034 if debug_s { 2035 // We are generating a binary with symbol table suppressed. 2036 // Suppress local symbols. We need to keep dynamically exported 2037 // and referenced symbols so the dynamic linker can resolve them. 2038 stripArgs = append(stripArgs, "-x") 2039 } 2040 stripArgs = append(stripArgs, *flagOutfile) 2041 if ctxt.Debugvlog != 0 { 2042 ctxt.Logf("host link strip: %q", stripCmd) 2043 for _, v := range stripArgs { 2044 ctxt.Logf(" %q", v) 2045 } 2046 ctxt.Logf("\n") 2047 } 2048 cmd = exec.Command(stripCmd, stripArgs...) 2049 if out, err := cmd.CombinedOutput(); err != nil { 2050 Exitf("%s: running strip failed: %v\n%s\n%s", os.Args[0], err, cmd, out) 2051 } 2052 // Skip combining if `dsymutil` didn't generate a file. See #11994. 2053 if _, err := os.Stat(dsym); err == nil { 2054 updateMachoOutFile("combining dwarf", 2055 func(ctxt *Link, exef *os.File, exem *macho.File, outexe string) error { 2056 return machoCombineDwarf(ctxt, exef, exem, dsym, outexe) 2057 }) 2058 uuidUpdated = true 2059 } 2060 } 2061 if ctxt.IsDarwin() && !uuidUpdated && *flagBuildid != "" { 2062 updateMachoOutFile("rewriting uuid", 2063 func(ctxt *Link, exef *os.File, exem *macho.File, outexe string) error { 2064 return machoRewriteUuid(ctxt, exef, exem, outexe) 2065 }) 2066 } 2067 if ctxt.NeedCodeSign() { 2068 err := machoCodeSign(ctxt, *flagOutfile) 2069 if err != nil { 2070 Exitf("%s: code signing failed: %v", os.Args[0], err) 2071 } 2072 } 2073} 2074 2075// passLongArgsInResponseFile writes the arguments into a file if they 2076// are very long. 2077func (ctxt *Link) passLongArgsInResponseFile(argv []string, altLinker string) []string { 2078 c := 0 2079 for _, arg := range argv { 2080 c += len(arg) 2081 } 2082 2083 if c < sys.ExecArgLengthLimit { 2084 return argv 2085 } 2086 2087 // Only use response files if they are supported. 2088 response := filepath.Join(*flagTmpdir, "response") 2089 if err := os.WriteFile(response, nil, 0644); err != nil { 2090 log.Fatalf("failed while testing response file: %v", err) 2091 } 2092 if !linkerFlagSupported(ctxt.Arch, argv[0], altLinker, "@"+response) { 2093 if ctxt.Debugvlog != 0 { 2094 ctxt.Logf("not using response file because linker does not support one") 2095 } 2096 return argv 2097 } 2098 2099 var buf bytes.Buffer 2100 for _, arg := range argv[1:] { 2101 // The external linker response file supports quoted strings. 2102 fmt.Fprintf(&buf, "%q\n", arg) 2103 } 2104 if err := os.WriteFile(response, buf.Bytes(), 0644); err != nil { 2105 log.Fatalf("failed while writing response file: %v", err) 2106 } 2107 if ctxt.Debugvlog != 0 { 2108 ctxt.Logf("response file %s contents:\n%s", response, buf.Bytes()) 2109 } 2110 return []string{ 2111 argv[0], 2112 "@" + response, 2113 } 2114} 2115 2116var createTrivialCOnce sync.Once 2117 2118func linkerFlagSupported(arch *sys.Arch, linker, altLinker, flag string) bool { 2119 createTrivialCOnce.Do(func() { 2120 src := filepath.Join(*flagTmpdir, "trivial.c") 2121 if err := os.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil { 2122 Errorf(nil, "WriteFile trivial.c failed: %v", err) 2123 } 2124 }) 2125 2126 flags := hostlinkArchArgs(arch) 2127 2128 moreFlags := trimLinkerArgv(append(flagExtldflags, ldflag...)) 2129 flags = append(flags, moreFlags...) 2130 2131 if altLinker != "" { 2132 flags = append(flags, "-fuse-ld="+altLinker) 2133 } 2134 trivialPath := filepath.Join(*flagTmpdir, "trivial.c") 2135 outPath := filepath.Join(*flagTmpdir, "a.out") 2136 flags = append(flags, "-o", outPath, flag, trivialPath) 2137 2138 cmd := exec.Command(linker, flags...) 2139 cmd.Env = append([]string{"LC_ALL=C"}, os.Environ()...) 2140 out, err := cmd.CombinedOutput() 2141 // GCC says "unrecognized command line option ‘-no-pie’" 2142 // clang says "unknown argument: '-no-pie'" 2143 return err == nil && !bytes.Contains(out, []byte("unrecognized")) && !bytes.Contains(out, []byte("unknown")) 2144} 2145 2146// trimLinkerArgv returns a new copy of argv that does not include flags 2147// that are not relevant for testing whether some linker option works. 2148func trimLinkerArgv(argv []string) []string { 2149 flagsWithNextArgSkip := []string{ 2150 "-F", 2151 "-l", 2152 "-L", 2153 "-framework", 2154 "-Wl,-framework", 2155 "-Wl,-rpath", 2156 "-Wl,-undefined", 2157 } 2158 flagsWithNextArgKeep := []string{ 2159 "-arch", 2160 "-isysroot", 2161 "--sysroot", 2162 "-target", 2163 } 2164 prefixesToKeep := []string{ 2165 "-f", 2166 "-m", 2167 "-p", 2168 "-Wl,", 2169 "-arch", 2170 "-isysroot", 2171 "--sysroot", 2172 "-target", 2173 } 2174 2175 var flags []string 2176 keep := false 2177 skip := false 2178 for _, f := range argv { 2179 if keep { 2180 flags = append(flags, f) 2181 keep = false 2182 } else if skip { 2183 skip = false 2184 } else if f == "" || f[0] != '-' { 2185 } else if contains(flagsWithNextArgSkip, f) { 2186 skip = true 2187 } else if contains(flagsWithNextArgKeep, f) { 2188 flags = append(flags, f) 2189 keep = true 2190 } else { 2191 for _, p := range prefixesToKeep { 2192 if strings.HasPrefix(f, p) { 2193 flags = append(flags, f) 2194 break 2195 } 2196 } 2197 } 2198 } 2199 return flags 2200} 2201 2202// hostlinkArchArgs returns arguments to pass to the external linker 2203// based on the architecture. 2204func hostlinkArchArgs(arch *sys.Arch) []string { 2205 switch arch.Family { 2206 case sys.I386: 2207 return []string{"-m32"} 2208 case sys.AMD64: 2209 if buildcfg.GOOS == "darwin" { 2210 return []string{"-arch", "x86_64", "-m64"} 2211 } 2212 return []string{"-m64"} 2213 case sys.S390X: 2214 return []string{"-m64"} 2215 case sys.ARM: 2216 return []string{"-marm"} 2217 case sys.ARM64: 2218 if buildcfg.GOOS == "darwin" { 2219 return []string{"-arch", "arm64"} 2220 } 2221 case sys.Loong64: 2222 return []string{"-mabi=lp64d"} 2223 case sys.MIPS64: 2224 return []string{"-mabi=64"} 2225 case sys.MIPS: 2226 return []string{"-mabi=32"} 2227 case sys.PPC64: 2228 if buildcfg.GOOS == "aix" { 2229 return []string{"-maix64"} 2230 } else { 2231 return []string{"-m64"} 2232 } 2233 2234 } 2235 return nil 2236} 2237 2238var wantHdr = objabi.HeaderString() 2239 2240// ldobj loads an input object. If it is a host object (an object 2241// compiled by a non-Go compiler) it returns the Hostobj pointer. If 2242// it is a Go object, it returns nil. 2243func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, file string) *Hostobj { 2244 pkg := objabi.PathToPrefix(lib.Pkg) 2245 2246 eof := f.Offset() + length 2247 start := f.Offset() 2248 c1 := bgetc(f) 2249 c2 := bgetc(f) 2250 c3 := bgetc(f) 2251 c4 := bgetc(f) 2252 f.MustSeek(start, 0) 2253 2254 unit := &sym.CompilationUnit{Lib: lib} 2255 lib.Units = append(lib.Units, unit) 2256 2257 magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4) 2258 if magic == 0x7f454c46 { // \x7F E L F 2259 ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { 2260 textp, flags, err := loadelf.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn, ehdr.Flags) 2261 if err != nil { 2262 Errorf(nil, "%v", err) 2263 return 2264 } 2265 ehdr.Flags = flags 2266 ctxt.Textp = append(ctxt.Textp, textp...) 2267 } 2268 return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file) 2269 } 2270 2271 if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe { 2272 ldmacho := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { 2273 textp, err := loadmacho.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn) 2274 if err != nil { 2275 Errorf(nil, "%v", err) 2276 return 2277 } 2278 ctxt.Textp = append(ctxt.Textp, textp...) 2279 } 2280 return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file) 2281 } 2282 2283 switch c1<<8 | c2 { 2284 case 0x4c01, // 386 2285 0x6486, // amd64 2286 0xc401, // arm 2287 0x64aa: // arm64 2288 ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { 2289 ls, err := loadpe.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn) 2290 if err != nil { 2291 Errorf(nil, "%v", err) 2292 return 2293 } 2294 if len(ls.Resources) != 0 { 2295 setpersrc(ctxt, ls.Resources) 2296 } 2297 if ls.PData != 0 { 2298 sehp.pdata = append(sehp.pdata, ls.PData) 2299 } 2300 if ls.XData != 0 { 2301 sehp.xdata = append(sehp.xdata, ls.XData) 2302 } 2303 ctxt.Textp = append(ctxt.Textp, ls.Textp...) 2304 } 2305 return ldhostobj(ldpe, ctxt.HeadType, f, pkg, length, pn, file) 2306 } 2307 2308 if c1 == 0x01 && (c2 == 0xD7 || c2 == 0xF7) { 2309 ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { 2310 textp, err := loadxcoff.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn) 2311 if err != nil { 2312 Errorf(nil, "%v", err) 2313 return 2314 } 2315 ctxt.Textp = append(ctxt.Textp, textp...) 2316 } 2317 return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file) 2318 } 2319 2320 if c1 != 'g' || c2 != 'o' || c3 != ' ' || c4 != 'o' { 2321 // An unrecognized object is just passed to the external linker. 2322 // If we try to read symbols from this object, we will 2323 // report an error at that time. 2324 unknownObjFormat = true 2325 return ldhostobj(nil, ctxt.HeadType, f, pkg, length, pn, file) 2326 } 2327 2328 /* check the header */ 2329 line, err := f.ReadString('\n') 2330 if err != nil { 2331 Errorf(nil, "truncated object file: %s: %v", pn, err) 2332 return nil 2333 } 2334 2335 if !strings.HasPrefix(line, "go object ") { 2336 if strings.HasSuffix(pn, ".go") { 2337 Exitf("%s: uncompiled .go source file", pn) 2338 return nil 2339 } 2340 2341 if line == ctxt.Arch.Name { 2342 // old header format: just $GOOS 2343 Errorf(nil, "%s: stale object file", pn) 2344 return nil 2345 } 2346 2347 Errorf(nil, "%s: not an object file: @%d %q", pn, start, line) 2348 return nil 2349 } 2350 2351 // First, check that the basic GOOS, GOARCH, and Version match. 2352 if line != wantHdr { 2353 Errorf(nil, "%s: linked object header mismatch:\nhave %q\nwant %q\n", pn, line, wantHdr) 2354 } 2355 2356 // Skip over exports and other info -- ends with \n!\n. 2357 // 2358 // Note: It's possible for "\n!\n" to appear within the binary 2359 // package export data format. To avoid truncating the package 2360 // definition prematurely (issue 21703), we keep track of 2361 // how many "$$" delimiters we've seen. 2362 2363 import0 := f.Offset() 2364 2365 c1 = '\n' // the last line ended in \n 2366 c2 = bgetc(f) 2367 c3 = bgetc(f) 2368 markers := 0 2369 for { 2370 if c1 == '\n' { 2371 if markers%2 == 0 && c2 == '!' && c3 == '\n' { 2372 break 2373 } 2374 if c2 == '$' && c3 == '$' { 2375 markers++ 2376 } 2377 } 2378 2379 c1 = c2 2380 c2 = c3 2381 c3 = bgetc(f) 2382 if c3 == -1 { 2383 Errorf(nil, "truncated object file: %s", pn) 2384 return nil 2385 } 2386 } 2387 2388 import1 := f.Offset() 2389 2390 f.MustSeek(import0, 0) 2391 ldpkg(ctxt, f, lib, import1-import0-2, pn) // -2 for !\n 2392 f.MustSeek(import1, 0) 2393 2394 fingerprint := ctxt.loader.Preload(ctxt.IncVersion(), f, lib, unit, eof-f.Offset()) 2395 if !fingerprint.IsZero() { // Assembly objects don't have fingerprints. Ignore them. 2396 // Check fingerprint, to ensure the importing and imported packages 2397 // have consistent view of symbol indices. 2398 // Normally the go command should ensure this. But in case something 2399 // goes wrong, it could lead to obscure bugs like run-time crash. 2400 // Check it here to be sure. 2401 if lib.Fingerprint.IsZero() { // Not yet imported. Update its fingerprint. 2402 lib.Fingerprint = fingerprint 2403 } 2404 checkFingerprint(lib, fingerprint, lib.Srcref, lib.Fingerprint) 2405 } 2406 2407 addImports(ctxt, lib, pn) 2408 return nil 2409} 2410 2411// symbolsAreUnresolved scans through the loader's list of unresolved 2412// symbols and checks to see whether any of them match the names of the 2413// symbols in 'want'. Return value is a list of bools, with list[K] set 2414// to true if there is an unresolved reference to the symbol in want[K]. 2415func symbolsAreUnresolved(ctxt *Link, want []string) []bool { 2416 returnAllUndefs := -1 2417 undefs, _ := ctxt.loader.UndefinedRelocTargets(returnAllUndefs) 2418 seen := make(map[loader.Sym]struct{}) 2419 rval := make([]bool, len(want)) 2420 wantm := make(map[string]int) 2421 for k, w := range want { 2422 wantm[w] = k 2423 } 2424 count := 0 2425 for _, s := range undefs { 2426 if _, ok := seen[s]; ok { 2427 continue 2428 } 2429 seen[s] = struct{}{} 2430 if k, ok := wantm[ctxt.loader.SymName(s)]; ok { 2431 rval[k] = true 2432 count++ 2433 if count == len(want) { 2434 return rval 2435 } 2436 } 2437 } 2438 return rval 2439} 2440 2441// hostObject reads a single host object file (compare to "hostArchive"). 2442// This is used as part of internal linking when we need to pull in 2443// files such as "crt?.o". 2444func hostObject(ctxt *Link, objname string, path string) { 2445 if ctxt.Debugvlog > 1 { 2446 ctxt.Logf("hostObject(%s)\n", path) 2447 } 2448 objlib := sym.Library{ 2449 Pkg: objname, 2450 } 2451 f, err := bio.Open(path) 2452 if err != nil { 2453 Exitf("cannot open host object %q file %s: %v", objname, path, err) 2454 } 2455 defer f.Close() 2456 h := ldobj(ctxt, f, &objlib, 0, path, path) 2457 if h.ld == nil { 2458 Exitf("unrecognized object file format in %s", path) 2459 } 2460 h.file = path 2461 h.length = f.MustSeek(0, 2) 2462 f.MustSeek(h.off, 0) 2463 h.ld(ctxt, f, h.pkg, h.length, h.pn) 2464 if *flagCaptureHostObjs != "" { 2465 captureHostObj(h) 2466 } 2467} 2468 2469func checkFingerprint(lib *sym.Library, libfp goobj.FingerprintType, src string, srcfp goobj.FingerprintType) { 2470 if libfp != srcfp { 2471 Exitf("fingerprint mismatch: %s has %x, import from %s expecting %x", lib, libfp, src, srcfp) 2472 } 2473} 2474 2475func readelfsymboldata(ctxt *Link, f *elf.File, sym *elf.Symbol) []byte { 2476 data := make([]byte, sym.Size) 2477 sect := f.Sections[sym.Section] 2478 if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE { 2479 Errorf(nil, "reading %s from non-data section", sym.Name) 2480 } 2481 n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr)) 2482 if uint64(n) != sym.Size { 2483 Errorf(nil, "reading contents of %s: %v", sym.Name, err) 2484 } 2485 return data 2486} 2487 2488func readwithpad(r io.Reader, sz int32) ([]byte, error) { 2489 data := make([]byte, Rnd(int64(sz), 4)) 2490 _, err := io.ReadFull(r, data) 2491 if err != nil { 2492 return nil, err 2493 } 2494 data = data[:sz] 2495 return data, nil 2496} 2497 2498func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) { 2499 for _, sect := range f.Sections { 2500 if sect.Type != elf.SHT_NOTE { 2501 continue 2502 } 2503 r := sect.Open() 2504 for { 2505 var namesize, descsize, noteType int32 2506 err := binary.Read(r, f.ByteOrder, &namesize) 2507 if err != nil { 2508 if err == io.EOF { 2509 break 2510 } 2511 return nil, fmt.Errorf("read namesize failed: %v", err) 2512 } 2513 err = binary.Read(r, f.ByteOrder, &descsize) 2514 if err != nil { 2515 return nil, fmt.Errorf("read descsize failed: %v", err) 2516 } 2517 err = binary.Read(r, f.ByteOrder, ¬eType) 2518 if err != nil { 2519 return nil, fmt.Errorf("read type failed: %v", err) 2520 } 2521 noteName, err := readwithpad(r, namesize) 2522 if err != nil { 2523 return nil, fmt.Errorf("read name failed: %v", err) 2524 } 2525 desc, err := readwithpad(r, descsize) 2526 if err != nil { 2527 return nil, fmt.Errorf("read desc failed: %v", err) 2528 } 2529 if string(name) == string(noteName) && typ == noteType { 2530 return desc, nil 2531 } 2532 } 2533 } 2534 return nil, nil 2535} 2536 2537func findshlib(ctxt *Link, shlib string) string { 2538 if filepath.IsAbs(shlib) { 2539 return shlib 2540 } 2541 for _, libdir := range ctxt.Libdir { 2542 libpath := filepath.Join(libdir, shlib) 2543 if _, err := os.Stat(libpath); err == nil { 2544 return libpath 2545 } 2546 } 2547 Errorf(nil, "cannot find shared library: %s", shlib) 2548 return "" 2549} 2550 2551func ldshlibsyms(ctxt *Link, shlib string) { 2552 var libpath string 2553 if filepath.IsAbs(shlib) { 2554 libpath = shlib 2555 shlib = filepath.Base(shlib) 2556 } else { 2557 libpath = findshlib(ctxt, shlib) 2558 if libpath == "" { 2559 return 2560 } 2561 } 2562 for _, processedlib := range ctxt.Shlibs { 2563 if processedlib.Path == libpath { 2564 return 2565 } 2566 } 2567 if ctxt.Debugvlog > 1 { 2568 ctxt.Logf("ldshlibsyms: found library with name %s at %s\n", shlib, libpath) 2569 } 2570 2571 f, err := elf.Open(libpath) 2572 if err != nil { 2573 Errorf(nil, "cannot open shared library: %s", libpath) 2574 return 2575 } 2576 // Keep the file open as decodetypeGcprog needs to read from it. 2577 // TODO: fix. Maybe mmap the file. 2578 //defer f.Close() 2579 2580 hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG) 2581 if err != nil { 2582 Errorf(nil, "cannot read ABI hash from shared library %s: %v", libpath, err) 2583 return 2584 } 2585 2586 depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG) 2587 if err != nil { 2588 Errorf(nil, "cannot read dep list from shared library %s: %v", libpath, err) 2589 return 2590 } 2591 var deps []string 2592 for _, dep := range strings.Split(string(depsbytes), "\n") { 2593 if dep == "" { 2594 continue 2595 } 2596 if !filepath.IsAbs(dep) { 2597 // If the dep can be interpreted as a path relative to the shlib 2598 // in which it was found, do that. Otherwise, we will leave it 2599 // to be resolved by libdir lookup. 2600 abs := filepath.Join(filepath.Dir(libpath), dep) 2601 if _, err := os.Stat(abs); err == nil { 2602 dep = abs 2603 } 2604 } 2605 deps = append(deps, dep) 2606 } 2607 2608 syms, err := f.DynamicSymbols() 2609 if err != nil { 2610 Errorf(nil, "cannot read symbols from shared library: %s", libpath) 2611 return 2612 } 2613 2614 for _, elfsym := range syms { 2615 if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION { 2616 continue 2617 } 2618 2619 // Symbols whose names start with "type:" are compiler generated, 2620 // so make functions with that prefix internal. 2621 ver := 0 2622 symname := elfsym.Name // (unmangled) symbol name 2623 if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type:") { 2624 ver = abiInternalVer 2625 } else if buildcfg.Experiment.RegabiWrappers && elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC { 2626 // Demangle the ABI name. Keep in sync with symtab.go:mangleABIName. 2627 if strings.HasSuffix(elfsym.Name, ".abiinternal") { 2628 ver = sym.SymVerABIInternal 2629 symname = strings.TrimSuffix(elfsym.Name, ".abiinternal") 2630 } else if strings.HasSuffix(elfsym.Name, ".abi0") { 2631 ver = 0 2632 symname = strings.TrimSuffix(elfsym.Name, ".abi0") 2633 } 2634 } 2635 2636 l := ctxt.loader 2637 s := l.LookupOrCreateSym(symname, ver) 2638 2639 // Because loadlib above loads all .a files before loading 2640 // any shared libraries, any non-dynimport symbols we find 2641 // that duplicate symbols already loaded should be ignored 2642 // (the symbols from the .a files "win"). 2643 if l.SymType(s) != 0 && l.SymType(s) != sym.SDYNIMPORT { 2644 continue 2645 } 2646 su := l.MakeSymbolUpdater(s) 2647 su.SetType(sym.SDYNIMPORT) 2648 l.SetSymElfType(s, elf.ST_TYPE(elfsym.Info)) 2649 su.SetSize(int64(elfsym.Size)) 2650 if elfsym.Section != elf.SHN_UNDEF { 2651 // Set .File for the library that actually defines the symbol. 2652 l.SetSymPkg(s, libpath) 2653 2654 // The decodetype_* functions in decodetype.go need access to 2655 // the type data. 2656 sname := l.SymName(s) 2657 if strings.HasPrefix(sname, "type:") && !strings.HasPrefix(sname, "type:.") { 2658 su.SetData(readelfsymboldata(ctxt, f, &elfsym)) 2659 } 2660 } 2661 2662 if symname != elfsym.Name { 2663 l.SetSymExtname(s, elfsym.Name) 2664 } 2665 } 2666 ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f}) 2667} 2668 2669func addsection(ldr *loader.Loader, arch *sys.Arch, seg *sym.Segment, name string, rwx int) *sym.Section { 2670 sect := ldr.NewSection() 2671 sect.Rwx = uint8(rwx) 2672 sect.Name = name 2673 sect.Seg = seg 2674 sect.Align = int32(arch.PtrSize) // everything is at least pointer-aligned 2675 seg.Sections = append(seg.Sections, sect) 2676 return sect 2677} 2678 2679func usage() { 2680 fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n") 2681 objabi.Flagprint(os.Stderr) 2682 Exit(2) 2683} 2684 2685type SymbolType int8 // TODO: after genasmsym is gone, maybe rename to plan9typeChar or something 2686 2687const ( 2688 // see also https://9p.io/magic/man2html/1/nm 2689 TextSym SymbolType = 'T' 2690 DataSym SymbolType = 'D' 2691 BSSSym SymbolType = 'B' 2692 UndefinedSym SymbolType = 'U' 2693 TLSSym SymbolType = 't' 2694 FrameSym SymbolType = 'm' 2695 ParamSym SymbolType = 'p' 2696 AutoSym SymbolType = 'a' 2697 2698 // Deleted auto (not a real sym, just placeholder for type) 2699 DeletedAutoSym = 'x' 2700) 2701 2702// defineInternal defines a symbol used internally by the go runtime. 2703func (ctxt *Link) defineInternal(p string, t sym.SymKind) loader.Sym { 2704 s := ctxt.loader.CreateSymForUpdate(p, 0) 2705 s.SetType(t) 2706 s.SetSpecial(true) 2707 s.SetLocal(true) 2708 return s.Sym() 2709} 2710 2711func (ctxt *Link) xdefine(p string, t sym.SymKind, v int64) loader.Sym { 2712 s := ctxt.defineInternal(p, t) 2713 ctxt.loader.SetSymValue(s, v) 2714 return s 2715} 2716 2717func datoff(ldr *loader.Loader, s loader.Sym, addr int64) int64 { 2718 if uint64(addr) >= Segdata.Vaddr { 2719 return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff) 2720 } 2721 if uint64(addr) >= Segtext.Vaddr { 2722 return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff) 2723 } 2724 ldr.Errorf(s, "invalid datoff %#x", addr) 2725 return 0 2726} 2727 2728func Entryvalue(ctxt *Link) int64 { 2729 a := *flagEntrySymbol 2730 if a[0] >= '0' && a[0] <= '9' { 2731 return atolwhex(a) 2732 } 2733 ldr := ctxt.loader 2734 s := ldr.Lookup(a, 0) 2735 if s == 0 { 2736 Errorf(nil, "missing entry symbol %q", a) 2737 return 0 2738 } 2739 st := ldr.SymType(s) 2740 if st == 0 { 2741 return *FlagTextAddr 2742 } 2743 if !ctxt.IsAIX() && st != sym.STEXT { 2744 ldr.Errorf(s, "entry not text") 2745 } 2746 return ldr.SymValue(s) 2747} 2748 2749func (ctxt *Link) callgraph() { 2750 if !*FlagC { 2751 return 2752 } 2753 2754 ldr := ctxt.loader 2755 for _, s := range ctxt.Textp { 2756 relocs := ldr.Relocs(s) 2757 for i := 0; i < relocs.Count(); i++ { 2758 r := relocs.At(i) 2759 rs := r.Sym() 2760 if rs == 0 { 2761 continue 2762 } 2763 if r.Type().IsDirectCall() && ldr.SymType(rs) == sym.STEXT { 2764 ctxt.Logf("%s calls %s\n", ldr.SymName(s), ldr.SymName(rs)) 2765 } 2766 } 2767 } 2768} 2769 2770func Rnd(v int64, r int64) int64 { 2771 if r <= 0 { 2772 return v 2773 } 2774 v += r - 1 2775 c := v % r 2776 if c < 0 { 2777 c += r 2778 } 2779 v -= c 2780 return v 2781} 2782 2783func bgetc(r *bio.Reader) int { 2784 c, err := r.ReadByte() 2785 if err != nil { 2786 if err != io.EOF { 2787 log.Fatalf("reading input: %v", err) 2788 } 2789 return -1 2790 } 2791 return int(c) 2792} 2793 2794type markKind uint8 // for postorder traversal 2795const ( 2796 _ markKind = iota 2797 visiting 2798 visited 2799) 2800 2801func postorder(libs []*sym.Library) []*sym.Library { 2802 order := make([]*sym.Library, 0, len(libs)) // hold the result 2803 mark := make(map[*sym.Library]markKind, len(libs)) 2804 for _, lib := range libs { 2805 dfs(lib, mark, &order) 2806 } 2807 return order 2808} 2809 2810func dfs(lib *sym.Library, mark map[*sym.Library]markKind, order *[]*sym.Library) { 2811 if mark[lib] == visited { 2812 return 2813 } 2814 if mark[lib] == visiting { 2815 panic("found import cycle while visiting " + lib.Pkg) 2816 } 2817 mark[lib] = visiting 2818 for _, i := range lib.Imports { 2819 dfs(i, mark, order) 2820 } 2821 mark[lib] = visited 2822 *order = append(*order, lib) 2823} 2824 2825func ElfSymForReloc(ctxt *Link, s loader.Sym) int32 { 2826 // If putelfsym created a local version of this symbol, use that in all 2827 // relocations. 2828 les := ctxt.loader.SymLocalElfSym(s) 2829 if les != 0 { 2830 return les 2831 } else { 2832 return ctxt.loader.SymElfSym(s) 2833 } 2834} 2835 2836func AddGotSym(target *Target, ldr *loader.Loader, syms *ArchSyms, s loader.Sym, elfRelocTyp uint32) { 2837 if ldr.SymGot(s) >= 0 { 2838 return 2839 } 2840 2841 Adddynsym(ldr, target, syms, s) 2842 got := ldr.MakeSymbolUpdater(syms.GOT) 2843 ldr.SetGot(s, int32(got.Size())) 2844 got.AddUint(target.Arch, 0) 2845 2846 if target.IsElf() { 2847 if target.Arch.PtrSize == 8 { 2848 rela := ldr.MakeSymbolUpdater(syms.Rela) 2849 rela.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s))) 2850 rela.AddUint64(target.Arch, elf.R_INFO(uint32(ldr.SymDynid(s)), elfRelocTyp)) 2851 rela.AddUint64(target.Arch, 0) 2852 } else { 2853 rel := ldr.MakeSymbolUpdater(syms.Rel) 2854 rel.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s))) 2855 rel.AddUint32(target.Arch, elf.R_INFO32(uint32(ldr.SymDynid(s)), elfRelocTyp)) 2856 } 2857 } else if target.IsDarwin() { 2858 leg := ldr.MakeSymbolUpdater(syms.LinkEditGOT) 2859 leg.AddUint32(target.Arch, uint32(ldr.SymDynid(s))) 2860 if target.IsPIE() && target.IsInternal() { 2861 // Mach-O relocations are a royal pain to lay out. 2862 // They use a compact stateful bytecode representation. 2863 // Here we record what are needed and encode them later. 2864 MachoAddBind(int64(ldr.SymGot(s)), s) 2865 } 2866 } else { 2867 ldr.Errorf(s, "addgotsym: unsupported binary format") 2868 } 2869} 2870 2871var hostobjcounter int 2872 2873// captureHostObj writes out the content of a host object (pulled from 2874// an archive or loaded from a *.o file directly) to a directory 2875// specified via the linker's "-capturehostobjs" debugging flag. This 2876// is intended to make it easier for a developer to inspect the actual 2877// object feeding into "CGO internal" link step. 2878func captureHostObj(h *Hostobj) { 2879 // Form paths for info file and obj file. 2880 ofile := fmt.Sprintf("captured-obj-%d.o", hostobjcounter) 2881 ifile := fmt.Sprintf("captured-obj-%d.txt", hostobjcounter) 2882 hostobjcounter++ 2883 opath := filepath.Join(*flagCaptureHostObjs, ofile) 2884 ipath := filepath.Join(*flagCaptureHostObjs, ifile) 2885 2886 // Write the info file. 2887 info := fmt.Sprintf("pkg: %s\npn: %s\nfile: %s\noff: %d\nlen: %d\n", 2888 h.pkg, h.pn, h.file, h.off, h.length) 2889 if err := os.WriteFile(ipath, []byte(info), 0666); err != nil { 2890 log.Fatalf("error writing captured host obj info %s: %v", ipath, err) 2891 } 2892 2893 readObjData := func() []byte { 2894 inf, err := os.Open(h.file) 2895 if err != nil { 2896 log.Fatalf("capturing host obj: open failed on %s: %v", h.pn, err) 2897 } 2898 defer inf.Close() 2899 res := make([]byte, h.length) 2900 if n, err := inf.ReadAt(res, h.off); err != nil || n != int(h.length) { 2901 log.Fatalf("capturing host obj: readat failed on %s: %v", h.pn, err) 2902 } 2903 return res 2904 } 2905 2906 // Write the object file. 2907 if err := os.WriteFile(opath, readObjData(), 0666); err != nil { 2908 log.Fatalf("error writing captured host object %s: %v", opath, err) 2909 } 2910 2911 fmt.Fprintf(os.Stderr, "link: info: captured host object %s to %s\n", 2912 h.file, opath) 2913} 2914 2915// findExtLinkTool invokes the external linker CC with --print-prog-name 2916// passing the name of the tool we're interested in, such as "strip", 2917// "ar", or "dsymutil", and returns the path passed back from the command. 2918func (ctxt *Link) findExtLinkTool(toolname string) string { 2919 var cc []string 2920 cc = append(cc, ctxt.extld()...) 2921 cc = append(cc, hostlinkArchArgs(ctxt.Arch)...) 2922 cc = append(cc, "--print-prog-name", toolname) 2923 out, err := exec.Command(cc[0], cc[1:]...).CombinedOutput() 2924 if err != nil { 2925 Exitf("%s: finding %s failed: %v\n%s", os.Args[0], toolname, err, out) 2926 } 2927 cmdpath := strings.TrimRight(string(out), "\r\n") 2928 return cmdpath 2929} 2930