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