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