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