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