github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/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/default/utils/6l/obj.c 3 // https://bitbucket.org/inferno-os/inferno-os/src/default/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 "cmd/internal/gcprog" 37 "cmd/internal/objabi" 38 "cmd/internal/sys" 39 "cmd/link/internal/sym" 40 "compress/zlib" 41 "encoding/binary" 42 "fmt" 43 "log" 44 "os" 45 "sort" 46 "strconv" 47 "strings" 48 "sync" 49 ) 50 51 // isRuntimeDepPkg reports whether pkg is the runtime package or its dependency 52 func isRuntimeDepPkg(pkg string) bool { 53 switch pkg { 54 case "runtime", 55 "sync/atomic", // runtime may call to sync/atomic, due to go:linkname 56 "internal/bytealg", // for IndexByte 57 "internal/cpu": // for cpu features 58 return true 59 } 60 return strings.HasPrefix(pkg, "runtime/internal/") && !strings.HasSuffix(pkg, "_test") 61 } 62 63 // Estimate the max size needed to hold any new trampolines created for this function. This 64 // is used to determine when the section can be split if it becomes too large, to ensure that 65 // the trampolines are in the same section as the function that uses them. 66 func maxSizeTrampolinesPPC64(s *sym.Symbol, isTramp bool) uint64 { 67 // If thearch.Trampoline is nil, then trampoline support is not available on this arch. 68 // A trampoline does not need any dependent trampolines. 69 if thearch.Trampoline == nil || isTramp { 70 return 0 71 } 72 73 n := uint64(0) 74 for ri := range s.R { 75 r := &s.R[ri] 76 if r.Type.IsDirectJump() { 77 n++ 78 } 79 } 80 // Trampolines in ppc64 are 4 instructions. 81 return n * 16 82 } 83 84 // detect too-far jumps in function s, and add trampolines if necessary 85 // ARM, PPC64 & PPC64LE support trampoline insertion for internal and external linking 86 // On PPC64 & PPC64LE the text sections might be split but will still insert trampolines 87 // where necessary. 88 func trampoline(ctxt *Link, s *sym.Symbol) { 89 if thearch.Trampoline == nil { 90 return // no need or no support of trampolines on this arch 91 } 92 93 for ri := range s.R { 94 r := &s.R[ri] 95 if !r.Type.IsDirectJump() { 96 continue 97 } 98 if Symaddr(r.Sym) == 0 && r.Sym.Type != sym.SDYNIMPORT { 99 if r.Sym.File != s.File { 100 if !isRuntimeDepPkg(s.File) || !isRuntimeDepPkg(r.Sym.File) { 101 ctxt.ErrorUnresolved(s, r) 102 } 103 // runtime and its dependent packages may call to each other. 104 // they are fine, as they will be laid down together. 105 } 106 continue 107 } 108 109 thearch.Trampoline(ctxt, r, s) 110 } 111 112 } 113 114 // relocsym resolve relocations in "s". The main loop walks through 115 // the list of relocations attached to "s" and resolves them where 116 // applicable. Relocations are often architecture-specific, requiring 117 // calls into the 'archreloc' and/or 'archrelocvariant' functions for 118 // the architecture. When external linking is in effect, it may not be 119 // possible to completely resolve the address/offset for a symbol, in 120 // which case the goal is to lay the groundwork for turning a given 121 // relocation into an external reloc (to be applied by the external 122 // linker). For more on how relocations work in general, see 123 // 124 // "Linkers and Loaders", by John R. Levine (Morgan Kaufmann, 1999), ch. 7 125 // 126 // This is a performance-critical function for the linker; be careful 127 // to avoid introducing unnecessary allocations in the main loop. 128 func relocsym(ctxt *Link, s *sym.Symbol) { 129 for ri := int32(0); ri < int32(len(s.R)); ri++ { 130 r := &s.R[ri] 131 if r.Done { 132 // Relocation already processed by an earlier phase. 133 continue 134 } 135 r.Done = true 136 off := r.Off 137 siz := int32(r.Siz) 138 if off < 0 || off+siz > int32(len(s.P)) { 139 rname := "" 140 if r.Sym != nil { 141 rname = r.Sym.Name 142 } 143 Errorf(s, "invalid relocation %s: %d+%d not in [%d,%d)", rname, off, siz, 0, len(s.P)) 144 continue 145 } 146 147 if r.Sym != nil && ((r.Sym.Type == sym.Sxxx && !r.Sym.Attr.VisibilityHidden()) || r.Sym.Type == sym.SXREF) { 148 // When putting the runtime but not main into a shared library 149 // these symbols are undefined and that's OK. 150 if ctxt.BuildMode == BuildModeShared { 151 if r.Sym.Name == "main.main" || r.Sym.Name == "main.init" { 152 r.Sym.Type = sym.SDYNIMPORT 153 } else if strings.HasPrefix(r.Sym.Name, "go.info.") { 154 // Skip go.info symbols. They are only needed to communicate 155 // DWARF info between the compiler and linker. 156 continue 157 } 158 } else { 159 ctxt.ErrorUnresolved(s, r) 160 continue 161 } 162 } 163 164 if r.Type >= 256 { 165 continue 166 } 167 if r.Siz == 0 { // informational relocation - no work to do 168 continue 169 } 170 if r.Type == objabi.R_DWARFFILEREF { 171 // These should have been processed previously during 172 // line table writing. 173 Errorf(s, "orphan R_DWARFFILEREF reloc to %v", r.Sym.Name) 174 continue 175 } 176 177 // We need to be able to reference dynimport symbols when linking against 178 // shared libraries, and Solaris, Darwin and AIX need it always 179 if ctxt.HeadType != objabi.Hsolaris && ctxt.HeadType != objabi.Hdarwin && ctxt.HeadType != objabi.Haix && r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT && !ctxt.DynlinkingGo() && !r.Sym.Attr.SubSymbol() { 180 if !(ctxt.Arch.Family == sys.PPC64 && ctxt.LinkMode == LinkExternal && r.Sym.Name == ".TOC.") { 181 Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", r.Sym.Name, r.Sym.Type, r.Sym.Type, r.Type, sym.RelocName(ctxt.Arch, r.Type)) 182 } 183 } 184 if r.Sym != nil && r.Sym.Type != sym.STLSBSS && r.Type != objabi.R_WEAKADDROFF && !r.Sym.Attr.Reachable() { 185 Errorf(s, "unreachable sym in relocation: %s", r.Sym.Name) 186 } 187 188 // TODO(mundaym): remove this special case - see issue 14218. 189 if ctxt.Arch.Family == sys.S390X { 190 switch r.Type { 191 case objabi.R_PCRELDBL: 192 r.Type = objabi.R_PCREL 193 r.Variant = sym.RV_390_DBL 194 case objabi.R_CALL: 195 r.Variant = sym.RV_390_DBL 196 } 197 } 198 199 var o int64 200 switch r.Type { 201 default: 202 switch siz { 203 default: 204 Errorf(s, "bad reloc size %#x for %s", uint32(siz), r.Sym.Name) 205 case 1: 206 o = int64(s.P[off]) 207 case 2: 208 o = int64(ctxt.Arch.ByteOrder.Uint16(s.P[off:])) 209 case 4: 210 o = int64(ctxt.Arch.ByteOrder.Uint32(s.P[off:])) 211 case 8: 212 o = int64(ctxt.Arch.ByteOrder.Uint64(s.P[off:])) 213 } 214 if offset, ok := thearch.Archreloc(ctxt, r, s, o); ok { 215 o = offset 216 } else { 217 Errorf(s, "unknown reloc to %v: %d (%s)", r.Sym.Name, r.Type, sym.RelocName(ctxt.Arch, r.Type)) 218 } 219 case objabi.R_TLS_LE: 220 isAndroidX86 := objabi.GOOS == "android" && (ctxt.Arch.InFamily(sys.AMD64, sys.I386)) 221 222 if ctxt.LinkMode == LinkExternal && ctxt.IsELF && !isAndroidX86 { 223 r.Done = false 224 if r.Sym == nil { 225 r.Sym = ctxt.Tlsg 226 } 227 r.Xsym = r.Sym 228 r.Xadd = r.Add 229 o = 0 230 if ctxt.Arch.Family != sys.AMD64 { 231 o = r.Add 232 } 233 break 234 } 235 236 if ctxt.IsELF && ctxt.Arch.Family == sys.ARM { 237 // On ELF ARM, the thread pointer is 8 bytes before 238 // the start of the thread-local data block, so add 8 239 // to the actual TLS offset (r->sym->value). 240 // This 8 seems to be a fundamental constant of 241 // ELF on ARM (or maybe Glibc on ARM); it is not 242 // related to the fact that our own TLS storage happens 243 // to take up 8 bytes. 244 o = 8 + r.Sym.Value 245 } else if ctxt.IsELF || ctxt.HeadType == objabi.Hplan9 || ctxt.HeadType == objabi.Hdarwin || isAndroidX86 { 246 o = int64(ctxt.Tlsoffset) + r.Add 247 } else if ctxt.HeadType == objabi.Hwindows { 248 o = r.Add 249 } else { 250 log.Fatalf("unexpected R_TLS_LE relocation for %v", ctxt.HeadType) 251 } 252 case objabi.R_TLS_IE: 253 isAndroidX86 := objabi.GOOS == "android" && (ctxt.Arch.InFamily(sys.AMD64, sys.I386)) 254 255 if ctxt.LinkMode == LinkExternal && ctxt.IsELF && !isAndroidX86 { 256 r.Done = false 257 if r.Sym == nil { 258 r.Sym = ctxt.Tlsg 259 } 260 r.Xsym = r.Sym 261 r.Xadd = r.Add 262 o = 0 263 if ctxt.Arch.Family != sys.AMD64 { 264 o = r.Add 265 } 266 break 267 } 268 if ctxt.BuildMode == BuildModePIE && ctxt.IsELF { 269 // We are linking the final executable, so we 270 // can optimize any TLS IE relocation to LE. 271 if thearch.TLSIEtoLE == nil { 272 log.Fatalf("internal linking of TLS IE not supported on %v", ctxt.Arch.Family) 273 } 274 thearch.TLSIEtoLE(s, int(off), int(r.Siz)) 275 o = int64(ctxt.Tlsoffset) 276 // TODO: o += r.Add when ctxt.Arch.Family != sys.AMD64? 277 // Why do we treat r.Add differently on AMD64? 278 // Is the external linker using Xadd at all? 279 } else { 280 log.Fatalf("cannot handle R_TLS_IE (sym %s) when linking internally", s.Name) 281 } 282 case objabi.R_ADDR: 283 if ctxt.LinkMode == LinkExternal && r.Sym.Type != sym.SCONST { 284 r.Done = false 285 286 // set up addend for eventual relocation via outer symbol. 287 rs := r.Sym 288 289 r.Xadd = r.Add 290 for rs.Outer != nil { 291 r.Xadd += Symaddr(rs) - Symaddr(rs.Outer) 292 rs = rs.Outer 293 } 294 295 if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil { 296 Errorf(s, "missing section for relocation target %s", rs.Name) 297 } 298 r.Xsym = rs 299 300 o = r.Xadd 301 if ctxt.IsELF { 302 if ctxt.Arch.Family == sys.AMD64 { 303 o = 0 304 } 305 } else if ctxt.HeadType == objabi.Hdarwin { 306 if rs.Type != sym.SHOSTOBJ { 307 o += Symaddr(rs) 308 } 309 } else if ctxt.HeadType == objabi.Hwindows { 310 // nothing to do 311 } else { 312 Errorf(s, "unhandled pcrel relocation to %s on %v", rs.Name, ctxt.HeadType) 313 } 314 315 break 316 } 317 318 // On AIX, a second relocation must be done by the loader, 319 // as section addresses can change once loaded. 320 // The "default" symbol address is still needed by the loader so 321 // the current relocation can't be skipped. 322 if ctxt.HeadType == objabi.Haix && r.Sym.Type != sym.SDYNIMPORT { 323 // It's not possible to make a loader relocation in a 324 // symbol which is not inside .data section. 325 // FIXME: It should be forbidden to have R_ADDR from a 326 // symbol which isn't in .data. However, as .text has the 327 // same address once loaded, this is possible. 328 if s.Sect.Seg == &Segdata { 329 Xcoffadddynrel(ctxt, s, r) 330 } 331 } 332 333 o = Symaddr(r.Sym) + r.Add 334 335 // On amd64, 4-byte offsets will be sign-extended, so it is impossible to 336 // access more than 2GB of static data; fail at link time is better than 337 // fail at runtime. See https://golang.org/issue/7980. 338 // Instead of special casing only amd64, we treat this as an error on all 339 // 64-bit architectures so as to be future-proof. 340 if int32(o) < 0 && ctxt.Arch.PtrSize > 4 && siz == 4 { 341 Errorf(s, "non-pc-relative relocation address for %s is too big: %#x (%#x + %#x)", r.Sym.Name, uint64(o), Symaddr(r.Sym), r.Add) 342 errorexit() 343 } 344 case objabi.R_DWARFSECREF: 345 if r.Sym.Sect == nil { 346 Errorf(s, "missing DWARF section for relocation target %s", r.Sym.Name) 347 } 348 349 if ctxt.LinkMode == LinkExternal { 350 r.Done = false 351 352 // On most platforms, the external linker needs to adjust DWARF references 353 // as it combines DWARF sections. However, on Darwin, dsymutil does the 354 // DWARF linking, and it understands how to follow section offsets. 355 // Leaving in the relocation records confuses it (see 356 // https://golang.org/issue/22068) so drop them for Darwin. 357 if ctxt.HeadType == objabi.Hdarwin { 358 r.Done = true 359 } 360 361 // PE code emits IMAGE_REL_I386_SECREL and IMAGE_REL_AMD64_SECREL 362 // for R_DWARFSECREF relocations, while R_ADDR is replaced with 363 // IMAGE_REL_I386_DIR32, IMAGE_REL_AMD64_ADDR64 and IMAGE_REL_AMD64_ADDR32. 364 // Do not replace R_DWARFSECREF with R_ADDR for windows - 365 // let PE code emit correct relocations. 366 if ctxt.HeadType != objabi.Hwindows { 367 r.Type = objabi.R_ADDR 368 } 369 370 r.Xsym = ctxt.Syms.ROLookup(r.Sym.Sect.Name, 0) 371 r.Xadd = r.Add + Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr) 372 373 o = r.Xadd 374 if ctxt.IsELF && ctxt.Arch.Family == sys.AMD64 { 375 o = 0 376 } 377 break 378 } 379 o = Symaddr(r.Sym) + r.Add - int64(r.Sym.Sect.Vaddr) 380 case objabi.R_WEAKADDROFF: 381 if !r.Sym.Attr.Reachable() { 382 continue 383 } 384 fallthrough 385 case objabi.R_ADDROFF: 386 // The method offset tables using this relocation expect the offset to be relative 387 // to the start of the first text section, even if there are multiple. 388 if r.Sym.Sect.Name == ".text" { 389 o = Symaddr(r.Sym) - int64(Segtext.Sections[0].Vaddr) + r.Add 390 } else { 391 o = Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr) + r.Add 392 } 393 394 case objabi.R_ADDRCUOFF: 395 // debug_range and debug_loc elements use this relocation type to get an 396 // offset from the start of the compile unit. 397 o = Symaddr(r.Sym) + r.Add - Symaddr(r.Sym.Lib.Textp[0]) 398 399 // r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call. 400 case objabi.R_GOTPCREL: 401 if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin && r.Sym != nil && r.Sym.Type != sym.SCONST { 402 r.Done = false 403 r.Xadd = r.Add 404 r.Xadd -= int64(r.Siz) // relative to address after the relocated chunk 405 r.Xsym = r.Sym 406 407 o = r.Xadd 408 o += int64(r.Siz) 409 break 410 } 411 fallthrough 412 case objabi.R_CALL, objabi.R_PCREL: 413 if ctxt.LinkMode == LinkExternal && r.Sym != nil && r.Sym.Type != sym.SCONST && (r.Sym.Sect != s.Sect || r.Type == objabi.R_GOTPCREL) { 414 r.Done = false 415 416 // set up addend for eventual relocation via outer symbol. 417 rs := r.Sym 418 419 r.Xadd = r.Add 420 for rs.Outer != nil { 421 r.Xadd += Symaddr(rs) - Symaddr(rs.Outer) 422 rs = rs.Outer 423 } 424 425 r.Xadd -= int64(r.Siz) // relative to address after the relocated chunk 426 if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil { 427 Errorf(s, "missing section for relocation target %s", rs.Name) 428 } 429 r.Xsym = rs 430 431 o = r.Xadd 432 if ctxt.IsELF { 433 if ctxt.Arch.Family == sys.AMD64 { 434 o = 0 435 } 436 } else if ctxt.HeadType == objabi.Hdarwin { 437 if r.Type == objabi.R_CALL { 438 if ctxt.LinkMode == LinkExternal && rs.Type == sym.SDYNIMPORT { 439 switch ctxt.Arch.Family { 440 case sys.AMD64: 441 // AMD64 dynamic relocations are relative to the end of the relocation. 442 o += int64(r.Siz) 443 case sys.I386: 444 // I386 dynamic relocations are relative to the start of the section. 445 o -= int64(r.Off) // offset in symbol 446 o -= int64(s.Value - int64(s.Sect.Vaddr)) // offset of symbol in section 447 } 448 } else { 449 if rs.Type != sym.SHOSTOBJ { 450 o += int64(uint64(Symaddr(rs)) - rs.Sect.Vaddr) 451 } 452 o -= int64(r.Off) // relative to section offset, not symbol 453 } 454 } else if ctxt.Arch.Family == sys.ARM { 455 // see ../arm/asm.go:/machoreloc1 456 o += Symaddr(rs) - s.Value - int64(r.Off) 457 } else { 458 o += int64(r.Siz) 459 } 460 } else if ctxt.HeadType == objabi.Hwindows && ctxt.Arch.Family == sys.AMD64 { // only amd64 needs PCREL 461 // PE/COFF's PC32 relocation uses the address after the relocated 462 // bytes as the base. Compensate by skewing the addend. 463 o += int64(r.Siz) 464 } else { 465 Errorf(s, "unhandled pcrel relocation to %s on %v", rs.Name, ctxt.HeadType) 466 } 467 468 break 469 } 470 471 o = 0 472 if r.Sym != nil { 473 o += Symaddr(r.Sym) 474 } 475 476 o += r.Add - (s.Value + int64(r.Off) + int64(r.Siz)) 477 case objabi.R_SIZE: 478 o = r.Sym.Size + r.Add 479 } 480 481 if r.Variant != sym.RV_NONE { 482 o = thearch.Archrelocvariant(ctxt, r, s, o) 483 } 484 485 if false { 486 nam := "<nil>" 487 var addr int64 488 if r.Sym != nil { 489 nam = r.Sym.Name 490 addr = Symaddr(r.Sym) 491 } 492 xnam := "<nil>" 493 if r.Xsym != nil { 494 xnam = r.Xsym.Name 495 } 496 fmt.Printf("relocate %s %#x (%#x+%#x, size %d) => %s %#x +%#x (xsym: %s +%#x) [type %d (%s)/%d, %x]\n", s.Name, s.Value+int64(off), s.Value, r.Off, r.Siz, nam, addr, r.Add, xnam, r.Xadd, r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Variant, o) 497 } 498 switch siz { 499 default: 500 Errorf(s, "bad reloc size %#x for %s", uint32(siz), r.Sym.Name) 501 fallthrough 502 503 // TODO(rsc): Remove. 504 case 1: 505 s.P[off] = byte(int8(o)) 506 case 2: 507 if o != int64(int16(o)) { 508 Errorf(s, "relocation address for %s is too big: %#x", r.Sym.Name, o) 509 } 510 i16 := int16(o) 511 ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(i16)) 512 case 4: 513 if r.Type == objabi.R_PCREL || r.Type == objabi.R_CALL { 514 if o != int64(int32(o)) { 515 Errorf(s, "pc-relative relocation address for %s is too big: %#x", r.Sym.Name, o) 516 } 517 } else { 518 if o != int64(int32(o)) && o != int64(uint32(o)) { 519 Errorf(s, "non-pc-relative relocation address for %s is too big: %#x", r.Sym.Name, uint64(o)) 520 } 521 } 522 523 fl := int32(o) 524 ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(fl)) 525 case 8: 526 ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(o)) 527 } 528 } 529 } 530 531 func (ctxt *Link) reloc() { 532 if ctxt.Debugvlog != 0 { 533 ctxt.Logf("%5.2f reloc\n", Cputime()) 534 } 535 536 for _, s := range ctxt.Textp { 537 relocsym(ctxt, s) 538 } 539 for _, s := range datap { 540 relocsym(ctxt, s) 541 } 542 for _, s := range dwarfp { 543 relocsym(ctxt, s) 544 } 545 } 546 547 func windynrelocsym(ctxt *Link, rel, s *sym.Symbol) { 548 for ri := range s.R { 549 r := &s.R[ri] 550 targ := r.Sym 551 if targ == nil { 552 continue 553 } 554 if !targ.Attr.Reachable() { 555 if r.Type == objabi.R_WEAKADDROFF { 556 continue 557 } 558 Errorf(s, "dynamic relocation to unreachable symbol %s", targ.Name) 559 } 560 if r.Sym.Plt() == -2 && r.Sym.Got() != -2 { // make dynimport JMP table for PE object files. 561 targ.SetPlt(int32(rel.Size)) 562 r.Sym = rel 563 r.Add = int64(targ.Plt()) 564 565 // jmp *addr 566 switch ctxt.Arch.Family { 567 default: 568 Errorf(s, "unsupported arch %v", ctxt.Arch.Family) 569 return 570 case sys.I386: 571 rel.AddUint8(0xff) 572 rel.AddUint8(0x25) 573 rel.AddAddr(ctxt.Arch, targ) 574 rel.AddUint8(0x90) 575 rel.AddUint8(0x90) 576 case sys.AMD64: 577 rel.AddUint8(0xff) 578 rel.AddUint8(0x24) 579 rel.AddUint8(0x25) 580 rel.AddAddrPlus4(targ, 0) 581 rel.AddUint8(0x90) 582 } 583 } else if r.Sym.Plt() >= 0 { 584 r.Sym = rel 585 r.Add = int64(targ.Plt()) 586 } 587 } 588 } 589 590 // windynrelocsyms generates jump table to C library functions that will be 591 // added later. windynrelocsyms writes the table into .rel symbol. 592 func (ctxt *Link) windynrelocsyms() { 593 if !(ctxt.HeadType == objabi.Hwindows && iscgo && ctxt.LinkMode == LinkInternal) { 594 return 595 } 596 if ctxt.Debugvlog != 0 { 597 ctxt.Logf("%5.2f windynrelocsyms\n", Cputime()) 598 } 599 600 /* relocation table */ 601 rel := ctxt.Syms.Lookup(".rel", 0) 602 rel.Attr |= sym.AttrReachable 603 rel.Type = sym.STEXT 604 ctxt.Textp = append(ctxt.Textp, rel) 605 606 for _, s := range ctxt.Textp { 607 if s == rel { 608 continue 609 } 610 windynrelocsym(ctxt, rel, s) 611 } 612 } 613 614 func dynrelocsym(ctxt *Link, s *sym.Symbol) { 615 for ri := range s.R { 616 r := &s.R[ri] 617 if ctxt.BuildMode == BuildModePIE && ctxt.LinkMode == LinkInternal { 618 // It's expected that some relocations will be done 619 // later by relocsym (R_TLS_LE, R_ADDROFF), so 620 // don't worry if Adddynrel returns false. 621 thearch.Adddynrel(ctxt, s, r) 622 continue 623 } 624 625 if r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT || r.Type >= 256 { 626 if r.Sym != nil && !r.Sym.Attr.Reachable() { 627 Errorf(s, "dynamic relocation to unreachable symbol %s", r.Sym.Name) 628 } 629 if !thearch.Adddynrel(ctxt, s, r) { 630 Errorf(s, "unsupported dynamic relocation for symbol %s (type=%d (%s) stype=%d (%s))", r.Sym.Name, r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Sym.Type, r.Sym.Type) 631 } 632 } 633 } 634 } 635 636 func dynreloc(ctxt *Link, data *[sym.SXREF][]*sym.Symbol) { 637 if ctxt.HeadType == objabi.Hwindows { 638 return 639 } 640 // -d suppresses dynamic loader format, so we may as well not 641 // compute these sections or mark their symbols as reachable. 642 if *FlagD { 643 return 644 } 645 if ctxt.Debugvlog != 0 { 646 ctxt.Logf("%5.2f dynreloc\n", Cputime()) 647 } 648 649 for _, s := range ctxt.Textp { 650 dynrelocsym(ctxt, s) 651 } 652 for _, syms := range data { 653 for _, s := range syms { 654 dynrelocsym(ctxt, s) 655 } 656 } 657 if ctxt.IsELF { 658 elfdynhash(ctxt) 659 } 660 } 661 662 func Codeblk(ctxt *Link, addr int64, size int64) { 663 CodeblkPad(ctxt, addr, size, zeros[:]) 664 } 665 func CodeblkPad(ctxt *Link, addr int64, size int64, pad []byte) { 666 if *flagA { 667 ctxt.Logf("codeblk [%#x,%#x) at offset %#x\n", addr, addr+size, ctxt.Out.Offset()) 668 } 669 670 blk(ctxt, ctxt.Textp, addr, size, pad) 671 672 /* again for printing */ 673 if !*flagA { 674 return 675 } 676 677 syms := ctxt.Textp 678 for i, s := range syms { 679 if !s.Attr.Reachable() { 680 continue 681 } 682 if s.Value >= addr { 683 syms = syms[i:] 684 break 685 } 686 } 687 688 eaddr := addr + size 689 for _, s := range syms { 690 if !s.Attr.Reachable() { 691 continue 692 } 693 if s.Value >= eaddr { 694 break 695 } 696 697 if addr < s.Value { 698 ctxt.Logf("%-20s %.8x|", "_", uint64(addr)) 699 for ; addr < s.Value; addr++ { 700 ctxt.Logf(" %.2x", 0) 701 } 702 ctxt.Logf("\n") 703 } 704 705 ctxt.Logf("%.6x\t%-20s\n", uint64(addr), s.Name) 706 q := s.P 707 708 for len(q) >= 16 { 709 ctxt.Logf("%.6x\t% x\n", uint64(addr), q[:16]) 710 addr += 16 711 q = q[16:] 712 } 713 714 if len(q) > 0 { 715 ctxt.Logf("%.6x\t% x\n", uint64(addr), q) 716 addr += int64(len(q)) 717 } 718 } 719 720 if addr < eaddr { 721 ctxt.Logf("%-20s %.8x|", "_", uint64(addr)) 722 for ; addr < eaddr; addr++ { 723 ctxt.Logf(" %.2x", 0) 724 } 725 } 726 } 727 728 func blk(ctxt *Link, syms []*sym.Symbol, addr, size int64, pad []byte) { 729 for i, s := range syms { 730 if !s.Attr.SubSymbol() && s.Value >= addr { 731 syms = syms[i:] 732 break 733 } 734 } 735 736 // This doesn't distinguish the memory size from the file 737 // size, and it lays out the file based on Symbol.Value, which 738 // is the virtual address. DWARF compression changes file sizes, 739 // so dwarfcompress will fix this up later if necessary. 740 eaddr := addr + size 741 for _, s := range syms { 742 if s.Attr.SubSymbol() { 743 continue 744 } 745 if s.Value >= eaddr { 746 break 747 } 748 if s.Value < addr { 749 Errorf(s, "phase error: addr=%#x but sym=%#x type=%d", addr, s.Value, s.Type) 750 errorexit() 751 } 752 if addr < s.Value { 753 ctxt.Out.WriteStringPad("", int(s.Value-addr), pad) 754 addr = s.Value 755 } 756 ctxt.Out.Write(s.P) 757 addr += int64(len(s.P)) 758 if addr < s.Value+s.Size { 759 ctxt.Out.WriteStringPad("", int(s.Value+s.Size-addr), pad) 760 addr = s.Value + s.Size 761 } 762 if addr != s.Value+s.Size { 763 Errorf(s, "phase error: addr=%#x value+size=%#x", addr, s.Value+s.Size) 764 errorexit() 765 } 766 if s.Value+s.Size >= eaddr { 767 break 768 } 769 } 770 771 if addr < eaddr { 772 ctxt.Out.WriteStringPad("", int(eaddr-addr), pad) 773 } 774 ctxt.Out.Flush() 775 } 776 777 func Datblk(ctxt *Link, addr int64, size int64) { 778 if *flagA { 779 ctxt.Logf("datblk [%#x,%#x) at offset %#x\n", addr, addr+size, ctxt.Out.Offset()) 780 } 781 782 blk(ctxt, datap, addr, size, zeros[:]) 783 784 /* again for printing */ 785 if !*flagA { 786 return 787 } 788 789 syms := datap 790 for i, sym := range syms { 791 if sym.Value >= addr { 792 syms = syms[i:] 793 break 794 } 795 } 796 797 eaddr := addr + size 798 for _, sym := range syms { 799 if sym.Value >= eaddr { 800 break 801 } 802 if addr < sym.Value { 803 ctxt.Logf("\t%.8x| 00 ...\n", uint64(addr)) 804 addr = sym.Value 805 } 806 807 ctxt.Logf("%s\n\t%.8x|", sym.Name, uint64(addr)) 808 for i, b := range sym.P { 809 if i > 0 && i%16 == 0 { 810 ctxt.Logf("\n\t%.8x|", uint64(addr)+uint64(i)) 811 } 812 ctxt.Logf(" %.2x", b) 813 } 814 815 addr += int64(len(sym.P)) 816 for ; addr < sym.Value+sym.Size; addr++ { 817 ctxt.Logf(" %.2x", 0) 818 } 819 ctxt.Logf("\n") 820 821 if ctxt.LinkMode != LinkExternal { 822 continue 823 } 824 for i := range sym.R { 825 r := &sym.R[i] // Copying sym.Reloc has measurable impact on performance 826 rsname := "" 827 if r.Sym != nil { 828 rsname = r.Sym.Name 829 } 830 typ := "?" 831 switch r.Type { 832 case objabi.R_ADDR: 833 typ = "addr" 834 case objabi.R_PCREL: 835 typ = "pcrel" 836 case objabi.R_CALL: 837 typ = "call" 838 } 839 ctxt.Logf("\treloc %.8x/%d %s %s+%#x [%#x]\n", uint(sym.Value+int64(r.Off)), r.Siz, typ, rsname, r.Add, r.Sym.Value+r.Add) 840 } 841 } 842 843 if addr < eaddr { 844 ctxt.Logf("\t%.8x| 00 ...\n", uint(addr)) 845 } 846 ctxt.Logf("\t%.8x|\n", uint(eaddr)) 847 } 848 849 func Dwarfblk(ctxt *Link, addr int64, size int64) { 850 if *flagA { 851 ctxt.Logf("dwarfblk [%#x,%#x) at offset %#x\n", addr, addr+size, ctxt.Out.Offset()) 852 } 853 854 blk(ctxt, dwarfp, addr, size, zeros[:]) 855 } 856 857 var zeros [512]byte 858 859 var ( 860 strdata = make(map[string]string) 861 strnames []string 862 ) 863 864 func addstrdata1(ctxt *Link, arg string) { 865 eq := strings.Index(arg, "=") 866 dot := strings.LastIndex(arg[:eq+1], ".") 867 if eq < 0 || dot < 0 { 868 Exitf("-X flag requires argument of the form importpath.name=value") 869 } 870 pkg := arg[:dot] 871 if ctxt.BuildMode == BuildModePlugin && pkg == "main" { 872 pkg = *flagPluginPath 873 } 874 pkg = objabi.PathToPrefix(pkg) 875 name := pkg + arg[dot:eq] 876 value := arg[eq+1:] 877 if _, ok := strdata[name]; !ok { 878 strnames = append(strnames, name) 879 } 880 strdata[name] = value 881 } 882 883 // addstrdata sets the initial value of the string variable name to value. 884 func addstrdata(ctxt *Link, name, value string) { 885 s := ctxt.Syms.ROLookup(name, 0) 886 if s == nil || s.Gotype == nil { 887 // Not defined in the loaded packages. 888 return 889 } 890 if s.Gotype.Name != "type.string" { 891 Errorf(s, "cannot set with -X: not a var of type string (%s)", s.Gotype.Name) 892 return 893 } 894 if s.Type == sym.SBSS { 895 s.Type = sym.SDATA 896 } 897 898 p := fmt.Sprintf("%s.str", s.Name) 899 sp := ctxt.Syms.Lookup(p, 0) 900 901 Addstring(sp, value) 902 sp.Type = sym.SRODATA 903 904 s.Size = 0 905 s.P = s.P[:0] 906 s.R = s.R[:0] 907 reachable := s.Attr.Reachable() 908 s.AddAddr(ctxt.Arch, sp) 909 s.AddUint(ctxt.Arch, uint64(len(value))) 910 911 // addstring, addaddr, etc., mark the symbols as reachable. 912 // In this case that is not necessarily true, so stick to what 913 // we know before entering this function. 914 s.Attr.Set(sym.AttrReachable, reachable) 915 916 sp.Attr.Set(sym.AttrReachable, reachable) 917 } 918 919 func (ctxt *Link) dostrdata() { 920 for _, name := range strnames { 921 addstrdata(ctxt, name, strdata[name]) 922 } 923 } 924 925 func Addstring(s *sym.Symbol, str string) int64 { 926 if s.Type == 0 { 927 s.Type = sym.SNOPTRDATA 928 } 929 s.Attr |= sym.AttrReachable 930 r := s.Size 931 if s.Name == ".shstrtab" { 932 elfsetstring(s, str, int(r)) 933 } 934 s.P = append(s.P, str...) 935 s.P = append(s.P, 0) 936 s.Size = int64(len(s.P)) 937 return r 938 } 939 940 // addgostring adds str, as a Go string value, to s. symname is the name of the 941 // symbol used to define the string data and must be unique per linked object. 942 func addgostring(ctxt *Link, s *sym.Symbol, symname, str string) { 943 sdata := ctxt.Syms.Lookup(symname, 0) 944 if sdata.Type != sym.Sxxx { 945 Errorf(s, "duplicate symname in addgostring: %s", symname) 946 } 947 sdata.Attr |= sym.AttrReachable 948 sdata.Attr |= sym.AttrLocal 949 sdata.Type = sym.SRODATA 950 sdata.Size = int64(len(str)) 951 sdata.P = []byte(str) 952 s.AddAddr(ctxt.Arch, sdata) 953 s.AddUint(ctxt.Arch, uint64(len(str))) 954 } 955 956 func addinitarrdata(ctxt *Link, s *sym.Symbol) { 957 p := s.Name + ".ptr" 958 sp := ctxt.Syms.Lookup(p, 0) 959 sp.Type = sym.SINITARR 960 sp.Size = 0 961 sp.Attr |= sym.AttrDuplicateOK 962 sp.AddAddr(ctxt.Arch, s) 963 } 964 965 func dosymtype(ctxt *Link) { 966 switch ctxt.BuildMode { 967 case BuildModeCArchive, BuildModeCShared: 968 for _, s := range ctxt.Syms.Allsym { 969 // Create a new entry in the .init_array section that points to the 970 // library initializer function. 971 if s.Name == *flagEntrySymbol { 972 addinitarrdata(ctxt, s) 973 } 974 } 975 } 976 } 977 978 // symalign returns the required alignment for the given symbol s. 979 func symalign(s *sym.Symbol) int32 { 980 min := int32(thearch.Minalign) 981 if s.Align >= min { 982 return s.Align 983 } else if s.Align != 0 { 984 return min 985 } 986 if strings.HasPrefix(s.Name, "go.string.") || strings.HasPrefix(s.Name, "type..namedata.") { 987 // String data is just bytes. 988 // If we align it, we waste a lot of space to padding. 989 return min 990 } 991 align := int32(thearch.Maxalign) 992 for int64(align) > s.Size && align > min { 993 align >>= 1 994 } 995 return align 996 } 997 998 func aligndatsize(datsize int64, s *sym.Symbol) int64 { 999 return Rnd(datsize, int64(symalign(s))) 1000 } 1001 1002 const debugGCProg = false 1003 1004 type GCProg struct { 1005 ctxt *Link 1006 sym *sym.Symbol 1007 w gcprog.Writer 1008 } 1009 1010 func (p *GCProg) Init(ctxt *Link, name string) { 1011 p.ctxt = ctxt 1012 p.sym = ctxt.Syms.Lookup(name, 0) 1013 p.w.Init(p.writeByte(ctxt)) 1014 if debugGCProg { 1015 fmt.Fprintf(os.Stderr, "ld: start GCProg %s\n", name) 1016 p.w.Debug(os.Stderr) 1017 } 1018 } 1019 1020 func (p *GCProg) writeByte(ctxt *Link) func(x byte) { 1021 return func(x byte) { 1022 p.sym.AddUint8(x) 1023 } 1024 } 1025 1026 func (p *GCProg) End(size int64) { 1027 p.w.ZeroUntil(size / int64(p.ctxt.Arch.PtrSize)) 1028 p.w.End() 1029 if debugGCProg { 1030 fmt.Fprintf(os.Stderr, "ld: end GCProg\n") 1031 } 1032 } 1033 1034 func (p *GCProg) AddSym(s *sym.Symbol) { 1035 typ := s.Gotype 1036 // Things without pointers should be in sym.SNOPTRDATA or sym.SNOPTRBSS; 1037 // everything we see should have pointers and should therefore have a type. 1038 if typ == nil { 1039 switch s.Name { 1040 case "runtime.data", "runtime.edata", "runtime.bss", "runtime.ebss": 1041 // Ignore special symbols that are sometimes laid out 1042 // as real symbols. See comment about dyld on darwin in 1043 // the address function. 1044 return 1045 } 1046 Errorf(s, "missing Go type information for global symbol: size %d", s.Size) 1047 return 1048 } 1049 1050 ptrsize := int64(p.ctxt.Arch.PtrSize) 1051 nptr := decodetypePtrdata(p.ctxt.Arch, typ) / ptrsize 1052 1053 if debugGCProg { 1054 fmt.Fprintf(os.Stderr, "gcprog sym: %s at %d (ptr=%d+%d)\n", s.Name, s.Value, s.Value/ptrsize, nptr) 1055 } 1056 1057 if decodetypeUsegcprog(p.ctxt.Arch, typ) == 0 { 1058 // Copy pointers from mask into program. 1059 mask := decodetypeGcmask(p.ctxt, typ) 1060 for i := int64(0); i < nptr; i++ { 1061 if (mask[i/8]>>uint(i%8))&1 != 0 { 1062 p.w.Ptr(s.Value/ptrsize + i) 1063 } 1064 } 1065 return 1066 } 1067 1068 // Copy program. 1069 prog := decodetypeGcprog(p.ctxt, typ) 1070 p.w.ZeroUntil(s.Value / ptrsize) 1071 p.w.Append(prog[4:], nptr) 1072 } 1073 1074 // dataSortKey is used to sort a slice of data symbol *sym.Symbol pointers. 1075 // The sort keys are kept inline to improve cache behavior while sorting. 1076 type dataSortKey struct { 1077 size int64 1078 name string 1079 sym *sym.Symbol 1080 } 1081 1082 type bySizeAndName []dataSortKey 1083 1084 func (d bySizeAndName) Len() int { return len(d) } 1085 func (d bySizeAndName) Swap(i, j int) { d[i], d[j] = d[j], d[i] } 1086 func (d bySizeAndName) Less(i, j int) bool { 1087 s1, s2 := d[i], d[j] 1088 if s1.size != s2.size { 1089 return s1.size < s2.size 1090 } 1091 return s1.name < s2.name 1092 } 1093 1094 // cutoff is the maximum data section size permitted by the linker 1095 // (see issue #9862). 1096 const cutoff = 2e9 // 2 GB (or so; looks better in errors than 2^31) 1097 1098 func checkdatsize(ctxt *Link, datsize int64, symn sym.SymKind) { 1099 if datsize > cutoff { 1100 Errorf(nil, "too much data in section %v (over %v bytes)", symn, cutoff) 1101 } 1102 } 1103 1104 // datap is a collection of reachable data symbols in address order. 1105 // Generated by dodata. 1106 var datap []*sym.Symbol 1107 1108 func (ctxt *Link) dodata() { 1109 if ctxt.Debugvlog != 0 { 1110 ctxt.Logf("%5.2f dodata\n", Cputime()) 1111 } 1112 1113 if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin { 1114 // The values in moduledata are filled out by relocations 1115 // pointing to the addresses of these special symbols. 1116 // Typically these symbols have no size and are not laid 1117 // out with their matching section. 1118 // 1119 // However on darwin, dyld will find the special symbol 1120 // in the first loaded module, even though it is local. 1121 // 1122 // (An hypothesis, formed without looking in the dyld sources: 1123 // these special symbols have no size, so their address 1124 // matches a real symbol. The dynamic linker assumes we 1125 // want the normal symbol with the same address and finds 1126 // it in the other module.) 1127 // 1128 // To work around this we lay out the symbls whose 1129 // addresses are vital for multi-module programs to work 1130 // as normal symbols, and give them a little size. 1131 bss := ctxt.Syms.Lookup("runtime.bss", 0) 1132 bss.Size = 8 1133 bss.Attr.Set(sym.AttrSpecial, false) 1134 1135 ctxt.Syms.Lookup("runtime.ebss", 0).Attr.Set(sym.AttrSpecial, false) 1136 1137 data := ctxt.Syms.Lookup("runtime.data", 0) 1138 data.Size = 8 1139 data.Attr.Set(sym.AttrSpecial, false) 1140 1141 ctxt.Syms.Lookup("runtime.edata", 0).Attr.Set(sym.AttrSpecial, false) 1142 1143 types := ctxt.Syms.Lookup("runtime.types", 0) 1144 types.Type = sym.STYPE 1145 types.Size = 8 1146 types.Attr.Set(sym.AttrSpecial, false) 1147 1148 etypes := ctxt.Syms.Lookup("runtime.etypes", 0) 1149 etypes.Type = sym.SFUNCTAB 1150 etypes.Attr.Set(sym.AttrSpecial, false) 1151 } 1152 1153 // Collect data symbols by type into data. 1154 var data [sym.SXREF][]*sym.Symbol 1155 for _, s := range ctxt.Syms.Allsym { 1156 if !s.Attr.Reachable() || s.Attr.Special() || s.Attr.SubSymbol() { 1157 continue 1158 } 1159 if s.Type <= sym.STEXT || s.Type >= sym.SXREF { 1160 continue 1161 } 1162 data[s.Type] = append(data[s.Type], s) 1163 } 1164 1165 // Now that we have the data symbols, but before we start 1166 // to assign addresses, record all the necessary 1167 // dynamic relocations. These will grow the relocation 1168 // symbol, which is itself data. 1169 // 1170 // On darwin, we need the symbol table numbers for dynreloc. 1171 if ctxt.HeadType == objabi.Hdarwin { 1172 machosymorder(ctxt) 1173 } 1174 dynreloc(ctxt, &data) 1175 1176 if ctxt.UseRelro() { 1177 // "read only" data with relocations needs to go in its own section 1178 // when building a shared library. We do this by boosting objects of 1179 // type SXXX with relocations to type SXXXRELRO. 1180 for _, symnro := range sym.ReadOnly { 1181 symnrelro := sym.RelROMap[symnro] 1182 1183 ro := []*sym.Symbol{} 1184 relro := data[symnrelro] 1185 1186 for _, s := range data[symnro] { 1187 isRelro := len(s.R) > 0 1188 switch s.Type { 1189 case sym.STYPE, sym.STYPERELRO, sym.SGOFUNCRELRO: 1190 // Symbols are not sorted yet, so it is possible 1191 // that an Outer symbol has been changed to a 1192 // relro Type before it reaches here. 1193 isRelro = true 1194 } 1195 if isRelro { 1196 s.Type = symnrelro 1197 if s.Outer != nil { 1198 s.Outer.Type = s.Type 1199 } 1200 relro = append(relro, s) 1201 } else { 1202 ro = append(ro, s) 1203 } 1204 } 1205 1206 // Check that we haven't made two symbols with the same .Outer into 1207 // different types (because references two symbols with non-nil Outer 1208 // become references to the outer symbol + offset it's vital that the 1209 // symbol and the outer end up in the same section). 1210 for _, s := range relro { 1211 if s.Outer != nil && s.Outer.Type != s.Type { 1212 Errorf(s, "inconsistent types for symbol and its Outer %s (%v != %v)", 1213 s.Outer.Name, s.Type, s.Outer.Type) 1214 } 1215 } 1216 1217 data[symnro] = ro 1218 data[symnrelro] = relro 1219 } 1220 } 1221 1222 // Sort symbols. 1223 var dataMaxAlign [sym.SXREF]int32 1224 var wg sync.WaitGroup 1225 for symn := range data { 1226 symn := sym.SymKind(symn) 1227 wg.Add(1) 1228 go func() { 1229 data[symn], dataMaxAlign[symn] = dodataSect(ctxt, symn, data[symn]) 1230 wg.Done() 1231 }() 1232 } 1233 wg.Wait() 1234 1235 // Allocate sections. 1236 // Data is processed before segtext, because we need 1237 // to see all symbols in the .data and .bss sections in order 1238 // to generate garbage collection information. 1239 datsize := int64(0) 1240 1241 // Writable data sections that do not need any specialized handling. 1242 writable := []sym.SymKind{ 1243 sym.SELFSECT, 1244 sym.SMACHO, 1245 sym.SMACHOGOT, 1246 sym.SWINDOWS, 1247 } 1248 for _, symn := range writable { 1249 for _, s := range data[symn] { 1250 sect := addsection(ctxt.Arch, &Segdata, s.Name, 06) 1251 sect.Align = symalign(s) 1252 datsize = Rnd(datsize, int64(sect.Align)) 1253 sect.Vaddr = uint64(datsize) 1254 s.Sect = sect 1255 s.Type = sym.SDATA 1256 s.Value = int64(uint64(datsize) - sect.Vaddr) 1257 datsize += s.Size 1258 sect.Length = uint64(datsize) - sect.Vaddr 1259 } 1260 checkdatsize(ctxt, datsize, symn) 1261 } 1262 1263 // .got (and .toc on ppc64) 1264 if len(data[sym.SELFGOT]) > 0 { 1265 sect := addsection(ctxt.Arch, &Segdata, ".got", 06) 1266 sect.Align = dataMaxAlign[sym.SELFGOT] 1267 datsize = Rnd(datsize, int64(sect.Align)) 1268 sect.Vaddr = uint64(datsize) 1269 for _, s := range data[sym.SELFGOT] { 1270 datsize = aligndatsize(datsize, s) 1271 s.Sect = sect 1272 s.Type = sym.SDATA 1273 s.Value = int64(uint64(datsize) - sect.Vaddr) 1274 1275 // Resolve .TOC. symbol for this object file (ppc64) 1276 toc := ctxt.Syms.ROLookup(".TOC.", int(s.Version)) 1277 if toc != nil { 1278 toc.Sect = sect 1279 toc.Outer = s 1280 toc.Sub = s.Sub 1281 s.Sub = toc 1282 1283 toc.Value = 0x8000 1284 } 1285 1286 datsize += s.Size 1287 } 1288 checkdatsize(ctxt, datsize, sym.SELFGOT) 1289 sect.Length = uint64(datsize) - sect.Vaddr 1290 } 1291 1292 /* pointer-free data */ 1293 sect := addsection(ctxt.Arch, &Segdata, ".noptrdata", 06) 1294 sect.Align = dataMaxAlign[sym.SNOPTRDATA] 1295 datsize = Rnd(datsize, int64(sect.Align)) 1296 sect.Vaddr = uint64(datsize) 1297 ctxt.Syms.Lookup("runtime.noptrdata", 0).Sect = sect 1298 ctxt.Syms.Lookup("runtime.enoptrdata", 0).Sect = sect 1299 for _, s := range data[sym.SNOPTRDATA] { 1300 datsize = aligndatsize(datsize, s) 1301 s.Sect = sect 1302 s.Type = sym.SDATA 1303 s.Value = int64(uint64(datsize) - sect.Vaddr) 1304 datsize += s.Size 1305 } 1306 checkdatsize(ctxt, datsize, sym.SNOPTRDATA) 1307 sect.Length = uint64(datsize) - sect.Vaddr 1308 1309 hasinitarr := ctxt.linkShared 1310 1311 /* shared library initializer */ 1312 switch ctxt.BuildMode { 1313 case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin: 1314 hasinitarr = true 1315 } 1316 if hasinitarr && len(data[sym.SINITARR]) > 0 { 1317 sect := addsection(ctxt.Arch, &Segdata, ".init_array", 06) 1318 sect.Align = dataMaxAlign[sym.SINITARR] 1319 datsize = Rnd(datsize, int64(sect.Align)) 1320 sect.Vaddr = uint64(datsize) 1321 for _, s := range data[sym.SINITARR] { 1322 datsize = aligndatsize(datsize, s) 1323 s.Sect = sect 1324 s.Value = int64(uint64(datsize) - sect.Vaddr) 1325 datsize += s.Size 1326 } 1327 sect.Length = uint64(datsize) - sect.Vaddr 1328 checkdatsize(ctxt, datsize, sym.SINITARR) 1329 } 1330 1331 /* data */ 1332 sect = addsection(ctxt.Arch, &Segdata, ".data", 06) 1333 sect.Align = dataMaxAlign[sym.SDATA] 1334 datsize = Rnd(datsize, int64(sect.Align)) 1335 sect.Vaddr = uint64(datsize) 1336 ctxt.Syms.Lookup("runtime.data", 0).Sect = sect 1337 ctxt.Syms.Lookup("runtime.edata", 0).Sect = sect 1338 var gc GCProg 1339 gc.Init(ctxt, "runtime.gcdata") 1340 for _, s := range data[sym.SDATA] { 1341 s.Sect = sect 1342 s.Type = sym.SDATA 1343 datsize = aligndatsize(datsize, s) 1344 s.Value = int64(uint64(datsize) - sect.Vaddr) 1345 gc.AddSym(s) 1346 datsize += s.Size 1347 } 1348 // On AIX, TOC entries must be the last of .data 1349 for _, s := range data[sym.SXCOFFTOC] { 1350 s.Sect = sect 1351 s.Type = sym.SDATA 1352 datsize = aligndatsize(datsize, s) 1353 s.Value = int64(uint64(datsize) - sect.Vaddr) 1354 datsize += s.Size 1355 } 1356 checkdatsize(ctxt, datsize, sym.SDATA) 1357 sect.Length = uint64(datsize) - sect.Vaddr 1358 gc.End(int64(sect.Length)) 1359 1360 /* bss */ 1361 sect = addsection(ctxt.Arch, &Segdata, ".bss", 06) 1362 sect.Align = dataMaxAlign[sym.SBSS] 1363 datsize = Rnd(datsize, int64(sect.Align)) 1364 sect.Vaddr = uint64(datsize) 1365 ctxt.Syms.Lookup("runtime.bss", 0).Sect = sect 1366 ctxt.Syms.Lookup("runtime.ebss", 0).Sect = sect 1367 gc = GCProg{} 1368 gc.Init(ctxt, "runtime.gcbss") 1369 for _, s := range data[sym.SBSS] { 1370 s.Sect = sect 1371 datsize = aligndatsize(datsize, s) 1372 s.Value = int64(uint64(datsize) - sect.Vaddr) 1373 gc.AddSym(s) 1374 datsize += s.Size 1375 } 1376 checkdatsize(ctxt, datsize, sym.SBSS) 1377 sect.Length = uint64(datsize) - sect.Vaddr 1378 gc.End(int64(sect.Length)) 1379 1380 /* pointer-free bss */ 1381 sect = addsection(ctxt.Arch, &Segdata, ".noptrbss", 06) 1382 sect.Align = dataMaxAlign[sym.SNOPTRBSS] 1383 datsize = Rnd(datsize, int64(sect.Align)) 1384 sect.Vaddr = uint64(datsize) 1385 ctxt.Syms.Lookup("runtime.noptrbss", 0).Sect = sect 1386 ctxt.Syms.Lookup("runtime.enoptrbss", 0).Sect = sect 1387 for _, s := range data[sym.SNOPTRBSS] { 1388 datsize = aligndatsize(datsize, s) 1389 s.Sect = sect 1390 s.Value = int64(uint64(datsize) - sect.Vaddr) 1391 datsize += s.Size 1392 } 1393 1394 sect.Length = uint64(datsize) - sect.Vaddr 1395 ctxt.Syms.Lookup("runtime.end", 0).Sect = sect 1396 checkdatsize(ctxt, datsize, sym.SNOPTRBSS) 1397 1398 if len(data[sym.STLSBSS]) > 0 { 1399 var sect *sym.Section 1400 if ctxt.IsELF && (ctxt.LinkMode == LinkExternal || !*FlagD) { 1401 sect = addsection(ctxt.Arch, &Segdata, ".tbss", 06) 1402 sect.Align = int32(ctxt.Arch.PtrSize) 1403 sect.Vaddr = 0 1404 } 1405 datsize = 0 1406 1407 for _, s := range data[sym.STLSBSS] { 1408 datsize = aligndatsize(datsize, s) 1409 s.Sect = sect 1410 s.Value = datsize 1411 datsize += s.Size 1412 } 1413 checkdatsize(ctxt, datsize, sym.STLSBSS) 1414 1415 if sect != nil { 1416 sect.Length = uint64(datsize) 1417 } 1418 } 1419 1420 /* 1421 * We finished data, begin read-only data. 1422 * Not all systems support a separate read-only non-executable data section. 1423 * ELF and Windows PE systems do. 1424 * OS X and Plan 9 do not. 1425 * And if we're using external linking mode, the point is moot, 1426 * since it's not our decision; that code expects the sections in 1427 * segtext. 1428 */ 1429 var segro *sym.Segment 1430 if ctxt.IsELF && ctxt.LinkMode == LinkInternal { 1431 segro = &Segrodata 1432 } else if ctxt.HeadType == objabi.Hwindows { 1433 segro = &Segrodata 1434 } else { 1435 segro = &Segtext 1436 } 1437 1438 datsize = 0 1439 1440 /* read-only executable ELF, Mach-O sections */ 1441 if len(data[sym.STEXT]) != 0 { 1442 Errorf(nil, "dodata found an sym.STEXT symbol: %s", data[sym.STEXT][0].Name) 1443 } 1444 for _, s := range data[sym.SELFRXSECT] { 1445 sect := addsection(ctxt.Arch, &Segtext, s.Name, 04) 1446 sect.Align = symalign(s) 1447 datsize = Rnd(datsize, int64(sect.Align)) 1448 sect.Vaddr = uint64(datsize) 1449 s.Sect = sect 1450 s.Type = sym.SRODATA 1451 s.Value = int64(uint64(datsize) - sect.Vaddr) 1452 datsize += s.Size 1453 sect.Length = uint64(datsize) - sect.Vaddr 1454 checkdatsize(ctxt, datsize, sym.SELFRXSECT) 1455 } 1456 1457 /* read-only data */ 1458 sect = addsection(ctxt.Arch, segro, ".rodata", 04) 1459 1460 sect.Vaddr = 0 1461 ctxt.Syms.Lookup("runtime.rodata", 0).Sect = sect 1462 ctxt.Syms.Lookup("runtime.erodata", 0).Sect = sect 1463 if !ctxt.UseRelro() { 1464 ctxt.Syms.Lookup("runtime.types", 0).Sect = sect 1465 ctxt.Syms.Lookup("runtime.etypes", 0).Sect = sect 1466 } 1467 for _, symn := range sym.ReadOnly { 1468 align := dataMaxAlign[symn] 1469 if sect.Align < align { 1470 sect.Align = align 1471 } 1472 } 1473 datsize = Rnd(datsize, int64(sect.Align)) 1474 for _, symn := range sym.ReadOnly { 1475 for _, s := range data[symn] { 1476 datsize = aligndatsize(datsize, s) 1477 s.Sect = sect 1478 s.Type = sym.SRODATA 1479 s.Value = int64(uint64(datsize) - sect.Vaddr) 1480 datsize += s.Size 1481 } 1482 checkdatsize(ctxt, datsize, symn) 1483 } 1484 sect.Length = uint64(datsize) - sect.Vaddr 1485 1486 /* read-only ELF, Mach-O sections */ 1487 for _, s := range data[sym.SELFROSECT] { 1488 sect = addsection(ctxt.Arch, segro, s.Name, 04) 1489 sect.Align = symalign(s) 1490 datsize = Rnd(datsize, int64(sect.Align)) 1491 sect.Vaddr = uint64(datsize) 1492 s.Sect = sect 1493 s.Type = sym.SRODATA 1494 s.Value = int64(uint64(datsize) - sect.Vaddr) 1495 datsize += s.Size 1496 sect.Length = uint64(datsize) - sect.Vaddr 1497 } 1498 checkdatsize(ctxt, datsize, sym.SELFROSECT) 1499 1500 for _, s := range data[sym.SMACHOPLT] { 1501 sect = addsection(ctxt.Arch, segro, s.Name, 04) 1502 sect.Align = symalign(s) 1503 datsize = Rnd(datsize, int64(sect.Align)) 1504 sect.Vaddr = uint64(datsize) 1505 s.Sect = sect 1506 s.Type = sym.SRODATA 1507 s.Value = int64(uint64(datsize) - sect.Vaddr) 1508 datsize += s.Size 1509 sect.Length = uint64(datsize) - sect.Vaddr 1510 } 1511 checkdatsize(ctxt, datsize, sym.SMACHOPLT) 1512 1513 // There is some data that are conceptually read-only but are written to by 1514 // relocations. On GNU systems, we can arrange for the dynamic linker to 1515 // mprotect sections after relocations are applied by giving them write 1516 // permissions in the object file and calling them ".data.rel.ro.FOO". We 1517 // divide the .rodata section between actual .rodata and .data.rel.ro.rodata, 1518 // but for the other sections that this applies to, we just write a read-only 1519 // .FOO section or a read-write .data.rel.ro.FOO section depending on the 1520 // situation. 1521 // TODO(mwhudson): It would make sense to do this more widely, but it makes 1522 // the system linker segfault on darwin. 1523 addrelrosection := func(suffix string) *sym.Section { 1524 return addsection(ctxt.Arch, segro, suffix, 04) 1525 } 1526 1527 if ctxt.UseRelro() { 1528 addrelrosection = func(suffix string) *sym.Section { 1529 seg := &Segrelrodata 1530 if ctxt.LinkMode == LinkExternal { 1531 // Using a separate segment with an external 1532 // linker results in some programs moving 1533 // their data sections unexpectedly, which 1534 // corrupts the moduledata. So we use the 1535 // rodata segment and let the external linker 1536 // sort out a rel.ro segment. 1537 seg = &Segrodata 1538 } 1539 return addsection(ctxt.Arch, seg, ".data.rel.ro"+suffix, 06) 1540 } 1541 /* data only written by relocations */ 1542 sect = addrelrosection("") 1543 1544 sect.Vaddr = 0 1545 ctxt.Syms.Lookup("runtime.types", 0).Sect = sect 1546 ctxt.Syms.Lookup("runtime.etypes", 0).Sect = sect 1547 for _, symnro := range sym.ReadOnly { 1548 symn := sym.RelROMap[symnro] 1549 align := dataMaxAlign[symn] 1550 if sect.Align < align { 1551 sect.Align = align 1552 } 1553 } 1554 datsize = Rnd(datsize, int64(sect.Align)) 1555 for _, symnro := range sym.ReadOnly { 1556 symn := sym.RelROMap[symnro] 1557 for _, s := range data[symn] { 1558 datsize = aligndatsize(datsize, s) 1559 if s.Outer != nil && s.Outer.Sect != nil && s.Outer.Sect != sect { 1560 Errorf(s, "s.Outer (%s) in different section from s, %s != %s", s.Outer.Name, s.Outer.Sect.Name, sect.Name) 1561 } 1562 s.Sect = sect 1563 s.Type = sym.SRODATA 1564 s.Value = int64(uint64(datsize) - sect.Vaddr) 1565 datsize += s.Size 1566 } 1567 checkdatsize(ctxt, datsize, symn) 1568 } 1569 1570 sect.Length = uint64(datsize) - sect.Vaddr 1571 } 1572 1573 /* typelink */ 1574 sect = addrelrosection(".typelink") 1575 sect.Align = dataMaxAlign[sym.STYPELINK] 1576 datsize = Rnd(datsize, int64(sect.Align)) 1577 sect.Vaddr = uint64(datsize) 1578 typelink := ctxt.Syms.Lookup("runtime.typelink", 0) 1579 typelink.Sect = sect 1580 typelink.Type = sym.SRODATA 1581 datsize += typelink.Size 1582 checkdatsize(ctxt, datsize, sym.STYPELINK) 1583 sect.Length = uint64(datsize) - sect.Vaddr 1584 1585 /* itablink */ 1586 sect = addrelrosection(".itablink") 1587 sect.Align = dataMaxAlign[sym.SITABLINK] 1588 datsize = Rnd(datsize, int64(sect.Align)) 1589 sect.Vaddr = uint64(datsize) 1590 ctxt.Syms.Lookup("runtime.itablink", 0).Sect = sect 1591 ctxt.Syms.Lookup("runtime.eitablink", 0).Sect = sect 1592 for _, s := range data[sym.SITABLINK] { 1593 datsize = aligndatsize(datsize, s) 1594 s.Sect = sect 1595 s.Type = sym.SRODATA 1596 s.Value = int64(uint64(datsize) - sect.Vaddr) 1597 datsize += s.Size 1598 } 1599 checkdatsize(ctxt, datsize, sym.SITABLINK) 1600 sect.Length = uint64(datsize) - sect.Vaddr 1601 1602 /* gosymtab */ 1603 sect = addrelrosection(".gosymtab") 1604 sect.Align = dataMaxAlign[sym.SSYMTAB] 1605 datsize = Rnd(datsize, int64(sect.Align)) 1606 sect.Vaddr = uint64(datsize) 1607 ctxt.Syms.Lookup("runtime.symtab", 0).Sect = sect 1608 ctxt.Syms.Lookup("runtime.esymtab", 0).Sect = sect 1609 for _, s := range data[sym.SSYMTAB] { 1610 datsize = aligndatsize(datsize, s) 1611 s.Sect = sect 1612 s.Type = sym.SRODATA 1613 s.Value = int64(uint64(datsize) - sect.Vaddr) 1614 datsize += s.Size 1615 } 1616 checkdatsize(ctxt, datsize, sym.SSYMTAB) 1617 sect.Length = uint64(datsize) - sect.Vaddr 1618 1619 /* gopclntab */ 1620 sect = addrelrosection(".gopclntab") 1621 sect.Align = dataMaxAlign[sym.SPCLNTAB] 1622 datsize = Rnd(datsize, int64(sect.Align)) 1623 sect.Vaddr = uint64(datsize) 1624 ctxt.Syms.Lookup("runtime.pclntab", 0).Sect = sect 1625 ctxt.Syms.Lookup("runtime.epclntab", 0).Sect = sect 1626 for _, s := range data[sym.SPCLNTAB] { 1627 datsize = aligndatsize(datsize, s) 1628 s.Sect = sect 1629 s.Type = sym.SRODATA 1630 s.Value = int64(uint64(datsize) - sect.Vaddr) 1631 datsize += s.Size 1632 } 1633 checkdatsize(ctxt, datsize, sym.SRODATA) 1634 sect.Length = uint64(datsize) - sect.Vaddr 1635 1636 // 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits. 1637 if datsize != int64(uint32(datsize)) { 1638 Errorf(nil, "read-only data segment too large: %d", datsize) 1639 } 1640 1641 for symn := sym.SELFRXSECT; symn < sym.SXREF; symn++ { 1642 datap = append(datap, data[symn]...) 1643 } 1644 1645 dwarfGenerateDebugSyms(ctxt) 1646 1647 var i int 1648 for ; i < len(dwarfp); i++ { 1649 s := dwarfp[i] 1650 if s.Type != sym.SDWARFSECT { 1651 break 1652 } 1653 1654 sect = addsection(ctxt.Arch, &Segdwarf, s.Name, 04) 1655 sect.Align = 1 1656 datsize = Rnd(datsize, int64(sect.Align)) 1657 sect.Vaddr = uint64(datsize) 1658 s.Sect = sect 1659 s.Type = sym.SRODATA 1660 s.Value = int64(uint64(datsize) - sect.Vaddr) 1661 datsize += s.Size 1662 sect.Length = uint64(datsize) - sect.Vaddr 1663 } 1664 checkdatsize(ctxt, datsize, sym.SDWARFSECT) 1665 1666 for i < len(dwarfp) { 1667 curType := dwarfp[i].Type 1668 var sect *sym.Section 1669 switch curType { 1670 case sym.SDWARFINFO: 1671 sect = addsection(ctxt.Arch, &Segdwarf, ".debug_info", 04) 1672 case sym.SDWARFRANGE: 1673 sect = addsection(ctxt.Arch, &Segdwarf, ".debug_ranges", 04) 1674 case sym.SDWARFLOC: 1675 sect = addsection(ctxt.Arch, &Segdwarf, ".debug_loc", 04) 1676 default: 1677 Errorf(dwarfp[i], "unknown DWARF section %v", curType) 1678 } 1679 1680 sect.Align = 1 1681 datsize = Rnd(datsize, int64(sect.Align)) 1682 sect.Vaddr = uint64(datsize) 1683 for ; i < len(dwarfp); i++ { 1684 s := dwarfp[i] 1685 if s.Type != curType { 1686 break 1687 } 1688 s.Sect = sect 1689 s.Type = sym.SRODATA 1690 s.Value = int64(uint64(datsize) - sect.Vaddr) 1691 s.Attr |= sym.AttrLocal 1692 datsize += s.Size 1693 } 1694 sect.Length = uint64(datsize) - sect.Vaddr 1695 checkdatsize(ctxt, datsize, curType) 1696 } 1697 1698 /* number the sections */ 1699 n := int32(1) 1700 1701 for _, sect := range Segtext.Sections { 1702 sect.Extnum = int16(n) 1703 n++ 1704 } 1705 for _, sect := range Segrodata.Sections { 1706 sect.Extnum = int16(n) 1707 n++ 1708 } 1709 for _, sect := range Segrelrodata.Sections { 1710 sect.Extnum = int16(n) 1711 n++ 1712 } 1713 for _, sect := range Segdata.Sections { 1714 sect.Extnum = int16(n) 1715 n++ 1716 } 1717 for _, sect := range Segdwarf.Sections { 1718 sect.Extnum = int16(n) 1719 n++ 1720 } 1721 } 1722 1723 func dodataSect(ctxt *Link, symn sym.SymKind, syms []*sym.Symbol) (result []*sym.Symbol, maxAlign int32) { 1724 if ctxt.HeadType == objabi.Hdarwin { 1725 // Some symbols may no longer belong in syms 1726 // due to movement in machosymorder. 1727 newSyms := make([]*sym.Symbol, 0, len(syms)) 1728 for _, s := range syms { 1729 if s.Type == symn { 1730 newSyms = append(newSyms, s) 1731 } 1732 } 1733 syms = newSyms 1734 } 1735 1736 var head, tail *sym.Symbol 1737 symsSort := make([]dataSortKey, 0, len(syms)) 1738 for _, s := range syms { 1739 if s.Attr.OnList() { 1740 log.Fatalf("symbol %s listed multiple times", s.Name) 1741 } 1742 s.Attr |= sym.AttrOnList 1743 switch { 1744 case s.Size < int64(len(s.P)): 1745 Errorf(s, "initialize bounds (%d < %d)", s.Size, len(s.P)) 1746 case s.Size < 0: 1747 Errorf(s, "negative size (%d bytes)", s.Size) 1748 case s.Size > cutoff: 1749 Errorf(s, "symbol too large (%d bytes)", s.Size) 1750 } 1751 1752 // If the usually-special section-marker symbols are being laid 1753 // out as regular symbols, put them either at the beginning or 1754 // end of their section. 1755 if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin { 1756 switch s.Name { 1757 case "runtime.text", "runtime.bss", "runtime.data", "runtime.types": 1758 head = s 1759 continue 1760 case "runtime.etext", "runtime.ebss", "runtime.edata", "runtime.etypes": 1761 tail = s 1762 continue 1763 } 1764 } 1765 1766 key := dataSortKey{ 1767 size: s.Size, 1768 name: s.Name, 1769 sym: s, 1770 } 1771 1772 switch s.Type { 1773 case sym.SELFGOT: 1774 // For ppc64, we want to interleave the .got and .toc sections 1775 // from input files. Both are type sym.SELFGOT, so in that case 1776 // we skip size comparison and fall through to the name 1777 // comparison (conveniently, .got sorts before .toc). 1778 key.size = 0 1779 } 1780 1781 symsSort = append(symsSort, key) 1782 } 1783 1784 sort.Sort(bySizeAndName(symsSort)) 1785 1786 off := 0 1787 if head != nil { 1788 syms[0] = head 1789 off++ 1790 } 1791 for i, symSort := range symsSort { 1792 syms[i+off] = symSort.sym 1793 align := symalign(symSort.sym) 1794 if maxAlign < align { 1795 maxAlign = align 1796 } 1797 } 1798 if tail != nil { 1799 syms[len(syms)-1] = tail 1800 } 1801 1802 if ctxt.IsELF && symn == sym.SELFROSECT { 1803 // Make .rela and .rela.plt contiguous, the ELF ABI requires this 1804 // and Solaris actually cares. 1805 reli, plti := -1, -1 1806 for i, s := range syms { 1807 switch s.Name { 1808 case ".rel.plt", ".rela.plt": 1809 plti = i 1810 case ".rel", ".rela": 1811 reli = i 1812 } 1813 } 1814 if reli >= 0 && plti >= 0 && plti != reli+1 { 1815 var first, second int 1816 if plti > reli { 1817 first, second = reli, plti 1818 } else { 1819 first, second = plti, reli 1820 } 1821 rel, plt := syms[reli], syms[plti] 1822 copy(syms[first+2:], syms[first+1:second]) 1823 syms[first+0] = rel 1824 syms[first+1] = plt 1825 1826 // Make sure alignment doesn't introduce a gap. 1827 // Setting the alignment explicitly prevents 1828 // symalign from basing it on the size and 1829 // getting it wrong. 1830 rel.Align = int32(ctxt.Arch.RegSize) 1831 plt.Align = int32(ctxt.Arch.RegSize) 1832 } 1833 } 1834 1835 return syms, maxAlign 1836 } 1837 1838 // Add buildid to beginning of text segment, on non-ELF systems. 1839 // Non-ELF binary formats are not always flexible enough to 1840 // give us a place to put the Go build ID. On those systems, we put it 1841 // at the very beginning of the text segment. 1842 // This ``header'' is read by cmd/go. 1843 func (ctxt *Link) textbuildid() { 1844 if ctxt.IsELF || ctxt.BuildMode == BuildModePlugin || *flagBuildid == "" { 1845 return 1846 } 1847 1848 s := ctxt.Syms.Lookup("go.buildid", 0) 1849 s.Attr |= sym.AttrReachable 1850 // The \xff is invalid UTF-8, meant to make it less likely 1851 // to find one of these accidentally. 1852 data := "\xff Go build ID: " + strconv.Quote(*flagBuildid) + "\n \xff" 1853 s.Type = sym.STEXT 1854 s.P = []byte(data) 1855 s.Size = int64(len(s.P)) 1856 1857 ctxt.Textp = append(ctxt.Textp, nil) 1858 copy(ctxt.Textp[1:], ctxt.Textp) 1859 ctxt.Textp[0] = s 1860 } 1861 1862 // assign addresses to text 1863 func (ctxt *Link) textaddress() { 1864 addsection(ctxt.Arch, &Segtext, ".text", 05) 1865 1866 // Assign PCs in text segment. 1867 // Could parallelize, by assigning to text 1868 // and then letting threads copy down, but probably not worth it. 1869 sect := Segtext.Sections[0] 1870 1871 sect.Align = int32(Funcalign) 1872 1873 text := ctxt.Syms.Lookup("runtime.text", 0) 1874 text.Sect = sect 1875 1876 if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin { 1877 etext := ctxt.Syms.Lookup("runtime.etext", 0) 1878 etext.Sect = sect 1879 1880 ctxt.Textp = append(ctxt.Textp, etext, nil) 1881 copy(ctxt.Textp[1:], ctxt.Textp) 1882 ctxt.Textp[0] = text 1883 } 1884 1885 va := uint64(*FlagTextAddr) 1886 n := 1 1887 sect.Vaddr = va 1888 ntramps := 0 1889 for _, s := range ctxt.Textp { 1890 sect, n, va = assignAddress(ctxt, sect, n, s, va, false) 1891 1892 trampoline(ctxt, s) // resolve jumps, may add trampolines if jump too far 1893 1894 // lay down trampolines after each function 1895 for ; ntramps < len(ctxt.tramps); ntramps++ { 1896 tramp := ctxt.tramps[ntramps] 1897 sect, n, va = assignAddress(ctxt, sect, n, tramp, va, true) 1898 } 1899 } 1900 1901 sect.Length = va - sect.Vaddr 1902 ctxt.Syms.Lookup("runtime.etext", 0).Sect = sect 1903 1904 // merge tramps into Textp, keeping Textp in address order 1905 if ntramps != 0 { 1906 newtextp := make([]*sym.Symbol, 0, len(ctxt.Textp)+ntramps) 1907 i := 0 1908 for _, s := range ctxt.Textp { 1909 for ; i < ntramps && ctxt.tramps[i].Value < s.Value; i++ { 1910 newtextp = append(newtextp, ctxt.tramps[i]) 1911 } 1912 newtextp = append(newtextp, s) 1913 } 1914 newtextp = append(newtextp, ctxt.tramps[i:ntramps]...) 1915 1916 ctxt.Textp = newtextp 1917 } 1918 } 1919 1920 // assigns address for a text symbol, returns (possibly new) section, its number, and the address 1921 // Note: once we have trampoline insertion support for external linking, this function 1922 // will not need to create new text sections, and so no need to return sect and n. 1923 func assignAddress(ctxt *Link, sect *sym.Section, n int, s *sym.Symbol, va uint64, isTramp bool) (*sym.Section, int, uint64) { 1924 if thearch.AssignAddress != nil { 1925 return thearch.AssignAddress(ctxt, sect, n, s, va, isTramp) 1926 } 1927 1928 s.Sect = sect 1929 if s.Attr.SubSymbol() { 1930 return sect, n, va 1931 } 1932 if s.Align != 0 { 1933 va = uint64(Rnd(int64(va), int64(s.Align))) 1934 } else { 1935 va = uint64(Rnd(int64(va), int64(Funcalign))) 1936 } 1937 s.Value = 0 1938 for sub := s; sub != nil; sub = sub.Sub { 1939 sub.Value += int64(va) 1940 } 1941 1942 funcsize := uint64(MINFUNC) // spacing required for findfunctab 1943 if s.Size > MINFUNC { 1944 funcsize = uint64(s.Size) 1945 } 1946 1947 // On ppc64x a text section should not be larger than 2^26 bytes due to the size of 1948 // call target offset field in the bl instruction. Splitting into smaller text 1949 // sections smaller than this limit allows the GNU linker to modify the long calls 1950 // appropriately. The limit allows for the space needed for tables inserted by the linker. 1951 1952 // If this function doesn't fit in the current text section, then create a new one. 1953 1954 // Only break at outermost syms. 1955 1956 if ctxt.Arch.InFamily(sys.PPC64) && s.Outer == nil && ctxt.IsELF && ctxt.LinkMode == LinkExternal && va-sect.Vaddr+funcsize+maxSizeTrampolinesPPC64(s, isTramp) > 0x1c00000 { 1957 // Set the length for the previous text section 1958 sect.Length = va - sect.Vaddr 1959 1960 // Create new section, set the starting Vaddr 1961 sect = addsection(ctxt.Arch, &Segtext, ".text", 05) 1962 sect.Vaddr = va 1963 s.Sect = sect 1964 1965 // Create a symbol for the start of the secondary text sections 1966 ctxt.Syms.Lookup(fmt.Sprintf("runtime.text.%d", n), 0).Sect = sect 1967 n++ 1968 } 1969 va += funcsize 1970 1971 return sect, n, va 1972 } 1973 1974 // address assigns virtual addresses to all segments and sections and 1975 // returns all segments in file order. 1976 func (ctxt *Link) address() []*sym.Segment { 1977 var order []*sym.Segment // Layout order 1978 1979 va := uint64(*FlagTextAddr) 1980 order = append(order, &Segtext) 1981 Segtext.Rwx = 05 1982 Segtext.Vaddr = va 1983 for _, s := range Segtext.Sections { 1984 va = uint64(Rnd(int64(va), int64(s.Align))) 1985 s.Vaddr = va 1986 va += s.Length 1987 } 1988 1989 Segtext.Length = va - uint64(*FlagTextAddr) 1990 if ctxt.HeadType == objabi.Hnacl { 1991 va += 32 // room for the "halt sled" 1992 } 1993 1994 if len(Segrodata.Sections) > 0 { 1995 // align to page boundary so as not to mix 1996 // rodata and executable text. 1997 // 1998 // Note: gold or GNU ld will reduce the size of the executable 1999 // file by arranging for the relro segment to end at a page 2000 // boundary, and overlap the end of the text segment with the 2001 // start of the relro segment in the file. The PT_LOAD segments 2002 // will be such that the last page of the text segment will be 2003 // mapped twice, once r-x and once starting out rw- and, after 2004 // relocation processing, changed to r--. 2005 // 2006 // Ideally the last page of the text segment would not be 2007 // writable even for this short period. 2008 va = uint64(Rnd(int64(va), int64(*FlagRound))) 2009 2010 order = append(order, &Segrodata) 2011 Segrodata.Rwx = 04 2012 Segrodata.Vaddr = va 2013 for _, s := range Segrodata.Sections { 2014 va = uint64(Rnd(int64(va), int64(s.Align))) 2015 s.Vaddr = va 2016 va += s.Length 2017 } 2018 2019 Segrodata.Length = va - Segrodata.Vaddr 2020 } 2021 if len(Segrelrodata.Sections) > 0 { 2022 // align to page boundary so as not to mix 2023 // rodata, rel-ro data, and executable text. 2024 va = uint64(Rnd(int64(va), int64(*FlagRound))) 2025 2026 order = append(order, &Segrelrodata) 2027 Segrelrodata.Rwx = 06 2028 Segrelrodata.Vaddr = va 2029 for _, s := range Segrelrodata.Sections { 2030 va = uint64(Rnd(int64(va), int64(s.Align))) 2031 s.Vaddr = va 2032 va += s.Length 2033 } 2034 2035 Segrelrodata.Length = va - Segrelrodata.Vaddr 2036 } 2037 2038 va = uint64(Rnd(int64(va), int64(*FlagRound))) 2039 if ctxt.HeadType == objabi.Haix { 2040 // Data sections are moved to an unreachable segment 2041 // to ensure that they are position-independent. 2042 va += uint64(XCOFFDATABASE) - uint64(XCOFFTEXTBASE) 2043 } 2044 order = append(order, &Segdata) 2045 Segdata.Rwx = 06 2046 Segdata.Vaddr = va 2047 var data *sym.Section 2048 var noptr *sym.Section 2049 var bss *sym.Section 2050 var noptrbss *sym.Section 2051 for i, s := range Segdata.Sections { 2052 if ctxt.IsELF && s.Name == ".tbss" { 2053 continue 2054 } 2055 vlen := int64(s.Length) 2056 if i+1 < len(Segdata.Sections) && !(ctxt.IsELF && Segdata.Sections[i+1].Name == ".tbss") { 2057 vlen = int64(Segdata.Sections[i+1].Vaddr - s.Vaddr) 2058 } 2059 s.Vaddr = va 2060 va += uint64(vlen) 2061 Segdata.Length = va - Segdata.Vaddr 2062 if s.Name == ".data" { 2063 data = s 2064 } 2065 if s.Name == ".noptrdata" { 2066 noptr = s 2067 } 2068 if s.Name == ".bss" { 2069 bss = s 2070 } 2071 if s.Name == ".noptrbss" { 2072 noptrbss = s 2073 } 2074 } 2075 2076 // Assign Segdata's Filelen omitting the BSS. We do this here 2077 // simply because right now we know where the BSS starts. 2078 Segdata.Filelen = bss.Vaddr - Segdata.Vaddr 2079 2080 va = uint64(Rnd(int64(va), int64(*FlagRound))) 2081 order = append(order, &Segdwarf) 2082 Segdwarf.Rwx = 06 2083 Segdwarf.Vaddr = va 2084 for i, s := range Segdwarf.Sections { 2085 vlen := int64(s.Length) 2086 if i+1 < len(Segdwarf.Sections) { 2087 vlen = int64(Segdwarf.Sections[i+1].Vaddr - s.Vaddr) 2088 } 2089 s.Vaddr = va 2090 va += uint64(vlen) 2091 if ctxt.HeadType == objabi.Hwindows { 2092 va = uint64(Rnd(int64(va), PEFILEALIGN)) 2093 } 2094 Segdwarf.Length = va - Segdwarf.Vaddr 2095 } 2096 2097 var ( 2098 text = Segtext.Sections[0] 2099 rodata = ctxt.Syms.Lookup("runtime.rodata", 0).Sect 2100 itablink = ctxt.Syms.Lookup("runtime.itablink", 0).Sect 2101 symtab = ctxt.Syms.Lookup("runtime.symtab", 0).Sect 2102 pclntab = ctxt.Syms.Lookup("runtime.pclntab", 0).Sect 2103 types = ctxt.Syms.Lookup("runtime.types", 0).Sect 2104 ) 2105 lasttext := text 2106 // Could be multiple .text sections 2107 for _, sect := range Segtext.Sections { 2108 if sect.Name == ".text" { 2109 lasttext = sect 2110 } 2111 } 2112 2113 for _, s := range datap { 2114 if s.Sect != nil { 2115 s.Value += int64(s.Sect.Vaddr) 2116 } 2117 for sub := s.Sub; sub != nil; sub = sub.Sub { 2118 sub.Value += s.Value 2119 } 2120 } 2121 2122 for _, s := range dwarfp { 2123 if s.Sect != nil { 2124 s.Value += int64(s.Sect.Vaddr) 2125 } 2126 for sub := s.Sub; sub != nil; sub = sub.Sub { 2127 sub.Value += s.Value 2128 } 2129 } 2130 2131 if ctxt.BuildMode == BuildModeShared { 2132 s := ctxt.Syms.Lookup("go.link.abihashbytes", 0) 2133 sectSym := ctxt.Syms.Lookup(".note.go.abihash", 0) 2134 s.Sect = sectSym.Sect 2135 s.Value = int64(sectSym.Sect.Vaddr + 16) 2136 } 2137 2138 ctxt.xdefine("runtime.text", sym.STEXT, int64(text.Vaddr)) 2139 ctxt.xdefine("runtime.etext", sym.STEXT, int64(lasttext.Vaddr+lasttext.Length)) 2140 2141 // If there are multiple text sections, create runtime.text.n for 2142 // their section Vaddr, using n for index 2143 n := 1 2144 for _, sect := range Segtext.Sections[1:] { 2145 if sect.Name != ".text" { 2146 break 2147 } 2148 symname := fmt.Sprintf("runtime.text.%d", n) 2149 ctxt.xdefine(symname, sym.STEXT, int64(sect.Vaddr)) 2150 n++ 2151 } 2152 2153 ctxt.xdefine("runtime.rodata", sym.SRODATA, int64(rodata.Vaddr)) 2154 ctxt.xdefine("runtime.erodata", sym.SRODATA, int64(rodata.Vaddr+rodata.Length)) 2155 ctxt.xdefine("runtime.types", sym.SRODATA, int64(types.Vaddr)) 2156 ctxt.xdefine("runtime.etypes", sym.SRODATA, int64(types.Vaddr+types.Length)) 2157 ctxt.xdefine("runtime.itablink", sym.SRODATA, int64(itablink.Vaddr)) 2158 ctxt.xdefine("runtime.eitablink", sym.SRODATA, int64(itablink.Vaddr+itablink.Length)) 2159 2160 s := ctxt.Syms.Lookup("runtime.gcdata", 0) 2161 s.Attr |= sym.AttrLocal 2162 ctxt.xdefine("runtime.egcdata", sym.SRODATA, Symaddr(s)+s.Size) 2163 ctxt.Syms.Lookup("runtime.egcdata", 0).Sect = s.Sect 2164 2165 s = ctxt.Syms.Lookup("runtime.gcbss", 0) 2166 s.Attr |= sym.AttrLocal 2167 ctxt.xdefine("runtime.egcbss", sym.SRODATA, Symaddr(s)+s.Size) 2168 ctxt.Syms.Lookup("runtime.egcbss", 0).Sect = s.Sect 2169 2170 ctxt.xdefine("runtime.symtab", sym.SRODATA, int64(symtab.Vaddr)) 2171 ctxt.xdefine("runtime.esymtab", sym.SRODATA, int64(symtab.Vaddr+symtab.Length)) 2172 ctxt.xdefine("runtime.pclntab", sym.SRODATA, int64(pclntab.Vaddr)) 2173 ctxt.xdefine("runtime.epclntab", sym.SRODATA, int64(pclntab.Vaddr+pclntab.Length)) 2174 ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr)) 2175 ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr+noptr.Length)) 2176 ctxt.xdefine("runtime.bss", sym.SBSS, int64(bss.Vaddr)) 2177 ctxt.xdefine("runtime.ebss", sym.SBSS, int64(bss.Vaddr+bss.Length)) 2178 ctxt.xdefine("runtime.data", sym.SDATA, int64(data.Vaddr)) 2179 ctxt.xdefine("runtime.edata", sym.SDATA, int64(data.Vaddr+data.Length)) 2180 ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr)) 2181 ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length)) 2182 ctxt.xdefine("runtime.end", sym.SBSS, int64(Segdata.Vaddr+Segdata.Length)) 2183 2184 return order 2185 } 2186 2187 // layout assigns file offsets and lengths to the segments in order. 2188 func (ctxt *Link) layout(order []*sym.Segment) { 2189 var prev *sym.Segment 2190 for _, seg := range order { 2191 if prev == nil { 2192 seg.Fileoff = uint64(HEADR) 2193 } else { 2194 switch ctxt.HeadType { 2195 default: 2196 // Assuming the previous segment was 2197 // aligned, the following rounding 2198 // should ensure that this segment's 2199 // VA ≡ Fileoff mod FlagRound. 2200 seg.Fileoff = uint64(Rnd(int64(prev.Fileoff+prev.Filelen), int64(*FlagRound))) 2201 if seg.Vaddr%uint64(*FlagRound) != seg.Fileoff%uint64(*FlagRound) { 2202 Exitf("bad segment rounding (Vaddr=%#x Fileoff=%#x FlagRound=%#x)", seg.Vaddr, seg.Fileoff, *FlagRound) 2203 } 2204 case objabi.Hwindows: 2205 seg.Fileoff = prev.Fileoff + uint64(Rnd(int64(prev.Filelen), PEFILEALIGN)) 2206 case objabi.Hplan9: 2207 seg.Fileoff = prev.Fileoff + prev.Filelen 2208 } 2209 } 2210 if seg != &Segdata { 2211 // Link.address already set Segdata.Filelen to 2212 // account for BSS. 2213 seg.Filelen = seg.Length 2214 } 2215 prev = seg 2216 } 2217 2218 } 2219 2220 // add a trampoline with symbol s (to be laid down after the current function) 2221 func (ctxt *Link) AddTramp(s *sym.Symbol) { 2222 s.Type = sym.STEXT 2223 s.Attr |= sym.AttrReachable 2224 s.Attr |= sym.AttrOnList 2225 ctxt.tramps = append(ctxt.tramps, s) 2226 if *FlagDebugTramp > 0 && ctxt.Debugvlog > 0 { 2227 ctxt.Logf("trampoline %s inserted\n", s) 2228 } 2229 } 2230 2231 // compressSyms compresses syms and returns the contents of the 2232 // compressed section. If the section would get larger, it returns nil. 2233 func compressSyms(ctxt *Link, syms []*sym.Symbol) []byte { 2234 var total int64 2235 for _, sym := range syms { 2236 total += sym.Size 2237 } 2238 2239 var buf bytes.Buffer 2240 buf.Write([]byte("ZLIB")) 2241 var sizeBytes [8]byte 2242 binary.BigEndian.PutUint64(sizeBytes[:], uint64(total)) 2243 buf.Write(sizeBytes[:]) 2244 2245 // Using zlib.BestSpeed achieves very nearly the same 2246 // compression levels of zlib.DefaultCompression, but takes 2247 // substantially less time. This is important because DWARF 2248 // compression can be a significant fraction of link time. 2249 z, err := zlib.NewWriterLevel(&buf, zlib.BestSpeed) 2250 if err != nil { 2251 log.Fatalf("NewWriterLevel failed: %s", err) 2252 } 2253 for _, sym := range syms { 2254 if _, err := z.Write(sym.P); err != nil { 2255 log.Fatalf("compression failed: %s", err) 2256 } 2257 for i := sym.Size - int64(len(sym.P)); i > 0; { 2258 b := zeros[:] 2259 if i < int64(len(b)) { 2260 b = b[:i] 2261 } 2262 n, err := z.Write(b) 2263 if err != nil { 2264 log.Fatalf("compression failed: %s", err) 2265 } 2266 i -= int64(n) 2267 } 2268 } 2269 if err := z.Close(); err != nil { 2270 log.Fatalf("compression failed: %s", err) 2271 } 2272 if int64(buf.Len()) >= total { 2273 // Compression didn't save any space. 2274 return nil 2275 } 2276 return buf.Bytes() 2277 }