1// Derived from Inferno utils/6l/obj.c and utils/6l/span.c 2// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6l/obj.c 3// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6l/span.c 4// 5// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 6// Portions Copyright © 1995-1997 C H Forsyth ([email protected]) 7// Portions Copyright © 1997-1999 Vita Nuova Limited 8// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 9// Portions Copyright © 2004,2006 Bruce Ellis 10// Portions Copyright © 2005-2007 C H Forsyth ([email protected]) 11// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 12// Portions Copyright © 2009 The Go Authors. All rights reserved. 13// 14// Permission is hereby granted, free of charge, to any person obtaining a copy 15// of this software and associated documentation files (the "Software"), to deal 16// in the Software without restriction, including without limitation the rights 17// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18// copies of the Software, and to permit persons to whom the Software is 19// furnished to do so, subject to the following conditions: 20// 21// The above copyright notice and this permission notice shall be included in 22// all copies or substantial portions of the Software. 23// 24// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 30// THE SOFTWARE. 31 32package ld 33 34import ( 35 "bytes" 36 "cmd/internal/gcprog" 37 "cmd/internal/objabi" 38 "cmd/internal/sys" 39 "cmd/link/internal/loader" 40 "cmd/link/internal/loadpe" 41 "cmd/link/internal/sym" 42 "compress/zlib" 43 "debug/elf" 44 "encoding/binary" 45 "fmt" 46 "internal/abi" 47 "log" 48 "math/rand" 49 "os" 50 "sort" 51 "strconv" 52 "strings" 53 "sync" 54 "sync/atomic" 55) 56 57// isRuntimeDepPkg reports whether pkg is the runtime package or its dependency. 58func isRuntimeDepPkg(pkg string) bool { 59 switch pkg { 60 case "runtime", 61 "sync/atomic", // runtime may call to sync/atomic, due to go:linkname 62 "internal/abi", // used by reflectcall (and maybe more) 63 "internal/bytealg", // for IndexByte 64 "internal/chacha8rand", // for rand 65 "internal/cpu": // for cpu features 66 return true 67 } 68 return strings.HasPrefix(pkg, "runtime/internal/") && !strings.HasSuffix(pkg, "_test") 69} 70 71// Estimate the max size needed to hold any new trampolines created for this function. This 72// is used to determine when the section can be split if it becomes too large, to ensure that 73// the trampolines are in the same section as the function that uses them. 74func maxSizeTrampolines(ctxt *Link, ldr *loader.Loader, s loader.Sym, isTramp bool) uint64 { 75 // If thearch.Trampoline is nil, then trampoline support is not available on this arch. 76 // A trampoline does not need any dependent trampolines. 77 if thearch.Trampoline == nil || isTramp { 78 return 0 79 } 80 81 n := uint64(0) 82 relocs := ldr.Relocs(s) 83 for ri := 0; ri < relocs.Count(); ri++ { 84 r := relocs.At(ri) 85 if r.Type().IsDirectCallOrJump() { 86 n++ 87 } 88 } 89 90 switch { 91 case ctxt.IsARM(): 92 return n * 20 // Trampolines in ARM range from 3 to 5 instructions. 93 case ctxt.IsARM64(): 94 return n * 12 // Trampolines in ARM64 are 3 instructions. 95 case ctxt.IsPPC64(): 96 return n * 16 // Trampolines in PPC64 are 4 instructions. 97 case ctxt.IsRISCV64(): 98 return n * 8 // Trampolines in RISCV64 are 2 instructions. 99 } 100 panic("unreachable") 101} 102 103// Detect too-far jumps in function s, and add trampolines if necessary. 104// ARM, PPC64, PPC64LE and RISCV64 support trampoline insertion for internal 105// and external linking. On PPC64 and PPC64LE the text sections might be split 106// but will still insert trampolines where necessary. 107func trampoline(ctxt *Link, s loader.Sym) { 108 if thearch.Trampoline == nil { 109 return // no need or no support of trampolines on this arch 110 } 111 112 ldr := ctxt.loader 113 relocs := ldr.Relocs(s) 114 for ri := 0; ri < relocs.Count(); ri++ { 115 r := relocs.At(ri) 116 rt := r.Type() 117 if !rt.IsDirectCallOrJump() && !isPLTCall(rt) { 118 continue 119 } 120 rs := r.Sym() 121 if !ldr.AttrReachable(rs) || ldr.SymType(rs) == sym.Sxxx { 122 continue // something is wrong. skip it here and we'll emit a better error later 123 } 124 125 if ldr.SymValue(rs) == 0 && ldr.SymType(rs) != sym.SDYNIMPORT && ldr.SymType(rs) != sym.SUNDEFEXT { 126 // Symbols in the same package are laid out together (if we 127 // don't randomize the function order). 128 // Except that if SymPkg(s) == "", it is a host object symbol 129 // which may call an external symbol via PLT. 130 if ldr.SymPkg(s) != "" && ldr.SymPkg(rs) == ldr.SymPkg(s) && *flagRandLayout == 0 { 131 // RISC-V is only able to reach +/-1MiB via a JAL instruction. 132 // We need to generate a trampoline when an address is 133 // currently unknown. 134 if !ctxt.Target.IsRISCV64() { 135 continue 136 } 137 } 138 // Runtime packages are laid out together. 139 if isRuntimeDepPkg(ldr.SymPkg(s)) && isRuntimeDepPkg(ldr.SymPkg(rs)) && *flagRandLayout == 0 { 140 continue 141 } 142 } 143 thearch.Trampoline(ctxt, ldr, ri, rs, s) 144 } 145} 146 147// whether rt is a (host object) relocation that will be turned into 148// a call to PLT. 149func isPLTCall(rt objabi.RelocType) bool { 150 const pcrel = 1 151 switch rt { 152 // ARM64 153 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_CALL26), 154 objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_JUMP26), 155 objabi.MachoRelocOffset + MACHO_ARM64_RELOC_BRANCH26*2 + pcrel: 156 return true 157 158 // ARM 159 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_CALL), 160 objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_PC24), 161 objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_JUMP24): 162 return true 163 } 164 // TODO: other architectures. 165 return false 166} 167 168// FoldSubSymbolOffset computes the offset of symbol s to its top-level outer 169// symbol. Returns the top-level symbol and the offset. 170// This is used in generating external relocations. 171func FoldSubSymbolOffset(ldr *loader.Loader, s loader.Sym) (loader.Sym, int64) { 172 outer := ldr.OuterSym(s) 173 off := int64(0) 174 if outer != 0 { 175 off += ldr.SymValue(s) - ldr.SymValue(outer) 176 s = outer 177 } 178 return s, off 179} 180 181// relocsym resolve relocations in "s", updating the symbol's content 182// in "P". 183// The main loop walks through the list of relocations attached to "s" 184// and resolves them where applicable. Relocations are often 185// architecture-specific, requiring calls into the 'archreloc' and/or 186// 'archrelocvariant' functions for the architecture. When external 187// linking is in effect, it may not be possible to completely resolve 188// the address/offset for a symbol, in which case the goal is to lay 189// the groundwork for turning a given relocation into an external reloc 190// (to be applied by the external linker). For more on how relocations 191// work in general, see 192// 193// "Linkers and Loaders", by John R. Levine (Morgan Kaufmann, 1999), ch. 7 194// 195// This is a performance-critical function for the linker; be careful 196// to avoid introducing unnecessary allocations in the main loop. 197func (st *relocSymState) relocsym(s loader.Sym, P []byte) { 198 ldr := st.ldr 199 relocs := ldr.Relocs(s) 200 if relocs.Count() == 0 { 201 return 202 } 203 target := st.target 204 syms := st.syms 205 nExtReloc := 0 // number of external relocations 206 for ri := 0; ri < relocs.Count(); ri++ { 207 r := relocs.At(ri) 208 off := r.Off() 209 siz := int32(r.Siz()) 210 rs := r.Sym() 211 rt := r.Type() 212 weak := r.Weak() 213 if off < 0 || off+siz > int32(len(P)) { 214 rname := "" 215 if rs != 0 { 216 rname = ldr.SymName(rs) 217 } 218 st.err.Errorf(s, "invalid relocation %s: %d+%d not in [%d,%d)", rname, off, siz, 0, len(P)) 219 continue 220 } 221 if siz == 0 { // informational relocation - no work to do 222 continue 223 } 224 225 var rst sym.SymKind 226 if rs != 0 { 227 rst = ldr.SymType(rs) 228 } 229 230 if rs != 0 && (rst == sym.Sxxx || rst == sym.SXREF) { 231 // When putting the runtime but not main into a shared library 232 // these symbols are undefined and that's OK. 233 if target.IsShared() || target.IsPlugin() { 234 if ldr.SymName(rs) == "main.main" || (!target.IsPlugin() && ldr.SymName(rs) == "main..inittask") { 235 sb := ldr.MakeSymbolUpdater(rs) 236 sb.SetType(sym.SDYNIMPORT) 237 } else if strings.HasPrefix(ldr.SymName(rs), "go:info.") { 238 // Skip go.info symbols. They are only needed to communicate 239 // DWARF info between the compiler and linker. 240 continue 241 } 242 } else if target.IsPPC64() && ldr.SymName(rs) == ".TOC." { 243 // TOC symbol doesn't have a type but we do assign a value 244 // (see the address pass) and we can resolve it. 245 // TODO: give it a type. 246 } else { 247 st.err.errorUnresolved(ldr, s, rs) 248 continue 249 } 250 } 251 252 if rt >= objabi.ElfRelocOffset { 253 continue 254 } 255 256 // We need to be able to reference dynimport symbols when linking against 257 // shared libraries, and AIX, Darwin, OpenBSD and Solaris always need it. 258 if !target.IsAIX() && !target.IsDarwin() && !target.IsSolaris() && !target.IsOpenbsd() && rs != 0 && rst == sym.SDYNIMPORT && !target.IsDynlinkingGo() && !ldr.AttrSubSymbol(rs) { 259 if !(target.IsPPC64() && target.IsExternal() && ldr.SymName(rs) == ".TOC.") { 260 st.err.Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", ldr.SymName(rs), rst, rst, rt, sym.RelocName(target.Arch, rt)) 261 } 262 } 263 if rs != 0 && rst != sym.STLSBSS && !weak && rt != objabi.R_METHODOFF && !ldr.AttrReachable(rs) { 264 st.err.Errorf(s, "unreachable sym in relocation: %s", ldr.SymName(rs)) 265 } 266 267 var rv sym.RelocVariant 268 if target.IsPPC64() || target.IsS390X() { 269 rv = ldr.RelocVariant(s, ri) 270 } 271 272 // TODO(mundaym): remove this special case - see issue 14218. 273 if target.IsS390X() { 274 switch rt { 275 case objabi.R_PCRELDBL: 276 rt = objabi.R_PCREL 277 rv = sym.RV_390_DBL 278 case objabi.R_CALL: 279 rv = sym.RV_390_DBL 280 } 281 } 282 283 var o int64 284 switch rt { 285 default: 286 switch siz { 287 default: 288 st.err.Errorf(s, "bad reloc size %#x for %s", uint32(siz), ldr.SymName(rs)) 289 case 1: 290 o = int64(P[off]) 291 case 2: 292 o = int64(target.Arch.ByteOrder.Uint16(P[off:])) 293 case 4: 294 o = int64(target.Arch.ByteOrder.Uint32(P[off:])) 295 case 8: 296 o = int64(target.Arch.ByteOrder.Uint64(P[off:])) 297 } 298 out, n, ok := thearch.Archreloc(target, ldr, syms, r, s, o) 299 if target.IsExternal() { 300 nExtReloc += n 301 } 302 if ok { 303 o = out 304 } else { 305 st.err.Errorf(s, "unknown reloc to %v: %d (%s)", ldr.SymName(rs), rt, sym.RelocName(target.Arch, rt)) 306 } 307 case objabi.R_TLS_LE: 308 if target.IsExternal() && target.IsElf() { 309 nExtReloc++ 310 o = 0 311 if !target.IsAMD64() { 312 o = r.Add() 313 } 314 break 315 } 316 317 if target.IsElf() && target.IsARM() { 318 // On ELF ARM, the thread pointer is 8 bytes before 319 // the start of the thread-local data block, so add 8 320 // to the actual TLS offset (r->sym->value). 321 // This 8 seems to be a fundamental constant of 322 // ELF on ARM (or maybe Glibc on ARM); it is not 323 // related to the fact that our own TLS storage happens 324 // to take up 8 bytes. 325 o = 8 + ldr.SymValue(rs) 326 } else if target.IsElf() || target.IsPlan9() || target.IsDarwin() { 327 o = int64(syms.Tlsoffset) + r.Add() 328 } else if target.IsWindows() { 329 o = r.Add() 330 } else { 331 log.Fatalf("unexpected R_TLS_LE relocation for %v", target.HeadType) 332 } 333 case objabi.R_TLS_IE: 334 if target.IsExternal() && target.IsElf() { 335 nExtReloc++ 336 o = 0 337 if !target.IsAMD64() { 338 o = r.Add() 339 } 340 if target.Is386() { 341 nExtReloc++ // need two ELF relocations on 386, see ../x86/asm.go:elfreloc1 342 } 343 break 344 } 345 if target.IsPIE() && target.IsElf() { 346 // We are linking the final executable, so we 347 // can optimize any TLS IE relocation to LE. 348 if thearch.TLSIEtoLE == nil { 349 log.Fatalf("internal linking of TLS IE not supported on %v", target.Arch.Family) 350 } 351 thearch.TLSIEtoLE(P, int(off), int(siz)) 352 o = int64(syms.Tlsoffset) 353 } else { 354 log.Fatalf("cannot handle R_TLS_IE (sym %s) when linking internally", ldr.SymName(s)) 355 } 356 case objabi.R_ADDR, objabi.R_PEIMAGEOFF: 357 if weak && !ldr.AttrReachable(rs) { 358 // Redirect it to runtime.unreachableMethod, which will throw if called. 359 rs = syms.unreachableMethod 360 } 361 if target.IsExternal() { 362 nExtReloc++ 363 364 // set up addend for eventual relocation via outer symbol. 365 rs := rs 366 rs, off := FoldSubSymbolOffset(ldr, rs) 367 xadd := r.Add() + off 368 rst := ldr.SymType(rs) 369 if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && rst != sym.SUNDEFEXT && ldr.SymSect(rs) == nil { 370 st.err.Errorf(s, "missing section for relocation target %s", ldr.SymName(rs)) 371 } 372 373 o = xadd 374 if target.IsElf() { 375 if target.IsAMD64() { 376 o = 0 377 } 378 } else if target.IsDarwin() { 379 if ldr.SymType(s).IsDWARF() { 380 // We generally use symbol-targeted relocations. 381 // DWARF tools seem to only handle section-targeted relocations, 382 // so generate section-targeted relocations in DWARF sections. 383 // See also machoreloc1. 384 o += ldr.SymValue(rs) 385 } 386 } else if target.IsWindows() { 387 // nothing to do 388 } else if target.IsAIX() { 389 o = ldr.SymValue(rs) + xadd 390 } else { 391 st.err.Errorf(s, "unhandled pcrel relocation to %s on %v", ldr.SymName(rs), target.HeadType) 392 } 393 394 break 395 } 396 397 // On AIX, a second relocation must be done by the loader, 398 // as section addresses can change once loaded. 399 // The "default" symbol address is still needed by the loader so 400 // the current relocation can't be skipped. 401 if target.IsAIX() && rst != sym.SDYNIMPORT { 402 // It's not possible to make a loader relocation in a 403 // symbol which is not inside .data section. 404 // FIXME: It should be forbidden to have R_ADDR from a 405 // symbol which isn't in .data. However, as .text has the 406 // same address once loaded, this is possible. 407 if ldr.SymSect(s).Seg == &Segdata { 408 Xcoffadddynrel(target, ldr, syms, s, r, ri) 409 } 410 } 411 412 o = ldr.SymValue(rs) + r.Add() 413 if rt == objabi.R_PEIMAGEOFF { 414 // The R_PEIMAGEOFF offset is a RVA, so subtract 415 // the base address for the executable. 416 o -= PEBASE 417 } 418 419 // On amd64, 4-byte offsets will be sign-extended, so it is impossible to 420 // access more than 2GB of static data; fail at link time is better than 421 // fail at runtime. See https://golang.org/issue/7980. 422 // Instead of special casing only amd64, we treat this as an error on all 423 // 64-bit architectures so as to be future-proof. 424 if int32(o) < 0 && target.Arch.PtrSize > 4 && siz == 4 { 425 st.err.Errorf(s, "non-pc-relative relocation address for %s is too big: %#x (%#x + %#x)", ldr.SymName(rs), uint64(o), ldr.SymValue(rs), r.Add()) 426 errorexit() 427 } 428 case objabi.R_DWARFSECREF: 429 if ldr.SymSect(rs) == nil { 430 st.err.Errorf(s, "missing DWARF section for relocation target %s", ldr.SymName(rs)) 431 } 432 433 if target.IsExternal() { 434 // On most platforms, the external linker needs to adjust DWARF references 435 // as it combines DWARF sections. However, on Darwin, dsymutil does the 436 // DWARF linking, and it understands how to follow section offsets. 437 // Leaving in the relocation records confuses it (see 438 // https://golang.org/issue/22068) so drop them for Darwin. 439 if !target.IsDarwin() { 440 nExtReloc++ 441 } 442 443 xadd := r.Add() + ldr.SymValue(rs) - int64(ldr.SymSect(rs).Vaddr) 444 445 o = xadd 446 if target.IsElf() && target.IsAMD64() { 447 o = 0 448 } 449 break 450 } 451 o = ldr.SymValue(rs) + r.Add() - int64(ldr.SymSect(rs).Vaddr) 452 case objabi.R_METHODOFF: 453 if !ldr.AttrReachable(rs) { 454 // Set it to a sentinel value. The runtime knows this is not pointing to 455 // anything valid. 456 o = -1 457 break 458 } 459 fallthrough 460 case objabi.R_ADDROFF: 461 if weak && !ldr.AttrReachable(rs) { 462 continue 463 } 464 sect := ldr.SymSect(rs) 465 if sect == nil { 466 if rst == sym.SDYNIMPORT { 467 st.err.Errorf(s, "cannot target DYNIMPORT sym in section-relative reloc: %s", ldr.SymName(rs)) 468 } else if rst == sym.SUNDEFEXT { 469 st.err.Errorf(s, "undefined symbol in relocation: %s", ldr.SymName(rs)) 470 } else { 471 st.err.Errorf(s, "missing section for relocation target %s", ldr.SymName(rs)) 472 } 473 continue 474 } 475 476 // The method offset tables using this relocation expect the offset to be relative 477 // to the start of the first text section, even if there are multiple. 478 if sect.Name == ".text" { 479 o = ldr.SymValue(rs) - int64(Segtext.Sections[0].Vaddr) + r.Add() 480 } else { 481 o = ldr.SymValue(rs) - int64(ldr.SymSect(rs).Vaddr) + r.Add() 482 } 483 484 case objabi.R_ADDRCUOFF: 485 // debug_range and debug_loc elements use this relocation type to get an 486 // offset from the start of the compile unit. 487 o = ldr.SymValue(rs) + r.Add() - ldr.SymValue(loader.Sym(ldr.SymUnit(rs).Textp[0])) 488 489 // r.Sym() can be 0 when CALL $(constant) is transformed from absolute PC to relative PC call. 490 case objabi.R_GOTPCREL: 491 if target.IsDynlinkingGo() && target.IsDarwin() && rs != 0 { 492 nExtReloc++ 493 o = r.Add() 494 break 495 } 496 if target.Is386() && target.IsExternal() && target.IsELF { 497 nExtReloc++ // need two ELF relocations on 386, see ../x86/asm.go:elfreloc1 498 } 499 fallthrough 500 case objabi.R_CALL, objabi.R_PCREL: 501 if target.IsExternal() && rs != 0 && rst == sym.SUNDEFEXT { 502 // pass through to the external linker. 503 nExtReloc++ 504 o = 0 505 break 506 } 507 if target.IsExternal() && rs != 0 && (ldr.SymSect(rs) != ldr.SymSect(s) || rt == objabi.R_GOTPCREL) { 508 nExtReloc++ 509 510 // set up addend for eventual relocation via outer symbol. 511 rs := rs 512 rs, off := FoldSubSymbolOffset(ldr, rs) 513 xadd := r.Add() + off - int64(siz) // relative to address after the relocated chunk 514 rst := ldr.SymType(rs) 515 if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && ldr.SymSect(rs) == nil { 516 st.err.Errorf(s, "missing section for relocation target %s", ldr.SymName(rs)) 517 } 518 519 o = xadd 520 if target.IsElf() { 521 if target.IsAMD64() { 522 o = 0 523 } 524 } else if target.IsDarwin() { 525 if rt == objabi.R_CALL { 526 if target.IsExternal() && rst == sym.SDYNIMPORT { 527 if target.IsAMD64() { 528 // AMD64 dynamic relocations are relative to the end of the relocation. 529 o += int64(siz) 530 } 531 } else { 532 if rst != sym.SHOSTOBJ { 533 o += int64(uint64(ldr.SymValue(rs)) - ldr.SymSect(rs).Vaddr) 534 } 535 o -= int64(off) // relative to section offset, not symbol 536 } 537 } else { 538 o += int64(siz) 539 } 540 } else if target.IsWindows() && target.IsAMD64() { // only amd64 needs PCREL 541 // PE/COFF's PC32 relocation uses the address after the relocated 542 // bytes as the base. Compensate by skewing the addend. 543 o += int64(siz) 544 } else { 545 st.err.Errorf(s, "unhandled pcrel relocation to %s on %v", ldr.SymName(rs), target.HeadType) 546 } 547 548 break 549 } 550 551 o = 0 552 if rs != 0 { 553 o = ldr.SymValue(rs) 554 } 555 556 o += r.Add() - (ldr.SymValue(s) + int64(off) + int64(siz)) 557 case objabi.R_SIZE: 558 o = ldr.SymSize(rs) + r.Add() 559 560 case objabi.R_XCOFFREF: 561 if !target.IsAIX() { 562 st.err.Errorf(s, "find XCOFF R_REF on non-XCOFF files") 563 } 564 if !target.IsExternal() { 565 st.err.Errorf(s, "find XCOFF R_REF with internal linking") 566 } 567 nExtReloc++ 568 continue 569 570 case objabi.R_DWARFFILEREF: 571 // We don't renumber files in dwarf.go:writelines anymore. 572 continue 573 574 case objabi.R_CONST: 575 o = r.Add() 576 577 case objabi.R_GOTOFF: 578 o = ldr.SymValue(rs) + r.Add() - ldr.SymValue(syms.GOT) 579 } 580 581 if target.IsPPC64() || target.IsS390X() { 582 if rv != sym.RV_NONE { 583 o = thearch.Archrelocvariant(target, ldr, r, rv, s, o, P) 584 } 585 } 586 587 switch siz { 588 default: 589 st.err.Errorf(s, "bad reloc size %#x for %s", uint32(siz), ldr.SymName(rs)) 590 case 1: 591 P[off] = byte(int8(o)) 592 case 2: 593 if (rt == objabi.R_PCREL || rt == objabi.R_CALL) && o != int64(int16(o)) { 594 st.err.Errorf(s, "pc-relative relocation address for %s is too big: %#x", ldr.SymName(rs), o) 595 } else if o != int64(int16(o)) && o != int64(uint16(o)) { 596 st.err.Errorf(s, "non-pc-relative relocation address for %s is too big: %#x", ldr.SymName(rs), uint64(o)) 597 } 598 target.Arch.ByteOrder.PutUint16(P[off:], uint16(o)) 599 case 4: 600 if (rt == objabi.R_PCREL || rt == objabi.R_CALL) && o != int64(int32(o)) { 601 st.err.Errorf(s, "pc-relative relocation address for %s is too big: %#x", ldr.SymName(rs), o) 602 } else if o != int64(int32(o)) && o != int64(uint32(o)) { 603 st.err.Errorf(s, "non-pc-relative relocation address for %s is too big: %#x", ldr.SymName(rs), uint64(o)) 604 } 605 target.Arch.ByteOrder.PutUint32(P[off:], uint32(o)) 606 case 8: 607 target.Arch.ByteOrder.PutUint64(P[off:], uint64(o)) 608 } 609 } 610 if target.IsExternal() { 611 // We'll stream out the external relocations in asmb2 (e.g. elfrelocsect) 612 // and we only need the count here. 613 atomic.AddUint32(&ldr.SymSect(s).Relcount, uint32(nExtReloc)) 614 } 615} 616 617// Convert a Go relocation to an external relocation. 618func extreloc(ctxt *Link, ldr *loader.Loader, s loader.Sym, r loader.Reloc) (loader.ExtReloc, bool) { 619 var rr loader.ExtReloc 620 target := &ctxt.Target 621 siz := int32(r.Siz()) 622 if siz == 0 { // informational relocation - no work to do 623 return rr, false 624 } 625 626 rt := r.Type() 627 if rt >= objabi.ElfRelocOffset { 628 return rr, false 629 } 630 rr.Type = rt 631 rr.Size = uint8(siz) 632 633 // TODO(mundaym): remove this special case - see issue 14218. 634 if target.IsS390X() { 635 switch rt { 636 case objabi.R_PCRELDBL: 637 rt = objabi.R_PCREL 638 } 639 } 640 641 switch rt { 642 default: 643 return thearch.Extreloc(target, ldr, r, s) 644 645 case objabi.R_TLS_LE, objabi.R_TLS_IE: 646 if target.IsElf() { 647 rs := r.Sym() 648 rr.Xsym = rs 649 if rr.Xsym == 0 { 650 rr.Xsym = ctxt.Tlsg 651 } 652 rr.Xadd = r.Add() 653 break 654 } 655 return rr, false 656 657 case objabi.R_ADDR, objabi.R_PEIMAGEOFF: 658 // set up addend for eventual relocation via outer symbol. 659 rs := r.Sym() 660 if r.Weak() && !ldr.AttrReachable(rs) { 661 rs = ctxt.ArchSyms.unreachableMethod 662 } 663 rs, off := FoldSubSymbolOffset(ldr, rs) 664 rr.Xadd = r.Add() + off 665 rr.Xsym = rs 666 667 case objabi.R_DWARFSECREF: 668 // On most platforms, the external linker needs to adjust DWARF references 669 // as it combines DWARF sections. However, on Darwin, dsymutil does the 670 // DWARF linking, and it understands how to follow section offsets. 671 // Leaving in the relocation records confuses it (see 672 // https://golang.org/issue/22068) so drop them for Darwin. 673 if target.IsDarwin() { 674 return rr, false 675 } 676 rs := r.Sym() 677 rr.Xsym = loader.Sym(ldr.SymSect(rs).Sym) 678 rr.Xadd = r.Add() + ldr.SymValue(rs) - int64(ldr.SymSect(rs).Vaddr) 679 680 // r.Sym() can be 0 when CALL $(constant) is transformed from absolute PC to relative PC call. 681 case objabi.R_GOTPCREL, objabi.R_CALL, objabi.R_PCREL: 682 rs := r.Sym() 683 if rt == objabi.R_GOTPCREL && target.IsDynlinkingGo() && target.IsDarwin() && rs != 0 { 684 rr.Xadd = r.Add() 685 rr.Xadd -= int64(siz) // relative to address after the relocated chunk 686 rr.Xsym = rs 687 break 688 } 689 if rs != 0 && ldr.SymType(rs) == sym.SUNDEFEXT { 690 // pass through to the external linker. 691 rr.Xadd = 0 692 if target.IsElf() { 693 rr.Xadd -= int64(siz) 694 } 695 rr.Xsym = rs 696 break 697 } 698 if rs != 0 && (ldr.SymSect(rs) != ldr.SymSect(s) || rt == objabi.R_GOTPCREL) { 699 // set up addend for eventual relocation via outer symbol. 700 rs := rs 701 rs, off := FoldSubSymbolOffset(ldr, rs) 702 rr.Xadd = r.Add() + off 703 rr.Xadd -= int64(siz) // relative to address after the relocated chunk 704 rr.Xsym = rs 705 break 706 } 707 return rr, false 708 709 case objabi.R_XCOFFREF: 710 return ExtrelocSimple(ldr, r), true 711 712 // These reloc types don't need external relocations. 713 case objabi.R_ADDROFF, objabi.R_METHODOFF, objabi.R_ADDRCUOFF, 714 objabi.R_SIZE, objabi.R_CONST, objabi.R_GOTOFF: 715 return rr, false 716 } 717 return rr, true 718} 719 720// ExtrelocSimple creates a simple external relocation from r, with the same 721// symbol and addend. 722func ExtrelocSimple(ldr *loader.Loader, r loader.Reloc) loader.ExtReloc { 723 var rr loader.ExtReloc 724 rs := r.Sym() 725 rr.Xsym = rs 726 rr.Xadd = r.Add() 727 rr.Type = r.Type() 728 rr.Size = r.Siz() 729 return rr 730} 731 732// ExtrelocViaOuterSym creates an external relocation from r targeting the 733// outer symbol and folding the subsymbol's offset into the addend. 734func ExtrelocViaOuterSym(ldr *loader.Loader, r loader.Reloc, s loader.Sym) loader.ExtReloc { 735 // set up addend for eventual relocation via outer symbol. 736 var rr loader.ExtReloc 737 rs := r.Sym() 738 rs, off := FoldSubSymbolOffset(ldr, rs) 739 rr.Xadd = r.Add() + off 740 rst := ldr.SymType(rs) 741 if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && rst != sym.SUNDEFEXT && ldr.SymSect(rs) == nil { 742 ldr.Errorf(s, "missing section for %s", ldr.SymName(rs)) 743 } 744 rr.Xsym = rs 745 rr.Type = r.Type() 746 rr.Size = r.Siz() 747 return rr 748} 749 750// relocSymState hold state information needed when making a series of 751// successive calls to relocsym(). The items here are invariant 752// (meaning that they are set up once initially and then don't change 753// during the execution of relocsym), with the exception of a slice 754// used to facilitate batch allocation of external relocations. Calls 755// to relocsym happen in parallel; the assumption is that each 756// parallel thread will have its own state object. 757type relocSymState struct { 758 target *Target 759 ldr *loader.Loader 760 err *ErrorReporter 761 syms *ArchSyms 762} 763 764// makeRelocSymState creates a relocSymState container object to 765// pass to relocsym(). If relocsym() calls happen in parallel, 766// each parallel thread should have its own state object. 767func (ctxt *Link) makeRelocSymState() *relocSymState { 768 return &relocSymState{ 769 target: &ctxt.Target, 770 ldr: ctxt.loader, 771 err: &ctxt.ErrorReporter, 772 syms: &ctxt.ArchSyms, 773 } 774} 775 776// windynrelocsym examines a text symbol 's' and looks for relocations 777// from it that correspond to references to symbols defined in DLLs, 778// then fixes up those relocations as needed. A reference to a symbol 779// XYZ from some DLL will fall into one of two categories: an indirect 780// ref via "__imp_XYZ", or a direct ref to "XYZ". Here's an example of 781// an indirect ref (this is an excerpt from objdump -ldr): 782// 783// 1c1: 48 89 c6 movq %rax, %rsi 784// 1c4: ff 15 00 00 00 00 callq *(%rip) 785// 00000000000001c6: IMAGE_REL_AMD64_REL32 __imp__errno 786// 787// In the assembly above, the code loads up the value of __imp_errno 788// and then does an indirect call to that value. 789// 790// Here is what a direct reference might look like: 791// 792// 137: e9 20 06 00 00 jmp 0x75c <pow+0x75c> 793// 13c: e8 00 00 00 00 callq 0x141 <pow+0x141> 794// 000000000000013d: IMAGE_REL_AMD64_REL32 _errno 795// 796// The assembly below dispenses with the import symbol and just makes 797// a direct call to _errno. 798// 799// The code below handles indirect refs by redirecting the target of 800// the relocation from "__imp_XYZ" to "XYZ" (since the latter symbol 801// is what the Windows loader is expected to resolve). For direct refs 802// the call is redirected to a stub, where the stub first loads the 803// symbol and then direct an indirect call to that value. 804// 805// Note that for a given symbol (as above) it is perfectly legal to 806// have both direct and indirect references. 807func windynrelocsym(ctxt *Link, rel *loader.SymbolBuilder, s loader.Sym) error { 808 var su *loader.SymbolBuilder 809 relocs := ctxt.loader.Relocs(s) 810 for ri := 0; ri < relocs.Count(); ri++ { 811 r := relocs.At(ri) 812 if r.IsMarker() { 813 continue // skip marker relocations 814 } 815 targ := r.Sym() 816 if targ == 0 { 817 continue 818 } 819 if !ctxt.loader.AttrReachable(targ) { 820 if r.Weak() { 821 continue 822 } 823 return fmt.Errorf("dynamic relocation to unreachable symbol %s", 824 ctxt.loader.SymName(targ)) 825 } 826 tgot := ctxt.loader.SymGot(targ) 827 if tgot == loadpe.RedirectToDynImportGotToken { 828 829 // Consistency check: name should be __imp_X 830 sname := ctxt.loader.SymName(targ) 831 if !strings.HasPrefix(sname, "__imp_") { 832 return fmt.Errorf("internal error in windynrelocsym: redirect GOT token applied to non-import symbol %s", sname) 833 } 834 835 // Locate underlying symbol (which originally had type 836 // SDYNIMPORT but has since been retyped to SWINDOWS). 837 ds, err := loadpe.LookupBaseFromImport(targ, ctxt.loader, ctxt.Arch) 838 if err != nil { 839 return err 840 } 841 dstyp := ctxt.loader.SymType(ds) 842 if dstyp != sym.SWINDOWS { 843 return fmt.Errorf("internal error in windynrelocsym: underlying sym for %q has wrong type %s", sname, dstyp.String()) 844 } 845 846 // Redirect relocation to the dynimport. 847 r.SetSym(ds) 848 continue 849 } 850 851 tplt := ctxt.loader.SymPlt(targ) 852 if tplt == loadpe.CreateImportStubPltToken { 853 854 // Consistency check: don't want to see both PLT and GOT tokens. 855 if tgot != -1 { 856 return fmt.Errorf("internal error in windynrelocsym: invalid GOT setting %d for reloc to %s", tgot, ctxt.loader.SymName(targ)) 857 } 858 859 // make dynimport JMP table for PE object files. 860 tplt := int32(rel.Size()) 861 ctxt.loader.SetPlt(targ, tplt) 862 863 if su == nil { 864 su = ctxt.loader.MakeSymbolUpdater(s) 865 } 866 r.SetSym(rel.Sym()) 867 r.SetAdd(int64(tplt)) 868 869 // jmp *addr 870 switch ctxt.Arch.Family { 871 default: 872 return fmt.Errorf("internal error in windynrelocsym: unsupported arch %v", ctxt.Arch.Family) 873 case sys.I386: 874 rel.AddUint8(0xff) 875 rel.AddUint8(0x25) 876 rel.AddAddrPlus(ctxt.Arch, targ, 0) 877 rel.AddUint8(0x90) 878 rel.AddUint8(0x90) 879 case sys.AMD64: 880 rel.AddUint8(0xff) 881 rel.AddUint8(0x24) 882 rel.AddUint8(0x25) 883 rel.AddAddrPlus4(ctxt.Arch, targ, 0) 884 rel.AddUint8(0x90) 885 } 886 } else if tplt >= 0 { 887 if su == nil { 888 su = ctxt.loader.MakeSymbolUpdater(s) 889 } 890 r.SetSym(rel.Sym()) 891 r.SetAdd(int64(tplt)) 892 } 893 } 894 return nil 895} 896 897// windynrelocsyms generates jump table to C library functions that will be 898// added later. windynrelocsyms writes the table into .rel symbol. 899func (ctxt *Link) windynrelocsyms() { 900 if !(ctxt.IsWindows() && iscgo && ctxt.IsInternal()) { 901 return 902 } 903 904 rel := ctxt.loader.CreateSymForUpdate(".rel", 0) 905 rel.SetType(sym.STEXT) 906 907 for _, s := range ctxt.Textp { 908 if err := windynrelocsym(ctxt, rel, s); err != nil { 909 ctxt.Errorf(s, "%v", err) 910 } 911 } 912 913 ctxt.Textp = append(ctxt.Textp, rel.Sym()) 914} 915 916func dynrelocsym(ctxt *Link, s loader.Sym) { 917 target := &ctxt.Target 918 ldr := ctxt.loader 919 syms := &ctxt.ArchSyms 920 relocs := ldr.Relocs(s) 921 for ri := 0; ri < relocs.Count(); ri++ { 922 r := relocs.At(ri) 923 if r.IsMarker() { 924 continue // skip marker relocations 925 } 926 rSym := r.Sym() 927 if r.Weak() && !ldr.AttrReachable(rSym) { 928 continue 929 } 930 if ctxt.BuildMode == BuildModePIE && ctxt.LinkMode == LinkInternal { 931 // It's expected that some relocations will be done 932 // later by relocsym (R_TLS_LE, R_ADDROFF), so 933 // don't worry if Adddynrel returns false. 934 thearch.Adddynrel(target, ldr, syms, s, r, ri) 935 continue 936 } 937 938 if rSym != 0 && ldr.SymType(rSym) == sym.SDYNIMPORT || r.Type() >= objabi.ElfRelocOffset { 939 if rSym != 0 && !ldr.AttrReachable(rSym) { 940 ctxt.Errorf(s, "dynamic relocation to unreachable symbol %s", ldr.SymName(rSym)) 941 } 942 if !thearch.Adddynrel(target, ldr, syms, s, r, ri) { 943 ctxt.Errorf(s, "unsupported dynamic relocation for symbol %s (type=%d (%s) stype=%d (%s))", ldr.SymName(rSym), r.Type(), sym.RelocName(ctxt.Arch, r.Type()), ldr.SymType(rSym), ldr.SymType(rSym)) 944 } 945 } 946 } 947} 948 949func (state *dodataState) dynreloc(ctxt *Link) { 950 if ctxt.HeadType == objabi.Hwindows { 951 return 952 } 953 // -d suppresses dynamic loader format, so we may as well not 954 // compute these sections or mark their symbols as reachable. 955 if *FlagD { 956 return 957 } 958 959 for _, s := range ctxt.Textp { 960 dynrelocsym(ctxt, s) 961 } 962 for _, syms := range state.data { 963 for _, s := range syms { 964 dynrelocsym(ctxt, s) 965 } 966 } 967 if ctxt.IsELF { 968 elfdynhash(ctxt) 969 } 970} 971 972func CodeblkPad(ctxt *Link, out *OutBuf, addr int64, size int64, pad []byte) { 973 writeBlocks(ctxt, out, ctxt.outSem, ctxt.loader, ctxt.Textp, addr, size, pad) 974} 975 976const blockSize = 1 << 20 // 1MB chunks written at a time. 977 978// writeBlocks writes a specified chunk of symbols to the output buffer. It 979// breaks the write up into ≥blockSize chunks to write them out, and schedules 980// as many goroutines as necessary to accomplish this task. This call then 981// blocks, waiting on the writes to complete. Note that we use the sem parameter 982// to limit the number of concurrent writes taking place. 983func writeBlocks(ctxt *Link, out *OutBuf, sem chan int, ldr *loader.Loader, syms []loader.Sym, addr, size int64, pad []byte) { 984 for i, s := range syms { 985 if ldr.SymValue(s) >= addr && !ldr.AttrSubSymbol(s) { 986 syms = syms[i:] 987 break 988 } 989 } 990 991 var wg sync.WaitGroup 992 max, lastAddr, written := int64(blockSize), addr+size, int64(0) 993 for addr < lastAddr { 994 // Find the last symbol we'd write. 995 idx := -1 996 for i, s := range syms { 997 if ldr.AttrSubSymbol(s) { 998 continue 999 } 1000 1001 // If the next symbol's size would put us out of bounds on the total length, 1002 // stop looking. 1003 end := ldr.SymValue(s) + ldr.SymSize(s) 1004 if end > lastAddr { 1005 break 1006 } 1007 1008 // We're gonna write this symbol. 1009 idx = i 1010 1011 // If we cross over the max size, we've got enough symbols. 1012 if end > addr+max { 1013 break 1014 } 1015 } 1016 1017 // If we didn't find any symbols to write, we're done here. 1018 if idx < 0 { 1019 break 1020 } 1021 1022 // Compute the length to write, including padding. 1023 // We need to write to the end address (lastAddr), or the next symbol's 1024 // start address, whichever comes first. If there is no more symbols, 1025 // just write to lastAddr. This ensures we don't leave holes between the 1026 // blocks or at the end. 1027 length := int64(0) 1028 if idx+1 < len(syms) { 1029 // Find the next top-level symbol. 1030 // Skip over sub symbols so we won't split a container symbol 1031 // into two blocks. 1032 next := syms[idx+1] 1033 for ldr.AttrSubSymbol(next) { 1034 idx++ 1035 next = syms[idx+1] 1036 } 1037 length = ldr.SymValue(next) - addr 1038 } 1039 if length == 0 || length > lastAddr-addr { 1040 length = lastAddr - addr 1041 } 1042 1043 // Start the block output operator. 1044 if o, err := out.View(uint64(out.Offset() + written)); err == nil { 1045 sem <- 1 1046 wg.Add(1) 1047 go func(o *OutBuf, ldr *loader.Loader, syms []loader.Sym, addr, size int64, pad []byte) { 1048 writeBlock(ctxt, o, ldr, syms, addr, size, pad) 1049 wg.Done() 1050 <-sem 1051 }(o, ldr, syms, addr, length, pad) 1052 } else { // output not mmaped, don't parallelize. 1053 writeBlock(ctxt, out, ldr, syms, addr, length, pad) 1054 } 1055 1056 // Prepare for the next loop. 1057 if idx != -1 { 1058 syms = syms[idx+1:] 1059 } 1060 written += length 1061 addr += length 1062 } 1063 wg.Wait() 1064} 1065 1066func writeBlock(ctxt *Link, out *OutBuf, ldr *loader.Loader, syms []loader.Sym, addr, size int64, pad []byte) { 1067 1068 st := ctxt.makeRelocSymState() 1069 1070 // This doesn't distinguish the memory size from the file 1071 // size, and it lays out the file based on Symbol.Value, which 1072 // is the virtual address. DWARF compression changes file sizes, 1073 // so dwarfcompress will fix this up later if necessary. 1074 eaddr := addr + size 1075 for _, s := range syms { 1076 if ldr.AttrSubSymbol(s) { 1077 continue 1078 } 1079 val := ldr.SymValue(s) 1080 if val >= eaddr { 1081 break 1082 } 1083 if val < addr { 1084 ldr.Errorf(s, "phase error: addr=%#x but val=%#x sym=%s type=%v sect=%v sect.addr=%#x", addr, val, ldr.SymName(s), ldr.SymType(s), ldr.SymSect(s).Name, ldr.SymSect(s).Vaddr) 1085 errorexit() 1086 } 1087 if addr < val { 1088 out.WriteStringPad("", int(val-addr), pad) 1089 addr = val 1090 } 1091 P := out.WriteSym(ldr, s) 1092 st.relocsym(s, P) 1093 if ldr.IsGeneratedSym(s) { 1094 f := ctxt.generatorSyms[s] 1095 f(ctxt, s) 1096 } 1097 addr += int64(len(P)) 1098 siz := ldr.SymSize(s) 1099 if addr < val+siz { 1100 out.WriteStringPad("", int(val+siz-addr), pad) 1101 addr = val + siz 1102 } 1103 if addr != val+siz { 1104 ldr.Errorf(s, "phase error: addr=%#x value+size=%#x", addr, val+siz) 1105 errorexit() 1106 } 1107 if val+siz >= eaddr { 1108 break 1109 } 1110 } 1111 1112 if addr < eaddr { 1113 out.WriteStringPad("", int(eaddr-addr), pad) 1114 } 1115} 1116 1117type writeFn func(*Link, *OutBuf, int64, int64) 1118 1119// writeParallel handles scheduling parallel execution of data write functions. 1120func writeParallel(wg *sync.WaitGroup, fn writeFn, ctxt *Link, seek, vaddr, length uint64) { 1121 if out, err := ctxt.Out.View(seek); err != nil { 1122 ctxt.Out.SeekSet(int64(seek)) 1123 fn(ctxt, ctxt.Out, int64(vaddr), int64(length)) 1124 } else { 1125 wg.Add(1) 1126 go func() { 1127 defer wg.Done() 1128 fn(ctxt, out, int64(vaddr), int64(length)) 1129 }() 1130 } 1131} 1132 1133func datblk(ctxt *Link, out *OutBuf, addr, size int64) { 1134 writeDatblkToOutBuf(ctxt, out, addr, size) 1135} 1136 1137// Used only on Wasm for now. 1138func DatblkBytes(ctxt *Link, addr int64, size int64) []byte { 1139 buf := make([]byte, size) 1140 out := &OutBuf{heap: buf} 1141 writeDatblkToOutBuf(ctxt, out, addr, size) 1142 return buf 1143} 1144 1145func writeDatblkToOutBuf(ctxt *Link, out *OutBuf, addr int64, size int64) { 1146 writeBlocks(ctxt, out, ctxt.outSem, ctxt.loader, ctxt.datap, addr, size, zeros[:]) 1147} 1148 1149func dwarfblk(ctxt *Link, out *OutBuf, addr int64, size int64) { 1150 // Concatenate the section symbol lists into a single list to pass 1151 // to writeBlocks. 1152 // 1153 // NB: ideally we would do a separate writeBlocks call for each 1154 // section, but this would run the risk of undoing any file offset 1155 // adjustments made during layout. 1156 n := 0 1157 for i := range dwarfp { 1158 n += len(dwarfp[i].syms) 1159 } 1160 syms := make([]loader.Sym, 0, n) 1161 for i := range dwarfp { 1162 syms = append(syms, dwarfp[i].syms...) 1163 } 1164 writeBlocks(ctxt, out, ctxt.outSem, ctxt.loader, syms, addr, size, zeros[:]) 1165} 1166 1167func pdatablk(ctxt *Link, out *OutBuf, addr int64, size int64) { 1168 writeBlocks(ctxt, out, ctxt.outSem, ctxt.loader, sehp.pdata, addr, size, zeros[:]) 1169} 1170 1171func xdatablk(ctxt *Link, out *OutBuf, addr int64, size int64) { 1172 writeBlocks(ctxt, out, ctxt.outSem, ctxt.loader, sehp.xdata, addr, size, zeros[:]) 1173} 1174 1175var covCounterDataStartOff, covCounterDataLen uint64 1176 1177var zeros [512]byte 1178 1179var ( 1180 strdata = make(map[string]string) 1181 strnames []string 1182) 1183 1184func addstrdata1(ctxt *Link, arg string) { 1185 eq := strings.Index(arg, "=") 1186 dot := strings.LastIndex(arg[:eq+1], ".") 1187 if eq < 0 || dot < 0 { 1188 Exitf("-X flag requires argument of the form importpath.name=value") 1189 } 1190 pkg := arg[:dot] 1191 if ctxt.BuildMode == BuildModePlugin && pkg == "main" { 1192 pkg = *flagPluginPath 1193 } 1194 pkg = objabi.PathToPrefix(pkg) 1195 name := pkg + arg[dot:eq] 1196 value := arg[eq+1:] 1197 if _, ok := strdata[name]; !ok { 1198 strnames = append(strnames, name) 1199 } 1200 strdata[name] = value 1201} 1202 1203// addstrdata sets the initial value of the string variable name to value. 1204func addstrdata(arch *sys.Arch, l *loader.Loader, name, value string) { 1205 s := l.Lookup(name, 0) 1206 if s == 0 { 1207 return 1208 } 1209 if goType := l.SymGoType(s); goType == 0 { 1210 return 1211 } else if typeName := l.SymName(goType); typeName != "type:string" { 1212 Errorf(nil, "%s: cannot set with -X: not a var of type string (%s)", name, typeName) 1213 return 1214 } 1215 if !l.AttrReachable(s) { 1216 return // don't bother setting unreachable variable 1217 } 1218 bld := l.MakeSymbolUpdater(s) 1219 if bld.Type() == sym.SBSS { 1220 bld.SetType(sym.SDATA) 1221 } 1222 1223 p := fmt.Sprintf("%s.str", name) 1224 sbld := l.CreateSymForUpdate(p, 0) 1225 sbld.Addstring(value) 1226 sbld.SetType(sym.SRODATA) 1227 1228 // Don't reset the variable's size. String variable usually has size of 1229 // 2*PtrSize, but in ASAN build it can be larger due to red zone. 1230 // (See issue 56175.) 1231 bld.SetData(make([]byte, arch.PtrSize*2)) 1232 bld.SetReadOnly(false) 1233 bld.ResetRelocs() 1234 bld.SetAddrPlus(arch, 0, sbld.Sym(), 0) 1235 bld.SetUint(arch, int64(arch.PtrSize), uint64(len(value))) 1236} 1237 1238func (ctxt *Link) dostrdata() { 1239 for _, name := range strnames { 1240 addstrdata(ctxt.Arch, ctxt.loader, name, strdata[name]) 1241 } 1242} 1243 1244// addgostring adds str, as a Go string value, to s. symname is the name of the 1245// symbol used to define the string data and must be unique per linked object. 1246func addgostring(ctxt *Link, ldr *loader.Loader, s *loader.SymbolBuilder, symname, str string) { 1247 sdata := ldr.CreateSymForUpdate(symname, 0) 1248 if sdata.Type() != sym.Sxxx { 1249 ctxt.Errorf(s.Sym(), "duplicate symname in addgostring: %s", symname) 1250 } 1251 sdata.SetLocal(true) 1252 sdata.SetType(sym.SRODATA) 1253 sdata.SetSize(int64(len(str))) 1254 sdata.SetData([]byte(str)) 1255 s.AddAddr(ctxt.Arch, sdata.Sym()) 1256 s.AddUint(ctxt.Arch, uint64(len(str))) 1257} 1258 1259func addinitarrdata(ctxt *Link, ldr *loader.Loader, s loader.Sym) { 1260 p := ldr.SymName(s) + ".ptr" 1261 sp := ldr.CreateSymForUpdate(p, 0) 1262 sp.SetType(sym.SINITARR) 1263 sp.SetSize(0) 1264 sp.SetDuplicateOK(true) 1265 sp.AddAddr(ctxt.Arch, s) 1266} 1267 1268// symalign returns the required alignment for the given symbol s. 1269func symalign(ldr *loader.Loader, s loader.Sym) int32 { 1270 min := int32(thearch.Minalign) 1271 align := ldr.SymAlign(s) 1272 if align >= min { 1273 return align 1274 } else if align != 0 { 1275 return min 1276 } 1277 align = int32(thearch.Maxalign) 1278 ssz := ldr.SymSize(s) 1279 for int64(align) > ssz && align > min { 1280 align >>= 1 1281 } 1282 ldr.SetSymAlign(s, align) 1283 return align 1284} 1285 1286func aligndatsize(state *dodataState, datsize int64, s loader.Sym) int64 { 1287 return Rnd(datsize, int64(symalign(state.ctxt.loader, s))) 1288} 1289 1290const debugGCProg = false 1291 1292type GCProg struct { 1293 ctxt *Link 1294 sym *loader.SymbolBuilder 1295 w gcprog.Writer 1296} 1297 1298func (p *GCProg) Init(ctxt *Link, name string) { 1299 p.ctxt = ctxt 1300 p.sym = ctxt.loader.CreateSymForUpdate(name, 0) 1301 p.w.Init(p.writeByte()) 1302 if debugGCProg { 1303 fmt.Fprintf(os.Stderr, "ld: start GCProg %s\n", name) 1304 p.w.Debug(os.Stderr) 1305 } 1306} 1307 1308func (p *GCProg) writeByte() func(x byte) { 1309 return func(x byte) { 1310 p.sym.AddUint8(x) 1311 } 1312} 1313 1314func (p *GCProg) End(size int64) { 1315 p.w.ZeroUntil(size / int64(p.ctxt.Arch.PtrSize)) 1316 p.w.End() 1317 if debugGCProg { 1318 fmt.Fprintf(os.Stderr, "ld: end GCProg\n") 1319 } 1320} 1321 1322func (p *GCProg) AddSym(s loader.Sym) { 1323 ldr := p.ctxt.loader 1324 typ := ldr.SymGoType(s) 1325 1326 // Things without pointers should be in sym.SNOPTRDATA or sym.SNOPTRBSS; 1327 // everything we see should have pointers and should therefore have a type. 1328 if typ == 0 { 1329 switch ldr.SymName(s) { 1330 case "runtime.data", "runtime.edata", "runtime.bss", "runtime.ebss": 1331 // Ignore special symbols that are sometimes laid out 1332 // as real symbols. See comment about dyld on darwin in 1333 // the address function. 1334 return 1335 } 1336 p.ctxt.Errorf(p.sym.Sym(), "missing Go type information for global symbol %s: size %d", ldr.SymName(s), ldr.SymSize(s)) 1337 return 1338 } 1339 1340 ptrsize := int64(p.ctxt.Arch.PtrSize) 1341 typData := ldr.Data(typ) 1342 nptr := decodetypePtrdata(p.ctxt.Arch, typData) / ptrsize 1343 1344 if debugGCProg { 1345 fmt.Fprintf(os.Stderr, "gcprog sym: %s at %d (ptr=%d+%d)\n", ldr.SymName(s), ldr.SymValue(s), ldr.SymValue(s)/ptrsize, nptr) 1346 } 1347 1348 sval := ldr.SymValue(s) 1349 if !decodetypeUsegcprog(p.ctxt.Arch, typData) { 1350 // Copy pointers from mask into program. 1351 mask := decodetypeGcmask(p.ctxt, typ) 1352 for i := int64(0); i < nptr; i++ { 1353 if (mask[i/8]>>uint(i%8))&1 != 0 { 1354 p.w.Ptr(sval/ptrsize + i) 1355 } 1356 } 1357 return 1358 } 1359 1360 // Copy program. 1361 prog := decodetypeGcprog(p.ctxt, typ) 1362 p.w.ZeroUntil(sval / ptrsize) 1363 p.w.Append(prog[4:], nptr) 1364} 1365 1366// cutoff is the maximum data section size permitted by the linker 1367// (see issue #9862). 1368const cutoff = 2e9 // 2 GB (or so; looks better in errors than 2^31) 1369 1370// check accumulated size of data sections 1371func (state *dodataState) checkdatsize(symn sym.SymKind) { 1372 if state.datsize > cutoff { 1373 Errorf(nil, "too much data, last section %v (%d, over %v bytes)", symn, state.datsize, cutoff) 1374 } 1375} 1376 1377func checkSectSize(sect *sym.Section) { 1378 // TODO: consider using 4 GB size limit for DWARF sections, and 1379 // make sure we generate unsigned offset in relocations and check 1380 // for overflow. 1381 if sect.Length > cutoff { 1382 Errorf(nil, "too much data in section %s (%d, over %v bytes)", sect.Name, sect.Length, cutoff) 1383 } 1384} 1385 1386// fixZeroSizedSymbols gives a few special symbols with zero size some space. 1387func fixZeroSizedSymbols(ctxt *Link) { 1388 // The values in moduledata are filled out by relocations 1389 // pointing to the addresses of these special symbols. 1390 // Typically these symbols have no size and are not laid 1391 // out with their matching section. 1392 // 1393 // However on darwin, dyld will find the special symbol 1394 // in the first loaded module, even though it is local. 1395 // 1396 // (An hypothesis, formed without looking in the dyld sources: 1397 // these special symbols have no size, so their address 1398 // matches a real symbol. The dynamic linker assumes we 1399 // want the normal symbol with the same address and finds 1400 // it in the other module.) 1401 // 1402 // To work around this we lay out the symbls whose 1403 // addresses are vital for multi-module programs to work 1404 // as normal symbols, and give them a little size. 1405 // 1406 // On AIX, as all DATA sections are merged together, ld might not put 1407 // these symbols at the beginning of their respective section if there 1408 // aren't real symbols, their alignment might not match the 1409 // first symbol alignment. Therefore, there are explicitly put at the 1410 // beginning of their section with the same alignment. 1411 if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) && !(ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) { 1412 return 1413 } 1414 1415 ldr := ctxt.loader 1416 bss := ldr.CreateSymForUpdate("runtime.bss", 0) 1417 bss.SetSize(8) 1418 ldr.SetAttrSpecial(bss.Sym(), false) 1419 1420 ebss := ldr.CreateSymForUpdate("runtime.ebss", 0) 1421 ldr.SetAttrSpecial(ebss.Sym(), false) 1422 1423 data := ldr.CreateSymForUpdate("runtime.data", 0) 1424 data.SetSize(8) 1425 ldr.SetAttrSpecial(data.Sym(), false) 1426 1427 edata := ldr.CreateSymForUpdate("runtime.edata", 0) 1428 ldr.SetAttrSpecial(edata.Sym(), false) 1429 1430 if ctxt.HeadType == objabi.Haix { 1431 // XCOFFTOC symbols are part of .data section. 1432 edata.SetType(sym.SXCOFFTOC) 1433 } 1434 1435 noptrbss := ldr.CreateSymForUpdate("runtime.noptrbss", 0) 1436 noptrbss.SetSize(8) 1437 ldr.SetAttrSpecial(noptrbss.Sym(), false) 1438 1439 enoptrbss := ldr.CreateSymForUpdate("runtime.enoptrbss", 0) 1440 ldr.SetAttrSpecial(enoptrbss.Sym(), false) 1441 1442 noptrdata := ldr.CreateSymForUpdate("runtime.noptrdata", 0) 1443 noptrdata.SetSize(8) 1444 ldr.SetAttrSpecial(noptrdata.Sym(), false) 1445 1446 enoptrdata := ldr.CreateSymForUpdate("runtime.enoptrdata", 0) 1447 ldr.SetAttrSpecial(enoptrdata.Sym(), false) 1448 1449 types := ldr.CreateSymForUpdate("runtime.types", 0) 1450 types.SetType(sym.STYPE) 1451 types.SetSize(8) 1452 ldr.SetAttrSpecial(types.Sym(), false) 1453 1454 etypes := ldr.CreateSymForUpdate("runtime.etypes", 0) 1455 etypes.SetType(sym.SFUNCTAB) 1456 ldr.SetAttrSpecial(etypes.Sym(), false) 1457 1458 if ctxt.HeadType == objabi.Haix { 1459 rodata := ldr.CreateSymForUpdate("runtime.rodata", 0) 1460 rodata.SetType(sym.SSTRING) 1461 rodata.SetSize(8) 1462 ldr.SetAttrSpecial(rodata.Sym(), false) 1463 1464 erodata := ldr.CreateSymForUpdate("runtime.erodata", 0) 1465 ldr.SetAttrSpecial(erodata.Sym(), false) 1466 } 1467} 1468 1469// makeRelroForSharedLib creates a section of readonly data if necessary. 1470func (state *dodataState) makeRelroForSharedLib(target *Link) { 1471 if !target.UseRelro() { 1472 return 1473 } 1474 1475 // "read only" data with relocations needs to go in its own section 1476 // when building a shared library. We do this by boosting objects of 1477 // type SXXX with relocations to type SXXXRELRO. 1478 ldr := target.loader 1479 for _, symnro := range sym.ReadOnly { 1480 symnrelro := sym.RelROMap[symnro] 1481 1482 ro := []loader.Sym{} 1483 relro := state.data[symnrelro] 1484 1485 for _, s := range state.data[symnro] { 1486 relocs := ldr.Relocs(s) 1487 isRelro := relocs.Count() > 0 1488 switch state.symType(s) { 1489 case sym.STYPE, sym.STYPERELRO, sym.SGOFUNCRELRO: 1490 // Symbols are not sorted yet, so it is possible 1491 // that an Outer symbol has been changed to a 1492 // relro Type before it reaches here. 1493 isRelro = true 1494 case sym.SFUNCTAB: 1495 if ldr.SymName(s) == "runtime.etypes" { 1496 // runtime.etypes must be at the end of 1497 // the relro data. 1498 isRelro = true 1499 } 1500 case sym.SGOFUNC: 1501 // The only SGOFUNC symbols that contain relocations are .stkobj, 1502 // and their relocations are of type objabi.R_ADDROFF, 1503 // which always get resolved during linking. 1504 isRelro = false 1505 } 1506 if isRelro { 1507 state.setSymType(s, symnrelro) 1508 if outer := ldr.OuterSym(s); outer != 0 { 1509 state.setSymType(outer, symnrelro) 1510 } 1511 relro = append(relro, s) 1512 } else { 1513 ro = append(ro, s) 1514 } 1515 } 1516 1517 // Check that we haven't made two symbols with the same .Outer into 1518 // different types (because references two symbols with non-nil Outer 1519 // become references to the outer symbol + offset it's vital that the 1520 // symbol and the outer end up in the same section). 1521 for _, s := range relro { 1522 if outer := ldr.OuterSym(s); outer != 0 { 1523 st := state.symType(s) 1524 ost := state.symType(outer) 1525 if st != ost { 1526 state.ctxt.Errorf(s, "inconsistent types for symbol and its Outer %s (%v != %v)", 1527 ldr.SymName(outer), st, ost) 1528 } 1529 } 1530 } 1531 1532 state.data[symnro] = ro 1533 state.data[symnrelro] = relro 1534 } 1535} 1536 1537// dodataState holds bits of state information needed by dodata() and the 1538// various helpers it calls. The lifetime of these items should not extend 1539// past the end of dodata(). 1540type dodataState struct { 1541 // Link context 1542 ctxt *Link 1543 // Data symbols bucketed by type. 1544 data [sym.SXREF][]loader.Sym 1545 // Max alignment for each flavor of data symbol. 1546 dataMaxAlign [sym.SXREF]int32 1547 // Overridden sym type 1548 symGroupType []sym.SymKind 1549 // Current data size so far. 1550 datsize int64 1551} 1552 1553// A note on symType/setSymType below: 1554// 1555// In the legacy linker, the types of symbols (notably data symbols) are 1556// changed during the symtab() phase so as to insure that similar symbols 1557// are bucketed together, then their types are changed back again during 1558// dodata. Symbol to section assignment also plays tricks along these lines 1559// in the case where a relro segment is needed. 1560// 1561// The value returned from setType() below reflects the effects of 1562// any overrides made by symtab and/or dodata. 1563 1564// symType returns the (possibly overridden) type of 's'. 1565func (state *dodataState) symType(s loader.Sym) sym.SymKind { 1566 if int(s) < len(state.symGroupType) { 1567 if override := state.symGroupType[s]; override != 0 { 1568 return override 1569 } 1570 } 1571 return state.ctxt.loader.SymType(s) 1572} 1573 1574// setSymType sets a new override type for 's'. 1575func (state *dodataState) setSymType(s loader.Sym, kind sym.SymKind) { 1576 if s == 0 { 1577 panic("bad") 1578 } 1579 if int(s) < len(state.symGroupType) { 1580 state.symGroupType[s] = kind 1581 } else { 1582 su := state.ctxt.loader.MakeSymbolUpdater(s) 1583 su.SetType(kind) 1584 } 1585} 1586 1587func (ctxt *Link) dodata(symGroupType []sym.SymKind) { 1588 1589 // Give zeros sized symbols space if necessary. 1590 fixZeroSizedSymbols(ctxt) 1591 1592 // Collect data symbols by type into data. 1593 state := dodataState{ctxt: ctxt, symGroupType: symGroupType} 1594 ldr := ctxt.loader 1595 for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ { 1596 if !ldr.AttrReachable(s) || ldr.AttrSpecial(s) || ldr.AttrSubSymbol(s) || 1597 !ldr.TopLevelSym(s) { 1598 continue 1599 } 1600 1601 st := state.symType(s) 1602 1603 if st <= sym.STEXT || st >= sym.SXREF { 1604 continue 1605 } 1606 state.data[st] = append(state.data[st], s) 1607 1608 // Similarly with checking the onlist attr. 1609 if ldr.AttrOnList(s) { 1610 log.Fatalf("symbol %s listed multiple times", ldr.SymName(s)) 1611 } 1612 ldr.SetAttrOnList(s, true) 1613 } 1614 1615 // Now that we have the data symbols, but before we start 1616 // to assign addresses, record all the necessary 1617 // dynamic relocations. These will grow the relocation 1618 // symbol, which is itself data. 1619 // 1620 // On darwin, we need the symbol table numbers for dynreloc. 1621 if ctxt.HeadType == objabi.Hdarwin { 1622 machosymorder(ctxt) 1623 } 1624 state.dynreloc(ctxt) 1625 1626 // Move any RO data with relocations to a separate section. 1627 state.makeRelroForSharedLib(ctxt) 1628 1629 // Set alignment for the symbol with the largest known index, 1630 // so as to trigger allocation of the loader's internal 1631 // alignment array. This will avoid data races in the parallel 1632 // section below. 1633 lastSym := loader.Sym(ldr.NSym() - 1) 1634 ldr.SetSymAlign(lastSym, ldr.SymAlign(lastSym)) 1635 1636 // Sort symbols. 1637 var wg sync.WaitGroup 1638 for symn := range state.data { 1639 symn := sym.SymKind(symn) 1640 wg.Add(1) 1641 go func() { 1642 state.data[symn], state.dataMaxAlign[symn] = state.dodataSect(ctxt, symn, state.data[symn]) 1643 wg.Done() 1644 }() 1645 } 1646 wg.Wait() 1647 1648 if ctxt.IsELF { 1649 // Make .rela and .rela.plt contiguous, the ELF ABI requires this 1650 // and Solaris actually cares. 1651 syms := state.data[sym.SELFROSECT] 1652 reli, plti := -1, -1 1653 for i, s := range syms { 1654 switch ldr.SymName(s) { 1655 case ".rel.plt", ".rela.plt": 1656 plti = i 1657 case ".rel", ".rela": 1658 reli = i 1659 } 1660 } 1661 if reli >= 0 && plti >= 0 && plti != reli+1 { 1662 var first, second int 1663 if plti > reli { 1664 first, second = reli, plti 1665 } else { 1666 first, second = plti, reli 1667 } 1668 rel, plt := syms[reli], syms[plti] 1669 copy(syms[first+2:], syms[first+1:second]) 1670 syms[first+0] = rel 1671 syms[first+1] = plt 1672 1673 // Make sure alignment doesn't introduce a gap. 1674 // Setting the alignment explicitly prevents 1675 // symalign from basing it on the size and 1676 // getting it wrong. 1677 ldr.SetSymAlign(rel, int32(ctxt.Arch.RegSize)) 1678 ldr.SetSymAlign(plt, int32(ctxt.Arch.RegSize)) 1679 } 1680 state.data[sym.SELFROSECT] = syms 1681 } 1682 1683 if ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal { 1684 // These symbols must have the same alignment as their section. 1685 // Otherwise, ld might change the layout of Go sections. 1686 ldr.SetSymAlign(ldr.Lookup("runtime.data", 0), state.dataMaxAlign[sym.SDATA]) 1687 ldr.SetSymAlign(ldr.Lookup("runtime.bss", 0), state.dataMaxAlign[sym.SBSS]) 1688 } 1689 1690 // Create *sym.Section objects and assign symbols to sections for 1691 // data/rodata (and related) symbols. 1692 state.allocateDataSections(ctxt) 1693 1694 state.allocateSEHSections(ctxt) 1695 1696 // Create *sym.Section objects and assign symbols to sections for 1697 // DWARF symbols. 1698 state.allocateDwarfSections(ctxt) 1699 1700 /* number the sections */ 1701 n := int16(1) 1702 1703 for _, sect := range Segtext.Sections { 1704 sect.Extnum = n 1705 n++ 1706 } 1707 for _, sect := range Segrodata.Sections { 1708 sect.Extnum = n 1709 n++ 1710 } 1711 for _, sect := range Segrelrodata.Sections { 1712 sect.Extnum = n 1713 n++ 1714 } 1715 for _, sect := range Segdata.Sections { 1716 sect.Extnum = n 1717 n++ 1718 } 1719 for _, sect := range Segdwarf.Sections { 1720 sect.Extnum = n 1721 n++ 1722 } 1723 for _, sect := range Segpdata.Sections { 1724 sect.Extnum = n 1725 n++ 1726 } 1727 for _, sect := range Segxdata.Sections { 1728 sect.Extnum = n 1729 n++ 1730 } 1731} 1732 1733// allocateDataSectionForSym creates a new sym.Section into which a 1734// single symbol will be placed. Here "seg" is the segment into which 1735// the section will go, "s" is the symbol to be placed into the new 1736// section, and "rwx" contains permissions for the section. 1737func (state *dodataState) allocateDataSectionForSym(seg *sym.Segment, s loader.Sym, rwx int) *sym.Section { 1738 ldr := state.ctxt.loader 1739 sname := ldr.SymName(s) 1740 if strings.HasPrefix(sname, "go:") { 1741 sname = ".go." + sname[len("go:"):] 1742 } 1743 sect := addsection(ldr, state.ctxt.Arch, seg, sname, rwx) 1744 sect.Align = symalign(ldr, s) 1745 state.datsize = Rnd(state.datsize, int64(sect.Align)) 1746 sect.Vaddr = uint64(state.datsize) 1747 return sect 1748} 1749 1750// allocateNamedDataSection creates a new sym.Section for a category 1751// of data symbols. Here "seg" is the segment into which the section 1752// will go, "sName" is the name to give to the section, "types" is a 1753// range of symbol types to be put into the section, and "rwx" 1754// contains permissions for the section. 1755func (state *dodataState) allocateNamedDataSection(seg *sym.Segment, sName string, types []sym.SymKind, rwx int) *sym.Section { 1756 sect := addsection(state.ctxt.loader, state.ctxt.Arch, seg, sName, rwx) 1757 if len(types) == 0 { 1758 sect.Align = 1 1759 } else if len(types) == 1 { 1760 sect.Align = state.dataMaxAlign[types[0]] 1761 } else { 1762 for _, symn := range types { 1763 align := state.dataMaxAlign[symn] 1764 if sect.Align < align { 1765 sect.Align = align 1766 } 1767 } 1768 } 1769 state.datsize = Rnd(state.datsize, int64(sect.Align)) 1770 sect.Vaddr = uint64(state.datsize) 1771 return sect 1772} 1773 1774// assignDsymsToSection assigns a collection of data symbols to a 1775// newly created section. "sect" is the section into which to place 1776// the symbols, "syms" holds the list of symbols to assign, 1777// "forceType" (if non-zero) contains a new sym type to apply to each 1778// sym during the assignment, and "aligner" is a hook to call to 1779// handle alignment during the assignment process. 1780func (state *dodataState) assignDsymsToSection(sect *sym.Section, syms []loader.Sym, forceType sym.SymKind, aligner func(state *dodataState, datsize int64, s loader.Sym) int64) { 1781 ldr := state.ctxt.loader 1782 for _, s := range syms { 1783 state.datsize = aligner(state, state.datsize, s) 1784 ldr.SetSymSect(s, sect) 1785 if forceType != sym.Sxxx { 1786 state.setSymType(s, forceType) 1787 } 1788 ldr.SetSymValue(s, int64(uint64(state.datsize)-sect.Vaddr)) 1789 state.datsize += ldr.SymSize(s) 1790 } 1791 sect.Length = uint64(state.datsize) - sect.Vaddr 1792} 1793 1794func (state *dodataState) assignToSection(sect *sym.Section, symn sym.SymKind, forceType sym.SymKind) { 1795 state.assignDsymsToSection(sect, state.data[symn], forceType, aligndatsize) 1796 state.checkdatsize(symn) 1797} 1798 1799// allocateSingleSymSections walks through the bucketed data symbols 1800// with type 'symn', creates a new section for each sym, and assigns 1801// the sym to a newly created section. Section name is set from the 1802// symbol name. "Seg" is the segment into which to place the new 1803// section, "forceType" is the new sym.SymKind to assign to the symbol 1804// within the section, and "rwx" holds section permissions. 1805func (state *dodataState) allocateSingleSymSections(seg *sym.Segment, symn sym.SymKind, forceType sym.SymKind, rwx int) { 1806 ldr := state.ctxt.loader 1807 for _, s := range state.data[symn] { 1808 sect := state.allocateDataSectionForSym(seg, s, rwx) 1809 ldr.SetSymSect(s, sect) 1810 state.setSymType(s, forceType) 1811 ldr.SetSymValue(s, int64(uint64(state.datsize)-sect.Vaddr)) 1812 state.datsize += ldr.SymSize(s) 1813 sect.Length = uint64(state.datsize) - sect.Vaddr 1814 } 1815 state.checkdatsize(symn) 1816} 1817 1818// allocateNamedSectionAndAssignSyms creates a new section with the 1819// specified name, then walks through the bucketed data symbols with 1820// type 'symn' and assigns each of them to this new section. "Seg" is 1821// the segment into which to place the new section, "secName" is the 1822// name to give to the new section, "forceType" (if non-zero) contains 1823// a new sym type to apply to each sym during the assignment, and 1824// "rwx" holds section permissions. 1825func (state *dodataState) allocateNamedSectionAndAssignSyms(seg *sym.Segment, secName string, symn sym.SymKind, forceType sym.SymKind, rwx int) *sym.Section { 1826 1827 sect := state.allocateNamedDataSection(seg, secName, []sym.SymKind{symn}, rwx) 1828 state.assignDsymsToSection(sect, state.data[symn], forceType, aligndatsize) 1829 return sect 1830} 1831 1832// allocateDataSections allocates sym.Section objects for data/rodata 1833// (and related) symbols, and then assigns symbols to those sections. 1834func (state *dodataState) allocateDataSections(ctxt *Link) { 1835 // Allocate sections. 1836 // Data is processed before segtext, because we need 1837 // to see all symbols in the .data and .bss sections in order 1838 // to generate garbage collection information. 1839 1840 // Writable data sections that do not need any specialized handling. 1841 writable := []sym.SymKind{ 1842 sym.SBUILDINFO, 1843 sym.SELFSECT, 1844 sym.SMACHO, 1845 sym.SMACHOGOT, 1846 sym.SWINDOWS, 1847 } 1848 for _, symn := range writable { 1849 state.allocateSingleSymSections(&Segdata, symn, sym.SDATA, 06) 1850 } 1851 ldr := ctxt.loader 1852 1853 // writable .got (note that for PIE binaries .got goes in relro) 1854 if len(state.data[sym.SELFGOT]) > 0 { 1855 state.allocateNamedSectionAndAssignSyms(&Segdata, ".got", sym.SELFGOT, sym.SDATA, 06) 1856 } 1857 1858 /* pointer-free data */ 1859 sect := state.allocateNamedSectionAndAssignSyms(&Segdata, ".noptrdata", sym.SNOPTRDATA, sym.SDATA, 06) 1860 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.noptrdata", 0), sect) 1861 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.enoptrdata", 0), sect) 1862 1863 hasinitarr := ctxt.linkShared 1864 1865 /* shared library initializer */ 1866 switch ctxt.BuildMode { 1867 case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin: 1868 hasinitarr = true 1869 } 1870 1871 if ctxt.HeadType == objabi.Haix { 1872 if len(state.data[sym.SINITARR]) > 0 { 1873 Errorf(nil, "XCOFF format doesn't allow .init_array section") 1874 } 1875 } 1876 1877 if hasinitarr && len(state.data[sym.SINITARR]) > 0 { 1878 state.allocateNamedSectionAndAssignSyms(&Segdata, ".init_array", sym.SINITARR, sym.Sxxx, 06) 1879 } 1880 1881 /* data */ 1882 sect = state.allocateNamedSectionAndAssignSyms(&Segdata, ".data", sym.SDATA, sym.SDATA, 06) 1883 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.data", 0), sect) 1884 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.edata", 0), sect) 1885 dataGcEnd := state.datsize - int64(sect.Vaddr) 1886 1887 // On AIX, TOC entries must be the last of .data 1888 // These aren't part of gc as they won't change during the runtime. 1889 state.assignToSection(sect, sym.SXCOFFTOC, sym.SDATA) 1890 state.checkdatsize(sym.SDATA) 1891 sect.Length = uint64(state.datsize) - sect.Vaddr 1892 1893 /* bss */ 1894 sect = state.allocateNamedSectionAndAssignSyms(&Segdata, ".bss", sym.SBSS, sym.Sxxx, 06) 1895 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.bss", 0), sect) 1896 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.ebss", 0), sect) 1897 bssGcEnd := state.datsize - int64(sect.Vaddr) 1898 1899 // Emit gcdata for bss symbols now that symbol values have been assigned. 1900 gcsToEmit := []struct { 1901 symName string 1902 symKind sym.SymKind 1903 gcEnd int64 1904 }{ 1905 {"runtime.gcdata", sym.SDATA, dataGcEnd}, 1906 {"runtime.gcbss", sym.SBSS, bssGcEnd}, 1907 } 1908 for _, g := range gcsToEmit { 1909 var gc GCProg 1910 gc.Init(ctxt, g.symName) 1911 for _, s := range state.data[g.symKind] { 1912 gc.AddSym(s) 1913 } 1914 gc.End(g.gcEnd) 1915 } 1916 1917 /* pointer-free bss */ 1918 sect = state.allocateNamedSectionAndAssignSyms(&Segdata, ".noptrbss", sym.SNOPTRBSS, sym.Sxxx, 06) 1919 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.noptrbss", 0), sect) 1920 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.enoptrbss", 0), sect) 1921 1922 // Code coverage counters are assigned to the .noptrbss section. 1923 // We assign them in a separate pass so that they stay aggregated 1924 // together in a single blob (coverage runtime depends on this). 1925 covCounterDataStartOff = sect.Length 1926 state.assignToSection(sect, sym.SCOVERAGE_COUNTER, sym.SNOPTRBSS) 1927 covCounterDataLen = sect.Length - covCounterDataStartOff 1928 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.covctrs", 0), sect) 1929 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.ecovctrs", 0), sect) 1930 1931 // Coverage instrumentation counters for libfuzzer. 1932 if len(state.data[sym.SLIBFUZZER_8BIT_COUNTER]) > 0 { 1933 sect := state.allocateNamedSectionAndAssignSyms(&Segdata, ".go.fuzzcntrs", sym.SLIBFUZZER_8BIT_COUNTER, sym.Sxxx, 06) 1934 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.__start___sancov_cntrs", 0), sect) 1935 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.__stop___sancov_cntrs", 0), sect) 1936 ldr.SetSymSect(ldr.LookupOrCreateSym("internal/fuzz._counters", 0), sect) 1937 ldr.SetSymSect(ldr.LookupOrCreateSym("internal/fuzz._ecounters", 0), sect) 1938 } 1939 1940 // Assign runtime.end to the last section of data segment. 1941 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.end", 0), Segdata.Sections[len(Segdata.Sections)-1]) 1942 1943 if len(state.data[sym.STLSBSS]) > 0 { 1944 var sect *sym.Section 1945 // FIXME: not clear why it is sometimes necessary to suppress .tbss section creation. 1946 if (ctxt.IsELF || ctxt.HeadType == objabi.Haix) && (ctxt.LinkMode == LinkExternal || !*FlagD) { 1947 sect = addsection(ldr, ctxt.Arch, &Segdata, ".tbss", 06) 1948 sect.Align = int32(ctxt.Arch.PtrSize) 1949 // FIXME: why does this need to be set to zero? 1950 sect.Vaddr = 0 1951 } 1952 state.datsize = 0 1953 1954 for _, s := range state.data[sym.STLSBSS] { 1955 state.datsize = aligndatsize(state, state.datsize, s) 1956 if sect != nil { 1957 ldr.SetSymSect(s, sect) 1958 } 1959 ldr.SetSymValue(s, state.datsize) 1960 state.datsize += ldr.SymSize(s) 1961 } 1962 state.checkdatsize(sym.STLSBSS) 1963 1964 if sect != nil { 1965 sect.Length = uint64(state.datsize) 1966 } 1967 } 1968 1969 /* 1970 * We finished data, begin read-only data. 1971 * Not all systems support a separate read-only non-executable data section. 1972 * ELF and Windows PE systems do. 1973 * OS X and Plan 9 do not. 1974 * And if we're using external linking mode, the point is moot, 1975 * since it's not our decision; that code expects the sections in 1976 * segtext. 1977 */ 1978 var segro *sym.Segment 1979 if ctxt.IsELF && ctxt.LinkMode == LinkInternal { 1980 segro = &Segrodata 1981 } else if ctxt.HeadType == objabi.Hwindows { 1982 segro = &Segrodata 1983 } else { 1984 segro = &Segtext 1985 } 1986 1987 state.datsize = 0 1988 1989 /* read-only executable ELF, Mach-O sections */ 1990 if len(state.data[sym.STEXT]) != 0 { 1991 culprit := ldr.SymName(state.data[sym.STEXT][0]) 1992 Errorf(nil, "dodata found an sym.STEXT symbol: %s", culprit) 1993 } 1994 state.allocateSingleSymSections(&Segtext, sym.SELFRXSECT, sym.SRODATA, 05) 1995 state.allocateSingleSymSections(&Segtext, sym.SMACHOPLT, sym.SRODATA, 05) 1996 1997 /* read-only data */ 1998 sect = state.allocateNamedDataSection(segro, ".rodata", sym.ReadOnly, 04) 1999 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.rodata", 0), sect) 2000 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.erodata", 0), sect) 2001 if !ctxt.UseRelro() { 2002 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.types", 0), sect) 2003 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.etypes", 0), sect) 2004 } 2005 for _, symn := range sym.ReadOnly { 2006 symnStartValue := state.datsize 2007 if len(state.data[symn]) != 0 { 2008 symnStartValue = aligndatsize(state, symnStartValue, state.data[symn][0]) 2009 } 2010 state.assignToSection(sect, symn, sym.SRODATA) 2011 setCarrierSize(symn, state.datsize-symnStartValue) 2012 if ctxt.HeadType == objabi.Haix { 2013 // Read-only symbols might be wrapped inside their outer 2014 // symbol. 2015 // XCOFF symbol table needs to know the size of 2016 // these outer symbols. 2017 xcoffUpdateOuterSize(ctxt, state.datsize-symnStartValue, symn) 2018 } 2019 } 2020 2021 /* read-only ELF, Mach-O sections */ 2022 state.allocateSingleSymSections(segro, sym.SELFROSECT, sym.SRODATA, 04) 2023 2024 // There is some data that are conceptually read-only but are written to by 2025 // relocations. On GNU systems, we can arrange for the dynamic linker to 2026 // mprotect sections after relocations are applied by giving them write 2027 // permissions in the object file and calling them ".data.rel.ro.FOO". We 2028 // divide the .rodata section between actual .rodata and .data.rel.ro.rodata, 2029 // but for the other sections that this applies to, we just write a read-only 2030 // .FOO section or a read-write .data.rel.ro.FOO section depending on the 2031 // situation. 2032 // TODO(mwhudson): It would make sense to do this more widely, but it makes 2033 // the system linker segfault on darwin. 2034 const relroPerm = 06 2035 const fallbackPerm = 04 2036 relroSecPerm := fallbackPerm 2037 genrelrosecname := func(suffix string) string { 2038 if suffix == "" { 2039 return ".rodata" 2040 } 2041 return suffix 2042 } 2043 seg := segro 2044 2045 if ctxt.UseRelro() { 2046 segrelro := &Segrelrodata 2047 if ctxt.LinkMode == LinkExternal && !ctxt.IsAIX() && !ctxt.IsDarwin() { 2048 // Using a separate segment with an external 2049 // linker results in some programs moving 2050 // their data sections unexpectedly, which 2051 // corrupts the moduledata. So we use the 2052 // rodata segment and let the external linker 2053 // sort out a rel.ro segment. 2054 segrelro = segro 2055 } else { 2056 // Reset datsize for new segment. 2057 state.datsize = 0 2058 } 2059 2060 if !ctxt.IsDarwin() { // We don't need the special names on darwin. 2061 genrelrosecname = func(suffix string) string { 2062 return ".data.rel.ro" + suffix 2063 } 2064 } 2065 2066 relroReadOnly := []sym.SymKind{} 2067 for _, symnro := range sym.ReadOnly { 2068 symn := sym.RelROMap[symnro] 2069 relroReadOnly = append(relroReadOnly, symn) 2070 } 2071 seg = segrelro 2072 relroSecPerm = relroPerm 2073 2074 /* data only written by relocations */ 2075 sect = state.allocateNamedDataSection(segrelro, genrelrosecname(""), relroReadOnly, relroSecPerm) 2076 2077 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.types", 0), sect) 2078 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.etypes", 0), sect) 2079 2080 for i, symnro := range sym.ReadOnly { 2081 if i == 0 && symnro == sym.STYPE && ctxt.HeadType != objabi.Haix { 2082 // Skip forward so that no type 2083 // reference uses a zero offset. 2084 // This is unlikely but possible in small 2085 // programs with no other read-only data. 2086 state.datsize++ 2087 } 2088 2089 symn := sym.RelROMap[symnro] 2090 symnStartValue := state.datsize 2091 if len(state.data[symn]) != 0 { 2092 symnStartValue = aligndatsize(state, symnStartValue, state.data[symn][0]) 2093 } 2094 2095 for _, s := range state.data[symn] { 2096 outer := ldr.OuterSym(s) 2097 if s != 0 && ldr.SymSect(outer) != nil && ldr.SymSect(outer) != sect { 2098 ctxt.Errorf(s, "s.Outer (%s) in different section from s, %s != %s", ldr.SymName(outer), ldr.SymSect(outer).Name, sect.Name) 2099 } 2100 } 2101 state.assignToSection(sect, symn, sym.SRODATA) 2102 setCarrierSize(symn, state.datsize-symnStartValue) 2103 if ctxt.HeadType == objabi.Haix { 2104 // Read-only symbols might be wrapped inside their outer 2105 // symbol. 2106 // XCOFF symbol table needs to know the size of 2107 // these outer symbols. 2108 xcoffUpdateOuterSize(ctxt, state.datsize-symnStartValue, symn) 2109 } 2110 } 2111 sect.Length = uint64(state.datsize) - sect.Vaddr 2112 2113 state.allocateSingleSymSections(segrelro, sym.SELFRELROSECT, sym.SRODATA, relroSecPerm) 2114 } 2115 2116 /* typelink */ 2117 sect = state.allocateNamedDataSection(seg, genrelrosecname(".typelink"), []sym.SymKind{sym.STYPELINK}, relroSecPerm) 2118 2119 typelink := ldr.CreateSymForUpdate("runtime.typelink", 0) 2120 ldr.SetSymSect(typelink.Sym(), sect) 2121 typelink.SetType(sym.SRODATA) 2122 state.datsize += typelink.Size() 2123 state.checkdatsize(sym.STYPELINK) 2124 sect.Length = uint64(state.datsize) - sect.Vaddr 2125 2126 /* itablink */ 2127 sect = state.allocateNamedDataSection(seg, genrelrosecname(".itablink"), []sym.SymKind{sym.SITABLINK}, relroSecPerm) 2128 2129 itablink := ldr.CreateSymForUpdate("runtime.itablink", 0) 2130 ldr.SetSymSect(itablink.Sym(), sect) 2131 itablink.SetType(sym.SRODATA) 2132 state.datsize += itablink.Size() 2133 state.checkdatsize(sym.SITABLINK) 2134 sect.Length = uint64(state.datsize) - sect.Vaddr 2135 2136 /* gosymtab */ 2137 sect = state.allocateNamedSectionAndAssignSyms(seg, genrelrosecname(".gosymtab"), sym.SSYMTAB, sym.SRODATA, relroSecPerm) 2138 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.symtab", 0), sect) 2139 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.esymtab", 0), sect) 2140 2141 /* gopclntab */ 2142 sect = state.allocateNamedSectionAndAssignSyms(seg, genrelrosecname(".gopclntab"), sym.SPCLNTAB, sym.SRODATA, relroSecPerm) 2143 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pclntab", 0), sect) 2144 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pcheader", 0), sect) 2145 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.funcnametab", 0), sect) 2146 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.cutab", 0), sect) 2147 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.filetab", 0), sect) 2148 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pctab", 0), sect) 2149 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.functab", 0), sect) 2150 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.epclntab", 0), sect) 2151 setCarrierSize(sym.SPCLNTAB, int64(sect.Length)) 2152 if ctxt.HeadType == objabi.Haix { 2153 xcoffUpdateOuterSize(ctxt, int64(sect.Length), sym.SPCLNTAB) 2154 } 2155 2156 // 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits. 2157 if state.datsize != int64(uint32(state.datsize)) { 2158 Errorf(nil, "read-only data segment too large: %d", state.datsize) 2159 } 2160 2161 siz := 0 2162 for symn := sym.SELFRXSECT; symn < sym.SXREF; symn++ { 2163 siz += len(state.data[symn]) 2164 } 2165 ctxt.datap = make([]loader.Sym, 0, siz) 2166 for symn := sym.SELFRXSECT; symn < sym.SXREF; symn++ { 2167 ctxt.datap = append(ctxt.datap, state.data[symn]...) 2168 } 2169} 2170 2171// allocateDwarfSections allocates sym.Section objects for DWARF 2172// symbols, and assigns symbols to sections. 2173func (state *dodataState) allocateDwarfSections(ctxt *Link) { 2174 2175 alignOne := func(state *dodataState, datsize int64, s loader.Sym) int64 { return datsize } 2176 2177 ldr := ctxt.loader 2178 for i := 0; i < len(dwarfp); i++ { 2179 // First the section symbol. 2180 s := dwarfp[i].secSym() 2181 sect := state.allocateNamedDataSection(&Segdwarf, ldr.SymName(s), []sym.SymKind{}, 04) 2182 ldr.SetSymSect(s, sect) 2183 sect.Sym = sym.LoaderSym(s) 2184 curType := ldr.SymType(s) 2185 state.setSymType(s, sym.SRODATA) 2186 ldr.SetSymValue(s, int64(uint64(state.datsize)-sect.Vaddr)) 2187 state.datsize += ldr.SymSize(s) 2188 2189 // Then any sub-symbols for the section symbol. 2190 subSyms := dwarfp[i].subSyms() 2191 state.assignDsymsToSection(sect, subSyms, sym.SRODATA, alignOne) 2192 2193 for j := 0; j < len(subSyms); j++ { 2194 s := subSyms[j] 2195 if ctxt.HeadType == objabi.Haix && curType == sym.SDWARFLOC { 2196 // Update the size of .debug_loc for this symbol's 2197 // package. 2198 addDwsectCUSize(".debug_loc", ldr.SymPkg(s), uint64(ldr.SymSize(s))) 2199 } 2200 } 2201 sect.Length = uint64(state.datsize) - sect.Vaddr 2202 checkSectSize(sect) 2203 } 2204} 2205 2206// allocateSEHSections allocate a sym.Section object for SEH 2207// symbols, and assigns symbols to sections. 2208func (state *dodataState) allocateSEHSections(ctxt *Link) { 2209 if len(sehp.pdata) > 0 { 2210 sect := state.allocateNamedDataSection(&Segpdata, ".pdata", []sym.SymKind{}, 04) 2211 state.assignDsymsToSection(sect, sehp.pdata, sym.SRODATA, aligndatsize) 2212 state.checkdatsize(sym.SSEHSECT) 2213 } 2214 if len(sehp.xdata) > 0 { 2215 sect := state.allocateNamedDataSection(&Segxdata, ".xdata", []sym.SymKind{}, 04) 2216 state.assignDsymsToSection(sect, sehp.xdata, sym.SRODATA, aligndatsize) 2217 state.checkdatsize(sym.SSEHSECT) 2218 } 2219} 2220 2221type symNameSize struct { 2222 name string 2223 sz int64 2224 val int64 2225 sym loader.Sym 2226} 2227 2228func (state *dodataState) dodataSect(ctxt *Link, symn sym.SymKind, syms []loader.Sym) (result []loader.Sym, maxAlign int32) { 2229 var head, tail, zerobase loader.Sym 2230 ldr := ctxt.loader 2231 sl := make([]symNameSize, len(syms)) 2232 2233 // For ppc64, we want to interleave the .got and .toc sections 2234 // from input files. Both are type sym.SELFGOT, so in that case 2235 // we skip size comparison and do the name comparison instead 2236 // (conveniently, .got sorts before .toc). 2237 checkSize := symn != sym.SELFGOT 2238 2239 for k, s := range syms { 2240 ss := ldr.SymSize(s) 2241 sl[k] = symNameSize{sz: ss, sym: s} 2242 if !checkSize { 2243 sl[k].name = ldr.SymName(s) 2244 } 2245 ds := int64(len(ldr.Data(s))) 2246 switch { 2247 case ss < ds: 2248 ctxt.Errorf(s, "initialize bounds (%d < %d)", ss, ds) 2249 case ss < 0: 2250 ctxt.Errorf(s, "negative size (%d bytes)", ss) 2251 case ss > cutoff: 2252 ctxt.Errorf(s, "symbol too large (%d bytes)", ss) 2253 } 2254 2255 // If the usually-special section-marker symbols are being laid 2256 // out as regular symbols, put them either at the beginning or 2257 // end of their section. 2258 if (ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) { 2259 switch ldr.SymName(s) { 2260 case "runtime.text", "runtime.bss", "runtime.data", "runtime.types", "runtime.rodata", 2261 "runtime.noptrdata", "runtime.noptrbss": 2262 head = s 2263 continue 2264 case "runtime.etext", "runtime.ebss", "runtime.edata", "runtime.etypes", "runtime.erodata", 2265 "runtime.enoptrdata", "runtime.enoptrbss": 2266 tail = s 2267 continue 2268 } 2269 } 2270 } 2271 zerobase = ldr.Lookup("runtime.zerobase", 0) 2272 2273 // Perform the sort. 2274 if symn != sym.SPCLNTAB { 2275 sort.Slice(sl, func(i, j int) bool { 2276 si, sj := sl[i].sym, sl[j].sym 2277 isz, jsz := sl[i].sz, sl[j].sz 2278 switch { 2279 case si == head, sj == tail: 2280 return true 2281 case sj == head, si == tail: 2282 return false 2283 // put zerobase right after all the zero-sized symbols, 2284 // so zero-sized symbols have the same address as zerobase. 2285 case si == zerobase: 2286 return jsz != 0 // zerobase < nonzero-sized 2287 case sj == zerobase: 2288 return isz == 0 // 0-sized < zerobase 2289 } 2290 if checkSize { 2291 if isz != jsz { 2292 return isz < jsz 2293 } 2294 } else { 2295 iname := sl[i].name 2296 jname := sl[j].name 2297 if iname != jname { 2298 return iname < jname 2299 } 2300 } 2301 return si < sj 2302 }) 2303 } else { 2304 // PCLNTAB was built internally, and already has the proper order. 2305 } 2306 2307 // Set alignment, construct result 2308 syms = syms[:0] 2309 for k := range sl { 2310 s := sl[k].sym 2311 if s != head && s != tail { 2312 align := symalign(ldr, s) 2313 if maxAlign < align { 2314 maxAlign = align 2315 } 2316 } 2317 syms = append(syms, s) 2318 } 2319 2320 return syms, maxAlign 2321} 2322 2323// Add buildid to beginning of text segment, on non-ELF systems. 2324// Non-ELF binary formats are not always flexible enough to 2325// give us a place to put the Go build ID. On those systems, we put it 2326// at the very beginning of the text segment. 2327// This “header” is read by cmd/go. 2328func (ctxt *Link) textbuildid() { 2329 if ctxt.IsELF || *flagBuildid == "" { 2330 return 2331 } 2332 2333 ldr := ctxt.loader 2334 s := ldr.CreateSymForUpdate("go:buildid", 0) 2335 // The \xff is invalid UTF-8, meant to make it less likely 2336 // to find one of these accidentally. 2337 data := "\xff Go build ID: " + strconv.Quote(*flagBuildid) + "\n \xff" 2338 s.SetType(sym.STEXT) 2339 s.SetData([]byte(data)) 2340 s.SetSize(int64(len(data))) 2341 2342 ctxt.Textp = append(ctxt.Textp, 0) 2343 copy(ctxt.Textp[1:], ctxt.Textp) 2344 ctxt.Textp[0] = s.Sym() 2345} 2346 2347func (ctxt *Link) buildinfo() { 2348 // Write the buildinfo symbol, which go version looks for. 2349 // The code reading this data is in package debug/buildinfo. 2350 ldr := ctxt.loader 2351 s := ldr.CreateSymForUpdate("go:buildinfo", 0) 2352 s.SetType(sym.SBUILDINFO) 2353 s.SetAlign(16) 2354 // The \xff is invalid UTF-8, meant to make it less likely 2355 // to find one of these accidentally. 2356 const prefix = "\xff Go buildinf:" // 14 bytes, plus 2 data bytes filled in below 2357 data := make([]byte, 32) 2358 copy(data, prefix) 2359 data[len(prefix)] = byte(ctxt.Arch.PtrSize) 2360 data[len(prefix)+1] = 0 2361 if ctxt.Arch.ByteOrder == binary.BigEndian { 2362 data[len(prefix)+1] = 1 2363 } 2364 data[len(prefix)+1] |= 2 // signals new pointer-free format 2365 data = appendString(data, strdata["runtime.buildVersion"]) 2366 data = appendString(data, strdata["runtime.modinfo"]) 2367 // MacOS linker gets very upset if the size os not a multiple of alignment. 2368 for len(data)%16 != 0 { 2369 data = append(data, 0) 2370 } 2371 s.SetData(data) 2372 s.SetSize(int64(len(data))) 2373 2374 // Add reference to go:buildinfo from the rodata section, 2375 // so that external linking with -Wl,--gc-sections does not 2376 // delete the build info. 2377 sr := ldr.CreateSymForUpdate("go:buildinfo.ref", 0) 2378 sr.SetType(sym.SRODATA) 2379 sr.SetAlign(int32(ctxt.Arch.PtrSize)) 2380 sr.AddAddr(ctxt.Arch, s.Sym()) 2381} 2382 2383// appendString appends s to data, prefixed by its varint-encoded length. 2384func appendString(data []byte, s string) []byte { 2385 var v [binary.MaxVarintLen64]byte 2386 n := binary.PutUvarint(v[:], uint64(len(s))) 2387 data = append(data, v[:n]...) 2388 data = append(data, s...) 2389 return data 2390} 2391 2392// assign addresses to text 2393func (ctxt *Link) textaddress() { 2394 addsection(ctxt.loader, ctxt.Arch, &Segtext, ".text", 05) 2395 2396 // Assign PCs in text segment. 2397 // Could parallelize, by assigning to text 2398 // and then letting threads copy down, but probably not worth it. 2399 sect := Segtext.Sections[0] 2400 2401 sect.Align = int32(Funcalign) 2402 2403 ldr := ctxt.loader 2404 2405 if *flagRandLayout != 0 { 2406 r := rand.New(rand.NewSource(*flagRandLayout)) 2407 textp := ctxt.Textp 2408 i := 0 2409 // don't move the buildid symbol 2410 if len(textp) > 0 && ldr.SymName(textp[0]) == "go:buildid" { 2411 i++ 2412 } 2413 // Skip over C symbols, as functions in a (C object) section must stay together. 2414 // TODO: maybe we can move a section as a whole. 2415 // Note: we load C symbols before Go symbols, so we can scan from the start. 2416 for i < len(textp) && (ldr.SubSym(textp[i]) != 0 || ldr.AttrSubSymbol(textp[i])) { 2417 i++ 2418 } 2419 textp = textp[i:] 2420 r.Shuffle(len(textp), func(i, j int) { 2421 textp[i], textp[j] = textp[j], textp[i] 2422 }) 2423 } 2424 2425 text := ctxt.xdefine("runtime.text", sym.STEXT, 0) 2426 etext := ctxt.xdefine("runtime.etext", sym.STEXT, 0) 2427 ldr.SetSymSect(text, sect) 2428 if ctxt.IsAIX() && ctxt.IsExternal() { 2429 // Setting runtime.text has a real symbol prevents ld to 2430 // change its base address resulting in wrong offsets for 2431 // reflect methods. 2432 u := ldr.MakeSymbolUpdater(text) 2433 u.SetAlign(sect.Align) 2434 u.SetSize(8) 2435 } 2436 2437 if (ctxt.DynlinkingGo() && ctxt.IsDarwin()) || (ctxt.IsAIX() && ctxt.IsExternal()) { 2438 ldr.SetSymSect(etext, sect) 2439 ctxt.Textp = append(ctxt.Textp, etext, 0) 2440 copy(ctxt.Textp[1:], ctxt.Textp) 2441 ctxt.Textp[0] = text 2442 } 2443 2444 start := uint64(Rnd(*FlagTextAddr, int64(Funcalign))) 2445 va := start 2446 n := 1 2447 sect.Vaddr = va 2448 2449 limit := thearch.TrampLimit 2450 if limit == 0 { 2451 limit = 1 << 63 // unlimited 2452 } 2453 if *FlagDebugTextSize != 0 { 2454 limit = uint64(*FlagDebugTextSize) 2455 } 2456 if *FlagDebugTramp > 1 { 2457 limit = 1 // debug mode, force generating trampolines for everything 2458 } 2459 2460 if ctxt.IsAIX() && ctxt.IsExternal() { 2461 // On AIX, normally we won't generate direct calls to external symbols, 2462 // except in one test, cmd/go/testdata/script/link_syso_issue33139.txt. 2463 // That test doesn't make much sense, and I'm not sure it ever works. 2464 // Just generate trampoline for now (which will turn a direct call to 2465 // an indirect call, which at least builds). 2466 limit = 1 2467 } 2468 2469 // First pass: assign addresses assuming the program is small and will 2470 // not require trampoline generation. 2471 big := false 2472 for _, s := range ctxt.Textp { 2473 sect, n, va = assignAddress(ctxt, sect, n, s, va, false, big) 2474 if va-start >= limit { 2475 big = true 2476 break 2477 } 2478 } 2479 2480 // Second pass: only if it is too big, insert trampolines for too-far 2481 // jumps and targets with unknown addresses. 2482 if big { 2483 // reset addresses 2484 for _, s := range ctxt.Textp { 2485 if s != text { 2486 resetAddress(ctxt, s) 2487 } 2488 } 2489 va = start 2490 2491 ntramps := 0 2492 var curPkg string 2493 for i, s := range ctxt.Textp { 2494 // When we find the first symbol in a package, perform a 2495 // single iteration that assigns temporary addresses to all 2496 // of the text in the same package, using the maximum possible 2497 // number of trampolines. This allows for better decisions to 2498 // be made regarding reachability and the need for trampolines. 2499 if symPkg := ldr.SymPkg(s); symPkg != "" && curPkg != symPkg { 2500 curPkg = symPkg 2501 vaTmp := va 2502 for j := i; j < len(ctxt.Textp); j++ { 2503 curSym := ctxt.Textp[j] 2504 if symPkg := ldr.SymPkg(curSym); symPkg == "" || curPkg != symPkg { 2505 break 2506 } 2507 // We do not pass big to assignAddress here, as this 2508 // can result in side effects such as section splitting. 2509 sect, n, vaTmp = assignAddress(ctxt, sect, n, curSym, vaTmp, false, false) 2510 vaTmp += maxSizeTrampolines(ctxt, ldr, curSym, false) 2511 } 2512 } 2513 2514 // Reset address for current symbol. 2515 if s != text { 2516 resetAddress(ctxt, s) 2517 } 2518 2519 // Assign actual address for current symbol. 2520 sect, n, va = assignAddress(ctxt, sect, n, s, va, false, big) 2521 2522 // Resolve jumps, adding trampolines if they are needed. 2523 trampoline(ctxt, s) 2524 2525 // lay down trampolines after each function 2526 for ; ntramps < len(ctxt.tramps); ntramps++ { 2527 tramp := ctxt.tramps[ntramps] 2528 if ctxt.IsAIX() && strings.HasPrefix(ldr.SymName(tramp), "runtime.text.") { 2529 // Already set in assignAddress 2530 continue 2531 } 2532 sect, n, va = assignAddress(ctxt, sect, n, tramp, va, true, big) 2533 } 2534 } 2535 2536 // merge tramps into Textp, keeping Textp in address order 2537 if ntramps != 0 { 2538 newtextp := make([]loader.Sym, 0, len(ctxt.Textp)+ntramps) 2539 i := 0 2540 for _, s := range ctxt.Textp { 2541 for ; i < ntramps && ldr.SymValue(ctxt.tramps[i]) < ldr.SymValue(s); i++ { 2542 newtextp = append(newtextp, ctxt.tramps[i]) 2543 } 2544 newtextp = append(newtextp, s) 2545 } 2546 newtextp = append(newtextp, ctxt.tramps[i:ntramps]...) 2547 2548 ctxt.Textp = newtextp 2549 } 2550 } 2551 2552 // Add MinLC size after etext, so it won't collide with the next symbol 2553 // (which may confuse some symbolizer). 2554 sect.Length = va - sect.Vaddr + uint64(ctxt.Arch.MinLC) 2555 ldr.SetSymSect(etext, sect) 2556 if ldr.SymValue(etext) == 0 { 2557 // Set the address of the start/end symbols, if not already 2558 // (i.e. not darwin+dynlink or AIX+external, see above). 2559 ldr.SetSymValue(etext, int64(va)) 2560 ldr.SetSymValue(text, int64(Segtext.Sections[0].Vaddr)) 2561 } 2562} 2563 2564// assigns address for a text symbol, returns (possibly new) section, its number, and the address. 2565func assignAddress(ctxt *Link, sect *sym.Section, n int, s loader.Sym, va uint64, isTramp, big bool) (*sym.Section, int, uint64) { 2566 ldr := ctxt.loader 2567 if thearch.AssignAddress != nil { 2568 return thearch.AssignAddress(ldr, sect, n, s, va, isTramp) 2569 } 2570 2571 ldr.SetSymSect(s, sect) 2572 if ldr.AttrSubSymbol(s) { 2573 return sect, n, va 2574 } 2575 2576 align := ldr.SymAlign(s) 2577 if align == 0 { 2578 align = int32(Funcalign) 2579 } 2580 va = uint64(Rnd(int64(va), int64(align))) 2581 if sect.Align < align { 2582 sect.Align = align 2583 } 2584 2585 funcsize := uint64(abi.MINFUNC) // spacing required for findfunctab 2586 if ldr.SymSize(s) > abi.MINFUNC { 2587 funcsize = uint64(ldr.SymSize(s)) 2588 } 2589 2590 // If we need to split text sections, and this function doesn't fit in the current 2591 // section, then create a new one. 2592 // 2593 // Only break at outermost syms. 2594 if big && splitTextSections(ctxt) && ldr.OuterSym(s) == 0 { 2595 // For debugging purposes, allow text size limit to be cranked down, 2596 // so as to stress test the code that handles multiple text sections. 2597 var textSizelimit uint64 = thearch.TrampLimit 2598 if *FlagDebugTextSize != 0 { 2599 textSizelimit = uint64(*FlagDebugTextSize) 2600 } 2601 2602 // Sanity check: make sure the limit is larger than any 2603 // individual text symbol. 2604 if funcsize > textSizelimit { 2605 panic(fmt.Sprintf("error: text size limit %d less than text symbol %s size of %d", textSizelimit, ldr.SymName(s), funcsize)) 2606 } 2607 2608 if va-sect.Vaddr+funcsize+maxSizeTrampolines(ctxt, ldr, s, isTramp) > textSizelimit { 2609 sectAlign := int32(thearch.Funcalign) 2610 if ctxt.IsPPC64() { 2611 // Align the next text section to the worst case function alignment likely 2612 // to be encountered when processing function symbols. The start address 2613 // is rounded against the final alignment of the text section later on in 2614 // (*Link).address. This may happen due to usage of PCALIGN directives 2615 // larger than Funcalign, or usage of ISA 3.1 prefixed instructions 2616 // (see ISA 3.1 Book I 1.9). 2617 const ppc64maxFuncalign = 64 2618 sectAlign = ppc64maxFuncalign 2619 va = uint64(Rnd(int64(va), ppc64maxFuncalign)) 2620 } 2621 2622 // Set the length for the previous text section 2623 sect.Length = va - sect.Vaddr 2624 2625 // Create new section, set the starting Vaddr 2626 sect = addsection(ctxt.loader, ctxt.Arch, &Segtext, ".text", 05) 2627 2628 sect.Vaddr = va 2629 sect.Align = sectAlign 2630 ldr.SetSymSect(s, sect) 2631 2632 // Create a symbol for the start of the secondary text sections 2633 ntext := ldr.CreateSymForUpdate(fmt.Sprintf("runtime.text.%d", n), 0) 2634 ntext.SetSect(sect) 2635 if ctxt.IsAIX() { 2636 // runtime.text.X must be a real symbol on AIX. 2637 // Assign its address directly in order to be the 2638 // first symbol of this new section. 2639 ntext.SetType(sym.STEXT) 2640 ntext.SetSize(int64(abi.MINFUNC)) 2641 ntext.SetOnList(true) 2642 ntext.SetAlign(sectAlign) 2643 ctxt.tramps = append(ctxt.tramps, ntext.Sym()) 2644 2645 ntext.SetValue(int64(va)) 2646 va += uint64(ntext.Size()) 2647 2648 if align := ldr.SymAlign(s); align != 0 { 2649 va = uint64(Rnd(int64(va), int64(align))) 2650 } else { 2651 va = uint64(Rnd(int64(va), int64(Funcalign))) 2652 } 2653 } 2654 n++ 2655 } 2656 } 2657 2658 ldr.SetSymValue(s, 0) 2659 for sub := s; sub != 0; sub = ldr.SubSym(sub) { 2660 ldr.SetSymValue(sub, ldr.SymValue(sub)+int64(va)) 2661 if ctxt.Debugvlog > 2 { 2662 fmt.Println("assign text address:", ldr.SymName(sub), ldr.SymValue(sub)) 2663 } 2664 } 2665 2666 va += funcsize 2667 2668 return sect, n, va 2669} 2670 2671func resetAddress(ctxt *Link, s loader.Sym) { 2672 ldr := ctxt.loader 2673 if ldr.OuterSym(s) != 0 { 2674 return 2675 } 2676 oldv := ldr.SymValue(s) 2677 for sub := s; sub != 0; sub = ldr.SubSym(sub) { 2678 ldr.SetSymValue(sub, ldr.SymValue(sub)-oldv) 2679 } 2680} 2681 2682// Return whether we may need to split text sections. 2683// 2684// On PPC64x, when external linking, a text section should not be 2685// larger than 2^25 bytes due to the size of call target offset field 2686// in the 'bl' instruction. Splitting into smaller text sections 2687// smaller than this limit allows the system linker to modify the long 2688// calls appropriately. The limit allows for the space needed for 2689// tables inserted by the linker. 2690// 2691// The same applies to Darwin/ARM64, with 2^27 byte threshold. 2692// 2693// Similarly for ARM, we split sections (at 2^25 bytes) to avoid 2694// inconsistencies between the Go linker's reachability calculations 2695// (e.g. will direct call from X to Y need a trampoline) and similar 2696// machinery in the external linker; see #58425 for more on the 2697// history here. 2698func splitTextSections(ctxt *Link) bool { 2699 return (ctxt.IsARM() || ctxt.IsPPC64() || (ctxt.IsARM64() && ctxt.IsDarwin())) && ctxt.IsExternal() 2700} 2701 2702// On Wasm, we reserve 4096 bytes for zero page, then 8192 bytes for wasm_exec.js 2703// to store command line args and environment variables. 2704// Data sections starts from at least address 12288. 2705// Keep in sync with wasm_exec.js. 2706const wasmMinDataAddr = 4096 + 8192 2707 2708// address assigns virtual addresses to all segments and sections and 2709// returns all segments in file order. 2710func (ctxt *Link) address() []*sym.Segment { 2711 var order []*sym.Segment // Layout order 2712 2713 va := uint64(*FlagTextAddr) 2714 order = append(order, &Segtext) 2715 Segtext.Rwx = 05 2716 Segtext.Vaddr = va 2717 for i, s := range Segtext.Sections { 2718 va = uint64(Rnd(int64(va), int64(s.Align))) 2719 s.Vaddr = va 2720 va += s.Length 2721 2722 if ctxt.IsWasm() && i == 0 && va < wasmMinDataAddr { 2723 va = wasmMinDataAddr 2724 } 2725 } 2726 2727 Segtext.Length = va - uint64(*FlagTextAddr) 2728 2729 if len(Segrodata.Sections) > 0 { 2730 // align to page boundary so as not to mix 2731 // rodata and executable text. 2732 // 2733 // Note: gold or GNU ld will reduce the size of the executable 2734 // file by arranging for the relro segment to end at a page 2735 // boundary, and overlap the end of the text segment with the 2736 // start of the relro segment in the file. The PT_LOAD segments 2737 // will be such that the last page of the text segment will be 2738 // mapped twice, once r-x and once starting out rw- and, after 2739 // relocation processing, changed to r--. 2740 // 2741 // Ideally the last page of the text segment would not be 2742 // writable even for this short period. 2743 va = uint64(Rnd(int64(va), *FlagRound)) 2744 2745 order = append(order, &Segrodata) 2746 Segrodata.Rwx = 04 2747 Segrodata.Vaddr = va 2748 for _, s := range Segrodata.Sections { 2749 va = uint64(Rnd(int64(va), int64(s.Align))) 2750 s.Vaddr = va 2751 va += s.Length 2752 } 2753 2754 Segrodata.Length = va - Segrodata.Vaddr 2755 } 2756 if len(Segrelrodata.Sections) > 0 { 2757 // align to page boundary so as not to mix 2758 // rodata, rel-ro data, and executable text. 2759 va = uint64(Rnd(int64(va), *FlagRound)) 2760 if ctxt.HeadType == objabi.Haix { 2761 // Relro data are inside data segment on AIX. 2762 va += uint64(XCOFFDATABASE) - uint64(XCOFFTEXTBASE) 2763 } 2764 2765 order = append(order, &Segrelrodata) 2766 Segrelrodata.Rwx = 06 2767 Segrelrodata.Vaddr = va 2768 for _, s := range Segrelrodata.Sections { 2769 va = uint64(Rnd(int64(va), int64(s.Align))) 2770 s.Vaddr = va 2771 va += s.Length 2772 } 2773 2774 Segrelrodata.Length = va - Segrelrodata.Vaddr 2775 } 2776 2777 va = uint64(Rnd(int64(va), *FlagRound)) 2778 if ctxt.HeadType == objabi.Haix && len(Segrelrodata.Sections) == 0 { 2779 // Data sections are moved to an unreachable segment 2780 // to ensure that they are position-independent. 2781 // Already done if relro sections exist. 2782 va += uint64(XCOFFDATABASE) - uint64(XCOFFTEXTBASE) 2783 } 2784 order = append(order, &Segdata) 2785 Segdata.Rwx = 06 2786 Segdata.Vaddr = va 2787 var data *sym.Section 2788 var noptr *sym.Section 2789 var bss *sym.Section 2790 var noptrbss *sym.Section 2791 var fuzzCounters *sym.Section 2792 for i, s := range Segdata.Sections { 2793 if (ctxt.IsELF || ctxt.HeadType == objabi.Haix) && s.Name == ".tbss" { 2794 continue 2795 } 2796 vlen := int64(s.Length) 2797 if i+1 < len(Segdata.Sections) && !((ctxt.IsELF || ctxt.HeadType == objabi.Haix) && Segdata.Sections[i+1].Name == ".tbss") { 2798 vlen = int64(Segdata.Sections[i+1].Vaddr - s.Vaddr) 2799 } 2800 s.Vaddr = va 2801 va += uint64(vlen) 2802 Segdata.Length = va - Segdata.Vaddr 2803 switch s.Name { 2804 case ".data": 2805 data = s 2806 case ".noptrdata": 2807 noptr = s 2808 case ".bss": 2809 bss = s 2810 case ".noptrbss": 2811 noptrbss = s 2812 case ".go.fuzzcntrs": 2813 fuzzCounters = s 2814 } 2815 } 2816 2817 // Assign Segdata's Filelen omitting the BSS. We do this here 2818 // simply because right now we know where the BSS starts. 2819 Segdata.Filelen = bss.Vaddr - Segdata.Vaddr 2820 2821 if len(Segpdata.Sections) > 0 { 2822 va = uint64(Rnd(int64(va), *FlagRound)) 2823 order = append(order, &Segpdata) 2824 Segpdata.Rwx = 04 2825 Segpdata.Vaddr = va 2826 // Segpdata.Sections is intended to contain just one section. 2827 // Loop through the slice anyway for consistency. 2828 for _, s := range Segpdata.Sections { 2829 va = uint64(Rnd(int64(va), int64(s.Align))) 2830 s.Vaddr = va 2831 va += s.Length 2832 } 2833 Segpdata.Length = va - Segpdata.Vaddr 2834 } 2835 2836 if len(Segxdata.Sections) > 0 { 2837 va = uint64(Rnd(int64(va), *FlagRound)) 2838 order = append(order, &Segxdata) 2839 Segxdata.Rwx = 04 2840 Segxdata.Vaddr = va 2841 // Segxdata.Sections is intended to contain just one section. 2842 // Loop through the slice anyway for consistency. 2843 for _, s := range Segxdata.Sections { 2844 va = uint64(Rnd(int64(va), int64(s.Align))) 2845 s.Vaddr = va 2846 va += s.Length 2847 } 2848 Segxdata.Length = va - Segxdata.Vaddr 2849 } 2850 2851 va = uint64(Rnd(int64(va), *FlagRound)) 2852 order = append(order, &Segdwarf) 2853 Segdwarf.Rwx = 06 2854 Segdwarf.Vaddr = va 2855 for i, s := range Segdwarf.Sections { 2856 vlen := int64(s.Length) 2857 if i+1 < len(Segdwarf.Sections) { 2858 vlen = int64(Segdwarf.Sections[i+1].Vaddr - s.Vaddr) 2859 } 2860 s.Vaddr = va 2861 va += uint64(vlen) 2862 if ctxt.HeadType == objabi.Hwindows { 2863 va = uint64(Rnd(int64(va), PEFILEALIGN)) 2864 } 2865 Segdwarf.Length = va - Segdwarf.Vaddr 2866 } 2867 2868 ldr := ctxt.loader 2869 var ( 2870 rodata = ldr.SymSect(ldr.LookupOrCreateSym("runtime.rodata", 0)) 2871 symtab = ldr.SymSect(ldr.LookupOrCreateSym("runtime.symtab", 0)) 2872 pclntab = ldr.SymSect(ldr.LookupOrCreateSym("runtime.pclntab", 0)) 2873 types = ldr.SymSect(ldr.LookupOrCreateSym("runtime.types", 0)) 2874 ) 2875 2876 for _, s := range ctxt.datap { 2877 if sect := ldr.SymSect(s); sect != nil { 2878 ldr.AddToSymValue(s, int64(sect.Vaddr)) 2879 } 2880 v := ldr.SymValue(s) 2881 for sub := ldr.SubSym(s); sub != 0; sub = ldr.SubSym(sub) { 2882 ldr.AddToSymValue(sub, v) 2883 } 2884 } 2885 2886 for _, si := range dwarfp { 2887 for _, s := range si.syms { 2888 if sect := ldr.SymSect(s); sect != nil { 2889 ldr.AddToSymValue(s, int64(sect.Vaddr)) 2890 } 2891 sub := ldr.SubSym(s) 2892 if sub != 0 { 2893 panic(fmt.Sprintf("unexpected sub-sym for %s %s", ldr.SymName(s), ldr.SymType(s).String())) 2894 } 2895 v := ldr.SymValue(s) 2896 for ; sub != 0; sub = ldr.SubSym(sub) { 2897 ldr.AddToSymValue(s, v) 2898 } 2899 } 2900 } 2901 2902 for _, s := range sehp.pdata { 2903 if sect := ldr.SymSect(s); sect != nil { 2904 ldr.AddToSymValue(s, int64(sect.Vaddr)) 2905 } 2906 } 2907 for _, s := range sehp.xdata { 2908 if sect := ldr.SymSect(s); sect != nil { 2909 ldr.AddToSymValue(s, int64(sect.Vaddr)) 2910 } 2911 } 2912 2913 if ctxt.BuildMode == BuildModeShared { 2914 s := ldr.LookupOrCreateSym("go:link.abihashbytes", 0) 2915 sect := ldr.SymSect(ldr.LookupOrCreateSym(".note.go.abihash", 0)) 2916 ldr.SetSymSect(s, sect) 2917 ldr.SetSymValue(s, int64(sect.Vaddr+16)) 2918 } 2919 2920 // If there are multiple text sections, create runtime.text.n for 2921 // their section Vaddr, using n for index 2922 n := 1 2923 for _, sect := range Segtext.Sections[1:] { 2924 if sect.Name != ".text" { 2925 break 2926 } 2927 symname := fmt.Sprintf("runtime.text.%d", n) 2928 if ctxt.HeadType != objabi.Haix || ctxt.LinkMode != LinkExternal { 2929 // Addresses are already set on AIX with external linker 2930 // because these symbols are part of their sections. 2931 ctxt.xdefine(symname, sym.STEXT, int64(sect.Vaddr)) 2932 } 2933 n++ 2934 } 2935 2936 ctxt.xdefine("runtime.rodata", sym.SRODATA, int64(rodata.Vaddr)) 2937 ctxt.xdefine("runtime.erodata", sym.SRODATA, int64(rodata.Vaddr+rodata.Length)) 2938 ctxt.xdefine("runtime.types", sym.SRODATA, int64(types.Vaddr)) 2939 ctxt.xdefine("runtime.etypes", sym.SRODATA, int64(types.Vaddr+types.Length)) 2940 2941 s := ldr.Lookup("runtime.gcdata", 0) 2942 ldr.SetAttrLocal(s, true) 2943 ctxt.xdefine("runtime.egcdata", sym.SRODATA, ldr.SymAddr(s)+ldr.SymSize(s)) 2944 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.egcdata", 0), ldr.SymSect(s)) 2945 2946 s = ldr.LookupOrCreateSym("runtime.gcbss", 0) 2947 ldr.SetAttrLocal(s, true) 2948 ctxt.xdefine("runtime.egcbss", sym.SRODATA, ldr.SymAddr(s)+ldr.SymSize(s)) 2949 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.egcbss", 0), ldr.SymSect(s)) 2950 2951 ctxt.xdefine("runtime.symtab", sym.SRODATA, int64(symtab.Vaddr)) 2952 ctxt.xdefine("runtime.esymtab", sym.SRODATA, int64(symtab.Vaddr+symtab.Length)) 2953 ctxt.xdefine("runtime.pclntab", sym.SRODATA, int64(pclntab.Vaddr)) 2954 ctxt.defineInternal("runtime.pcheader", sym.SRODATA) 2955 ctxt.defineInternal("runtime.funcnametab", sym.SRODATA) 2956 ctxt.defineInternal("runtime.cutab", sym.SRODATA) 2957 ctxt.defineInternal("runtime.filetab", sym.SRODATA) 2958 ctxt.defineInternal("runtime.pctab", sym.SRODATA) 2959 ctxt.defineInternal("runtime.functab", sym.SRODATA) 2960 ctxt.xdefine("runtime.epclntab", sym.SRODATA, int64(pclntab.Vaddr+pclntab.Length)) 2961 ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr)) 2962 ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr+noptr.Length)) 2963 ctxt.xdefine("runtime.bss", sym.SBSS, int64(bss.Vaddr)) 2964 ctxt.xdefine("runtime.ebss", sym.SBSS, int64(bss.Vaddr+bss.Length)) 2965 ctxt.xdefine("runtime.data", sym.SDATA, int64(data.Vaddr)) 2966 ctxt.xdefine("runtime.edata", sym.SDATA, int64(data.Vaddr+data.Length)) 2967 ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr)) 2968 ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length)) 2969 ctxt.xdefine("runtime.covctrs", sym.SCOVERAGE_COUNTER, int64(noptrbss.Vaddr+covCounterDataStartOff)) 2970 ctxt.xdefine("runtime.ecovctrs", sym.SCOVERAGE_COUNTER, int64(noptrbss.Vaddr+covCounterDataStartOff+covCounterDataLen)) 2971 ctxt.xdefine("runtime.end", sym.SBSS, int64(Segdata.Vaddr+Segdata.Length)) 2972 2973 if fuzzCounters != nil { 2974 ctxt.xdefine("runtime.__start___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr)) 2975 ctxt.xdefine("runtime.__stop___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr+fuzzCounters.Length)) 2976 ctxt.xdefine("internal/fuzz._counters", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr)) 2977 ctxt.xdefine("internal/fuzz._ecounters", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr+fuzzCounters.Length)) 2978 } 2979 2980 if ctxt.IsSolaris() { 2981 // On Solaris, in the runtime it sets the external names of the 2982 // end symbols. Unset them and define separate symbols, so we 2983 // keep both. 2984 etext := ldr.Lookup("runtime.etext", 0) 2985 edata := ldr.Lookup("runtime.edata", 0) 2986 end := ldr.Lookup("runtime.end", 0) 2987 ldr.SetSymExtname(etext, "runtime.etext") 2988 ldr.SetSymExtname(edata, "runtime.edata") 2989 ldr.SetSymExtname(end, "runtime.end") 2990 ctxt.xdefine("_etext", ldr.SymType(etext), ldr.SymValue(etext)) 2991 ctxt.xdefine("_edata", ldr.SymType(edata), ldr.SymValue(edata)) 2992 ctxt.xdefine("_end", ldr.SymType(end), ldr.SymValue(end)) 2993 ldr.SetSymSect(ldr.Lookup("_etext", 0), ldr.SymSect(etext)) 2994 ldr.SetSymSect(ldr.Lookup("_edata", 0), ldr.SymSect(edata)) 2995 ldr.SetSymSect(ldr.Lookup("_end", 0), ldr.SymSect(end)) 2996 } 2997 2998 if ctxt.IsPPC64() && ctxt.IsElf() { 2999 // Resolve .TOC. symbols for all objects. Only one TOC region is supported. If a 3000 // GOT section is present, compute it as suggested by the ELFv2 ABI. Otherwise, 3001 // choose a similar offset from the start of the data segment. 3002 tocAddr := int64(Segdata.Vaddr) + 0x8000 3003 if gotAddr := ldr.SymValue(ctxt.GOT); gotAddr != 0 { 3004 tocAddr = gotAddr + 0x8000 3005 } 3006 for i := range ctxt.DotTOC { 3007 if i >= sym.SymVerABICount && i < sym.SymVerStatic { // these versions are not used currently 3008 continue 3009 } 3010 if toc := ldr.Lookup(".TOC.", i); toc != 0 { 3011 ldr.SetSymValue(toc, tocAddr) 3012 } 3013 } 3014 } 3015 3016 return order 3017} 3018 3019// layout assigns file offsets and lengths to the segments in order. 3020// Returns the file size containing all the segments. 3021func (ctxt *Link) layout(order []*sym.Segment) uint64 { 3022 var prev *sym.Segment 3023 for _, seg := range order { 3024 if prev == nil { 3025 seg.Fileoff = uint64(HEADR) 3026 } else { 3027 switch ctxt.HeadType { 3028 default: 3029 // Assuming the previous segment was 3030 // aligned, the following rounding 3031 // should ensure that this segment's 3032 // VA ≡ Fileoff mod FlagRound. 3033 seg.Fileoff = uint64(Rnd(int64(prev.Fileoff+prev.Filelen), *FlagRound)) 3034 if seg.Vaddr%uint64(*FlagRound) != seg.Fileoff%uint64(*FlagRound) { 3035 Exitf("bad segment rounding (Vaddr=%#x Fileoff=%#x FlagRound=%#x)", seg.Vaddr, seg.Fileoff, *FlagRound) 3036 } 3037 case objabi.Hwindows: 3038 seg.Fileoff = prev.Fileoff + uint64(Rnd(int64(prev.Filelen), PEFILEALIGN)) 3039 case objabi.Hplan9: 3040 seg.Fileoff = prev.Fileoff + prev.Filelen 3041 } 3042 } 3043 if seg != &Segdata { 3044 // Link.address already set Segdata.Filelen to 3045 // account for BSS. 3046 seg.Filelen = seg.Length 3047 } 3048 prev = seg 3049 } 3050 return prev.Fileoff + prev.Filelen 3051} 3052 3053// add a trampoline with symbol s (to be laid down after the current function) 3054func (ctxt *Link) AddTramp(s *loader.SymbolBuilder) { 3055 s.SetType(sym.STEXT) 3056 s.SetReachable(true) 3057 s.SetOnList(true) 3058 ctxt.tramps = append(ctxt.tramps, s.Sym()) 3059 if *FlagDebugTramp > 0 && ctxt.Debugvlog > 0 { 3060 ctxt.Logf("trampoline %s inserted\n", s.Name()) 3061 } 3062} 3063 3064// compressSyms compresses syms and returns the contents of the 3065// compressed section. If the section would get larger, it returns nil. 3066func compressSyms(ctxt *Link, syms []loader.Sym) []byte { 3067 ldr := ctxt.loader 3068 var total int64 3069 for _, sym := range syms { 3070 total += ldr.SymSize(sym) 3071 } 3072 3073 var buf bytes.Buffer 3074 if ctxt.IsELF { 3075 switch ctxt.Arch.PtrSize { 3076 case 8: 3077 binary.Write(&buf, ctxt.Arch.ByteOrder, elf.Chdr64{ 3078 Type: uint32(elf.COMPRESS_ZLIB), 3079 Size: uint64(total), 3080 Addralign: uint64(ctxt.Arch.Alignment), 3081 }) 3082 case 4: 3083 binary.Write(&buf, ctxt.Arch.ByteOrder, elf.Chdr32{ 3084 Type: uint32(elf.COMPRESS_ZLIB), 3085 Size: uint32(total), 3086 Addralign: uint32(ctxt.Arch.Alignment), 3087 }) 3088 default: 3089 log.Fatalf("can't compress header size:%d", ctxt.Arch.PtrSize) 3090 } 3091 } else { 3092 buf.Write([]byte("ZLIB")) 3093 var sizeBytes [8]byte 3094 binary.BigEndian.PutUint64(sizeBytes[:], uint64(total)) 3095 buf.Write(sizeBytes[:]) 3096 } 3097 3098 var relocbuf []byte // temporary buffer for applying relocations 3099 3100 // Using zlib.BestSpeed achieves very nearly the same 3101 // compression levels of zlib.DefaultCompression, but takes 3102 // substantially less time. This is important because DWARF 3103 // compression can be a significant fraction of link time. 3104 z, err := zlib.NewWriterLevel(&buf, zlib.BestSpeed) 3105 if err != nil { 3106 log.Fatalf("NewWriterLevel failed: %s", err) 3107 } 3108 st := ctxt.makeRelocSymState() 3109 for _, s := range syms { 3110 // Symbol data may be read-only. Apply relocations in a 3111 // temporary buffer, and immediately write it out. 3112 P := ldr.Data(s) 3113 relocs := ldr.Relocs(s) 3114 if relocs.Count() != 0 { 3115 relocbuf = append(relocbuf[:0], P...) 3116 P = relocbuf 3117 st.relocsym(s, P) 3118 } 3119 if _, err := z.Write(P); err != nil { 3120 log.Fatalf("compression failed: %s", err) 3121 } 3122 for i := ldr.SymSize(s) - int64(len(P)); i > 0; { 3123 b := zeros[:] 3124 if i < int64(len(b)) { 3125 b = b[:i] 3126 } 3127 n, err := z.Write(b) 3128 if err != nil { 3129 log.Fatalf("compression failed: %s", err) 3130 } 3131 i -= int64(n) 3132 } 3133 } 3134 if err := z.Close(); err != nil { 3135 log.Fatalf("compression failed: %s", err) 3136 } 3137 if int64(buf.Len()) >= total { 3138 // Compression didn't save any space. 3139 return nil 3140 } 3141 return buf.Bytes() 3142} 3143