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