]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/link/internal/ld/data.go
cmd/link: write buildid to plugin
[gostls13.git] / src / cmd / link / internal / ld / data.go
1 // Derived from Inferno utils/6l/obj.c and utils/6l/span.c
2 // https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6l/obj.c
3 // https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6l/span.c
4 //
5 //      Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
6 //      Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
7 //      Portions Copyright © 1997-1999 Vita Nuova Limited
8 //      Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
9 //      Portions Copyright © 2004,2006 Bruce Ellis
10 //      Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
11 //      Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
12 //      Portions Copyright © 2009 The Go Authors. All rights reserved.
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to deal
16 // in the Software without restriction, including without limitation the rights
17 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18 // copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included in
22 // all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
27 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30 // THE SOFTWARE.
31
32 package ld
33
34 import (
35         "bytes"
36         "cmd/internal/gcprog"
37         "cmd/internal/objabi"
38         "cmd/internal/sys"
39         "cmd/link/internal/loader"
40         "cmd/link/internal/loadpe"
41         "cmd/link/internal/sym"
42         "compress/zlib"
43         "debug/elf"
44         "encoding/binary"
45         "fmt"
46         "log"
47         "os"
48         "sort"
49         "strconv"
50         "strings"
51         "sync"
52         "sync/atomic"
53 )
54
55 // isRuntimeDepPkg reports whether pkg is the runtime package or its dependency.
56 func isRuntimeDepPkg(pkg string) bool {
57         switch pkg {
58         case "runtime",
59                 "sync/atomic",      // runtime may call to sync/atomic, due to go:linkname
60                 "internal/abi",     // used by reflectcall (and maybe more)
61                 "internal/bytealg", // for IndexByte
62                 "internal/cpu":     // for cpu features
63                 return true
64         }
65         return strings.HasPrefix(pkg, "runtime/internal/") && !strings.HasSuffix(pkg, "_test")
66 }
67
68 // Estimate the max size needed to hold any new trampolines created for this function. This
69 // is used to determine when the section can be split if it becomes too large, to ensure that
70 // the trampolines are in the same section as the function that uses them.
71 func maxSizeTrampolines(ctxt *Link, ldr *loader.Loader, s loader.Sym, isTramp bool) uint64 {
72         // If thearch.Trampoline is nil, then trampoline support is not available on this arch.
73         // A trampoline does not need any dependent trampolines.
74         if thearch.Trampoline == nil || isTramp {
75                 return 0
76         }
77
78         n := uint64(0)
79         relocs := ldr.Relocs(s)
80         for ri := 0; ri < relocs.Count(); ri++ {
81                 r := relocs.At(ri)
82                 if r.Type().IsDirectCallOrJump() {
83                         n++
84                 }
85         }
86
87         if ctxt.IsARM() {
88                 return n * 20 // Trampolines in ARM range from 3 to 5 instructions.
89         }
90         if ctxt.IsPPC64() {
91                 return n * 16 // Trampolines in PPC64 are 4 instructions.
92         }
93         if ctxt.IsARM64() {
94                 return n * 12 // Trampolines in ARM64 are 3 instructions.
95         }
96         panic("unreachable")
97 }
98
99 // Detect too-far jumps in function s, and add trampolines if necessary.
100 // ARM, PPC64, PPC64LE and RISCV64 support trampoline insertion for internal
101 // and external linking. On PPC64 and PPC64LE the text sections might be split
102 // but will still insert trampolines where necessary.
103 func trampoline(ctxt *Link, s loader.Sym) {
104         if thearch.Trampoline == nil {
105                 return // no need or no support of trampolines on this arch
106         }
107
108         ldr := ctxt.loader
109         relocs := ldr.Relocs(s)
110         for ri := 0; ri < relocs.Count(); ri++ {
111                 r := relocs.At(ri)
112                 rt := r.Type()
113                 if !rt.IsDirectCallOrJump() && !isPLTCall(rt) {
114                         continue
115                 }
116                 rs := r.Sym()
117                 if !ldr.AttrReachable(rs) || ldr.SymType(rs) == sym.Sxxx {
118                         continue // something is wrong. skip it here and we'll emit a better error later
119                 }
120
121                 // RISC-V is only able to reach +/-1MiB via a JAL instruction,
122                 // which we can readily exceed in the same package. As such, we
123                 // need to generate trampolines when the address is unknown.
124                 if ldr.SymValue(rs) == 0 && !ctxt.Target.IsRISCV64() && ldr.SymType(rs) != sym.SDYNIMPORT && ldr.SymType(rs) != sym.SUNDEFEXT {
125                         if ldr.SymPkg(s) != "" && ldr.SymPkg(rs) == ldr.SymPkg(s) {
126                                 // Symbols in the same package are laid out together.
127                                 // Except that if SymPkg(s) == "", it is a host object symbol
128                                 // which may call an external symbol via PLT.
129                                 continue
130                         }
131                         if isRuntimeDepPkg(ldr.SymPkg(s)) && isRuntimeDepPkg(ldr.SymPkg(rs)) {
132                                 continue // runtime packages are laid out together
133                         }
134                 }
135                 thearch.Trampoline(ctxt, ldr, ri, rs, s)
136         }
137 }
138
139 // whether rt is a (host object) relocation that will be turned into
140 // a call to PLT.
141 func isPLTCall(rt objabi.RelocType) bool {
142         const pcrel = 1
143         switch rt {
144         // ARM64
145         case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_CALL26),
146                 objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_JUMP26),
147                 objabi.MachoRelocOffset + MACHO_ARM64_RELOC_BRANCH26*2 + pcrel:
148                 return true
149
150         // ARM
151         case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_CALL),
152                 objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_PC24),
153                 objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_JUMP24):
154                 return true
155         }
156         // TODO: other architectures.
157         return false
158 }
159
160 // FoldSubSymbolOffset computes the offset of symbol s to its top-level outer
161 // symbol. Returns the top-level symbol and the offset.
162 // This is used in generating external relocations.
163 func FoldSubSymbolOffset(ldr *loader.Loader, s loader.Sym) (loader.Sym, int64) {
164         outer := ldr.OuterSym(s)
165         off := int64(0)
166         if outer != 0 {
167                 off += ldr.SymValue(s) - ldr.SymValue(outer)
168                 s = outer
169         }
170         return s, off
171 }
172
173 // relocsym resolve relocations in "s", updating the symbol's content
174 // in "P".
175 // The main loop walks through the list of relocations attached to "s"
176 // and resolves them where applicable. Relocations are often
177 // architecture-specific, requiring calls into the 'archreloc' and/or
178 // 'archrelocvariant' functions for the architecture. When external
179 // linking is in effect, it may not be  possible to completely resolve
180 // the address/offset for a symbol, in which case the goal is to lay
181 // the groundwork for turning a given relocation into an external reloc
182 // (to be applied by the external linker). For more on how relocations
183 // work in general, see
184 //
185 //      "Linkers and Loaders", by John R. Levine (Morgan Kaufmann, 1999), ch. 7
186 //
187 // This is a performance-critical function for the linker; be careful
188 // to avoid introducing unnecessary allocations in the main loop.
189 func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
190         ldr := st.ldr
191         relocs := ldr.Relocs(s)
192         if relocs.Count() == 0 {
193                 return
194         }
195         target := st.target
196         syms := st.syms
197         nExtReloc := 0 // number of external relocations
198         for ri := 0; ri < relocs.Count(); ri++ {
199                 r := relocs.At(ri)
200                 off := r.Off()
201                 siz := int32(r.Siz())
202                 rs := r.Sym()
203                 rt := r.Type()
204                 weak := r.Weak()
205                 if off < 0 || off+siz > int32(len(P)) {
206                         rname := ""
207                         if rs != 0 {
208                                 rname = ldr.SymName(rs)
209                         }
210                         st.err.Errorf(s, "invalid relocation %s: %d+%d not in [%d,%d)", rname, off, siz, 0, len(P))
211                         continue
212                 }
213                 if siz == 0 { // informational relocation - no work to do
214                         continue
215                 }
216
217                 var rst sym.SymKind
218                 if rs != 0 {
219                         rst = ldr.SymType(rs)
220                 }
221
222                 if rs != 0 && (rst == sym.Sxxx || rst == sym.SXREF) {
223                         // When putting the runtime but not main into a shared library
224                         // these symbols are undefined and that's OK.
225                         if target.IsShared() || target.IsPlugin() {
226                                 if ldr.SymName(rs) == "main.main" || (!target.IsPlugin() && ldr.SymName(rs) == "main..inittask") {
227                                         sb := ldr.MakeSymbolUpdater(rs)
228                                         sb.SetType(sym.SDYNIMPORT)
229                                 } else if strings.HasPrefix(ldr.SymName(rs), "go:info.") {
230                                         // Skip go.info symbols. They are only needed to communicate
231                                         // DWARF info between the compiler and linker.
232                                         continue
233                                 }
234                         } else if target.IsPPC64() && ldr.SymName(rs) == ".TOC." {
235                                 // TOC symbol doesn't have a type but we do assign a value
236                                 // (see the address pass) and we can resolve it.
237                                 // TODO: give it a type.
238                         } else {
239                                 st.err.errorUnresolved(ldr, s, rs)
240                                 continue
241                         }
242                 }
243
244                 if rt >= objabi.ElfRelocOffset {
245                         continue
246                 }
247
248                 // We need to be able to reference dynimport symbols when linking against
249                 // shared libraries, and AIX, Darwin, OpenBSD and Solaris always need it.
250                 if !target.IsAIX() && !target.IsDarwin() && !target.IsSolaris() && !target.IsOpenbsd() && rs != 0 && rst == sym.SDYNIMPORT && !target.IsDynlinkingGo() && !ldr.AttrSubSymbol(rs) {
251                         if !(target.IsPPC64() && target.IsExternal() && ldr.SymName(rs) == ".TOC.") {
252                                 st.err.Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", ldr.SymName(rs), rst, rst, rt, sym.RelocName(target.Arch, rt))
253                         }
254                 }
255                 if rs != 0 && rst != sym.STLSBSS && !weak && rt != objabi.R_METHODOFF && !ldr.AttrReachable(rs) {
256                         st.err.Errorf(s, "unreachable sym in relocation: %s", ldr.SymName(rs))
257                 }
258
259                 var rv sym.RelocVariant
260                 if target.IsPPC64() || target.IsS390X() {
261                         rv = ldr.RelocVariant(s, ri)
262                 }
263
264                 // TODO(mundaym): remove this special case - see issue 14218.
265                 if target.IsS390X() {
266                         switch rt {
267                         case objabi.R_PCRELDBL:
268                                 rt = objabi.R_PCREL
269                                 rv = sym.RV_390_DBL
270                         case objabi.R_CALL:
271                                 rv = sym.RV_390_DBL
272                         }
273                 }
274
275                 var o int64
276                 switch rt {
277                 default:
278                         switch siz {
279                         default:
280                                 st.err.Errorf(s, "bad reloc size %#x for %s", uint32(siz), ldr.SymName(rs))
281                         case 1:
282                                 o = int64(P[off])
283                         case 2:
284                                 o = int64(target.Arch.ByteOrder.Uint16(P[off:]))
285                         case 4:
286                                 o = int64(target.Arch.ByteOrder.Uint32(P[off:]))
287                         case 8:
288                                 o = int64(target.Arch.ByteOrder.Uint64(P[off:]))
289                         }
290                         out, n, ok := thearch.Archreloc(target, ldr, syms, r, s, o)
291                         if target.IsExternal() {
292                                 nExtReloc += n
293                         }
294                         if ok {
295                                 o = out
296                         } else {
297                                 st.err.Errorf(s, "unknown reloc to %v: %d (%s)", ldr.SymName(rs), rt, sym.RelocName(target.Arch, rt))
298                         }
299                 case objabi.R_TLS_LE:
300                         if target.IsExternal() && target.IsElf() {
301                                 nExtReloc++
302                                 o = 0
303                                 if !target.IsAMD64() {
304                                         o = r.Add()
305                                 }
306                                 break
307                         }
308
309                         if target.IsElf() && target.IsARM() {
310                                 // On ELF ARM, the thread pointer is 8 bytes before
311                                 // the start of the thread-local data block, so add 8
312                                 // to the actual TLS offset (r->sym->value).
313                                 // This 8 seems to be a fundamental constant of
314                                 // ELF on ARM (or maybe Glibc on ARM); it is not
315                                 // related to the fact that our own TLS storage happens
316                                 // to take up 8 bytes.
317                                 o = 8 + ldr.SymValue(rs)
318                         } else if target.IsElf() || target.IsPlan9() || target.IsDarwin() {
319                                 o = int64(syms.Tlsoffset) + r.Add()
320                         } else if target.IsWindows() {
321                                 o = r.Add()
322                         } else {
323                                 log.Fatalf("unexpected R_TLS_LE relocation for %v", target.HeadType)
324                         }
325                 case objabi.R_TLS_IE:
326                         if target.IsExternal() && target.IsElf() {
327                                 nExtReloc++
328                                 o = 0
329                                 if !target.IsAMD64() {
330                                         o = r.Add()
331                                 }
332                                 if target.Is386() {
333                                         nExtReloc++ // need two ELF relocations on 386, see ../x86/asm.go:elfreloc1
334                                 }
335                                 break
336                         }
337                         if target.IsPIE() && target.IsElf() {
338                                 // We are linking the final executable, so we
339                                 // can optimize any TLS IE relocation to LE.
340                                 if thearch.TLSIEtoLE == nil {
341                                         log.Fatalf("internal linking of TLS IE not supported on %v", target.Arch.Family)
342                                 }
343                                 thearch.TLSIEtoLE(P, int(off), int(siz))
344                                 o = int64(syms.Tlsoffset)
345                         } else {
346                                 log.Fatalf("cannot handle R_TLS_IE (sym %s) when linking internally", ldr.SymName(s))
347                         }
348                 case objabi.R_ADDR, objabi.R_PEIMAGEOFF:
349                         if weak && !ldr.AttrReachable(rs) {
350                                 // Redirect it to runtime.unreachableMethod, which will throw if called.
351                                 rs = syms.unreachableMethod
352                         }
353                         if target.IsExternal() {
354                                 nExtReloc++
355
356                                 // set up addend for eventual relocation via outer symbol.
357                                 rs := rs
358                                 rs, off := FoldSubSymbolOffset(ldr, rs)
359                                 xadd := r.Add() + off
360                                 rst := ldr.SymType(rs)
361                                 if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && rst != sym.SUNDEFEXT && ldr.SymSect(rs) == nil {
362                                         st.err.Errorf(s, "missing section for relocation target %s", ldr.SymName(rs))
363                                 }
364
365                                 o = xadd
366                                 if target.IsElf() {
367                                         if target.IsAMD64() {
368                                                 o = 0
369                                         }
370                                 } else if target.IsDarwin() {
371                                         if ldr.SymType(rs) != sym.SHOSTOBJ {
372                                                 o += ldr.SymValue(rs)
373                                         }
374                                 } else if target.IsWindows() {
375                                         // nothing to do
376                                 } else if target.IsAIX() {
377                                         o = ldr.SymValue(rs) + xadd
378                                 } else {
379                                         st.err.Errorf(s, "unhandled pcrel relocation to %s on %v", ldr.SymName(rs), target.HeadType)
380                                 }
381
382                                 break
383                         }
384
385                         // On AIX, a second relocation must be done by the loader,
386                         // as section addresses can change once loaded.
387                         // The "default" symbol address is still needed by the loader so
388                         // the current relocation can't be skipped.
389                         if target.IsAIX() && rst != sym.SDYNIMPORT {
390                                 // It's not possible to make a loader relocation in a
391                                 // symbol which is not inside .data section.
392                                 // FIXME: It should be forbidden to have R_ADDR from a
393                                 // symbol which isn't in .data. However, as .text has the
394                                 // same address once loaded, this is possible.
395                                 if ldr.SymSect(s).Seg == &Segdata {
396                                         Xcoffadddynrel(target, ldr, syms, s, r, ri)
397                                 }
398                         }
399
400                         o = ldr.SymValue(rs) + r.Add()
401                         if rt == objabi.R_PEIMAGEOFF {
402                                 // The R_PEIMAGEOFF offset is a RVA, so subtract
403                                 // the base address for the executable.
404                                 o -= PEBASE
405                         }
406
407                         // On amd64, 4-byte offsets will be sign-extended, so it is impossible to
408                         // access more than 2GB of static data; fail at link time is better than
409                         // fail at runtime. See https://golang.org/issue/7980.
410                         // Instead of special casing only amd64, we treat this as an error on all
411                         // 64-bit architectures so as to be future-proof.
412                         if int32(o) < 0 && target.Arch.PtrSize > 4 && siz == 4 {
413                                 st.err.Errorf(s, "non-pc-relative relocation address for %s is too big: %#x (%#x + %#x)", ldr.SymName(rs), uint64(o), ldr.SymValue(rs), r.Add())
414                                 errorexit()
415                         }
416                 case objabi.R_DWARFSECREF:
417                         if ldr.SymSect(rs) == nil {
418                                 st.err.Errorf(s, "missing DWARF section for relocation target %s", ldr.SymName(rs))
419                         }
420
421                         if target.IsExternal() {
422                                 // On most platforms, the external linker needs to adjust DWARF references
423                                 // as it combines DWARF sections. However, on Darwin, dsymutil does the
424                                 // DWARF linking, and it understands how to follow section offsets.
425                                 // Leaving in the relocation records confuses it (see
426                                 // https://golang.org/issue/22068) so drop them for Darwin.
427                                 if !target.IsDarwin() {
428                                         nExtReloc++
429                                 }
430
431                                 xadd := r.Add() + ldr.SymValue(rs) - int64(ldr.SymSect(rs).Vaddr)
432
433                                 o = xadd
434                                 if target.IsElf() && target.IsAMD64() {
435                                         o = 0
436                                 }
437                                 break
438                         }
439                         o = ldr.SymValue(rs) + r.Add() - int64(ldr.SymSect(rs).Vaddr)
440                 case objabi.R_METHODOFF:
441                         if !ldr.AttrReachable(rs) {
442                                 // Set it to a sentinel value. The runtime knows this is not pointing to
443                                 // anything valid.
444                                 o = -1
445                                 break
446                         }
447                         fallthrough
448                 case objabi.R_ADDROFF:
449                         if weak && !ldr.AttrReachable(rs) {
450                                 continue
451                         }
452                         sect := ldr.SymSect(rs)
453                         if sect == nil {
454                                 if rst == sym.SDYNIMPORT {
455                                         st.err.Errorf(s, "cannot target DYNIMPORT sym in section-relative reloc: %s", ldr.SymName(rs))
456                                 } else if rst == sym.SUNDEFEXT {
457                                         st.err.Errorf(s, "undefined symbol in relocation: %s", ldr.SymName(rs))
458                                 } else {
459                                         st.err.Errorf(s, "missing section for relocation target %s", ldr.SymName(rs))
460                                 }
461                                 continue
462                         }
463
464                         // The method offset tables using this relocation expect the offset to be relative
465                         // to the start of the first text section, even if there are multiple.
466                         if sect.Name == ".text" {
467                                 o = ldr.SymValue(rs) - int64(Segtext.Sections[0].Vaddr) + r.Add()
468                         } else {
469                                 o = ldr.SymValue(rs) - int64(ldr.SymSect(rs).Vaddr) + r.Add()
470                         }
471
472                 case objabi.R_ADDRCUOFF:
473                         // debug_range and debug_loc elements use this relocation type to get an
474                         // offset from the start of the compile unit.
475                         o = ldr.SymValue(rs) + r.Add() - ldr.SymValue(loader.Sym(ldr.SymUnit(rs).Textp[0]))
476
477                 // r.Sym() can be 0 when CALL $(constant) is transformed from absolute PC to relative PC call.
478                 case objabi.R_GOTPCREL:
479                         if target.IsDynlinkingGo() && target.IsDarwin() && rs != 0 {
480                                 nExtReloc++
481                                 o = r.Add()
482                                 break
483                         }
484                         if target.Is386() && target.IsExternal() && target.IsELF {
485                                 nExtReloc++ // need two ELF relocations on 386, see ../x86/asm.go:elfreloc1
486                         }
487                         fallthrough
488                 case objabi.R_CALL, objabi.R_PCREL:
489                         if target.IsExternal() && rs != 0 && rst == sym.SUNDEFEXT {
490                                 // pass through to the external linker.
491                                 nExtReloc++
492                                 o = 0
493                                 break
494                         }
495                         if target.IsExternal() && rs != 0 && (ldr.SymSect(rs) != ldr.SymSect(s) || rt == objabi.R_GOTPCREL) {
496                                 nExtReloc++
497
498                                 // set up addend for eventual relocation via outer symbol.
499                                 rs := rs
500                                 rs, off := FoldSubSymbolOffset(ldr, rs)
501                                 xadd := r.Add() + off - int64(siz) // relative to address after the relocated chunk
502                                 rst := ldr.SymType(rs)
503                                 if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && ldr.SymSect(rs) == nil {
504                                         st.err.Errorf(s, "missing section for relocation target %s", ldr.SymName(rs))
505                                 }
506
507                                 o = xadd
508                                 if target.IsElf() {
509                                         if target.IsAMD64() {
510                                                 o = 0
511                                         }
512                                 } else if target.IsDarwin() {
513                                         if rt == objabi.R_CALL {
514                                                 if target.IsExternal() && rst == sym.SDYNIMPORT {
515                                                         if target.IsAMD64() {
516                                                                 // AMD64 dynamic relocations are relative to the end of the relocation.
517                                                                 o += int64(siz)
518                                                         }
519                                                 } else {
520                                                         if rst != sym.SHOSTOBJ {
521                                                                 o += int64(uint64(ldr.SymValue(rs)) - ldr.SymSect(rs).Vaddr)
522                                                         }
523                                                         o -= int64(off) // relative to section offset, not symbol
524                                                 }
525                                         } else {
526                                                 o += int64(siz)
527                                         }
528                                 } else if target.IsWindows() && target.IsAMD64() { // only amd64 needs PCREL
529                                         // PE/COFF's PC32 relocation uses the address after the relocated
530                                         // bytes as the base. Compensate by skewing the addend.
531                                         o += int64(siz)
532                                 } else {
533                                         st.err.Errorf(s, "unhandled pcrel relocation to %s on %v", ldr.SymName(rs), target.HeadType)
534                                 }
535
536                                 break
537                         }
538
539                         o = 0
540                         if rs != 0 {
541                                 o = ldr.SymValue(rs)
542                         }
543
544                         o += r.Add() - (ldr.SymValue(s) + int64(off) + int64(siz))
545                 case objabi.R_SIZE:
546                         o = ldr.SymSize(rs) + r.Add()
547
548                 case objabi.R_XCOFFREF:
549                         if !target.IsAIX() {
550                                 st.err.Errorf(s, "find XCOFF R_REF on non-XCOFF files")
551                         }
552                         if !target.IsExternal() {
553                                 st.err.Errorf(s, "find XCOFF R_REF with internal linking")
554                         }
555                         nExtReloc++
556                         continue
557
558                 case objabi.R_DWARFFILEREF:
559                         // We don't renumber files in dwarf.go:writelines anymore.
560                         continue
561
562                 case objabi.R_CONST:
563                         o = r.Add()
564
565                 case objabi.R_GOTOFF:
566                         o = ldr.SymValue(rs) + r.Add() - ldr.SymValue(syms.GOT)
567                 }
568
569                 if target.IsPPC64() || target.IsS390X() {
570                         if rv != sym.RV_NONE {
571                                 o = thearch.Archrelocvariant(target, ldr, r, rv, s, o, P)
572                         }
573                 }
574
575                 switch siz {
576                 default:
577                         st.err.Errorf(s, "bad reloc size %#x for %s", uint32(siz), ldr.SymName(rs))
578                 case 1:
579                         P[off] = byte(int8(o))
580                 case 2:
581                         if o != int64(int16(o)) {
582                                 st.err.Errorf(s, "relocation address for %s is too big: %#x", ldr.SymName(rs), o)
583                         }
584                         target.Arch.ByteOrder.PutUint16(P[off:], uint16(o))
585                 case 4:
586                         if rt == objabi.R_PCREL || rt == objabi.R_CALL {
587                                 if o != int64(int32(o)) {
588                                         st.err.Errorf(s, "pc-relative relocation address for %s is too big: %#x", ldr.SymName(rs), o)
589                                 }
590                         } else {
591                                 if o != int64(int32(o)) && o != int64(uint32(o)) {
592                                         st.err.Errorf(s, "non-pc-relative relocation address for %s is too big: %#x", ldr.SymName(rs), uint64(o))
593                                 }
594                         }
595                         target.Arch.ByteOrder.PutUint32(P[off:], uint32(o))
596                 case 8:
597                         target.Arch.ByteOrder.PutUint64(P[off:], uint64(o))
598                 }
599         }
600         if target.IsExternal() {
601                 // We'll stream out the external relocations in asmb2 (e.g. elfrelocsect)
602                 // and we only need the count here.
603                 atomic.AddUint32(&ldr.SymSect(s).Relcount, uint32(nExtReloc))
604         }
605 }
606
607 // Convert a Go relocation to an external relocation.
608 func extreloc(ctxt *Link, ldr *loader.Loader, s loader.Sym, r loader.Reloc) (loader.ExtReloc, bool) {
609         var rr loader.ExtReloc
610         target := &ctxt.Target
611         siz := int32(r.Siz())
612         if siz == 0 { // informational relocation - no work to do
613                 return rr, false
614         }
615
616         rt := r.Type()
617         if rt >= objabi.ElfRelocOffset {
618                 return rr, false
619         }
620         rr.Type = rt
621         rr.Size = uint8(siz)
622
623         // TODO(mundaym): remove this special case - see issue 14218.
624         if target.IsS390X() {
625                 switch rt {
626                 case objabi.R_PCRELDBL:
627                         rt = objabi.R_PCREL
628                 }
629         }
630
631         switch rt {
632         default:
633                 return thearch.Extreloc(target, ldr, r, s)
634
635         case objabi.R_TLS_LE, objabi.R_TLS_IE:
636                 if target.IsElf() {
637                         rs := r.Sym()
638                         rr.Xsym = rs
639                         if rr.Xsym == 0 {
640                                 rr.Xsym = ctxt.Tlsg
641                         }
642                         rr.Xadd = r.Add()
643                         break
644                 }
645                 return rr, false
646
647         case objabi.R_ADDR, objabi.R_PEIMAGEOFF:
648                 // set up addend for eventual relocation via outer symbol.
649                 rs := r.Sym()
650                 if r.Weak() && !ldr.AttrReachable(rs) {
651                         rs = ctxt.ArchSyms.unreachableMethod
652                 }
653                 rs, off := FoldSubSymbolOffset(ldr, rs)
654                 rr.Xadd = r.Add() + off
655                 rr.Xsym = rs
656
657         case objabi.R_DWARFSECREF:
658                 // On most platforms, the external linker needs to adjust DWARF references
659                 // as it combines DWARF sections. However, on Darwin, dsymutil does the
660                 // DWARF linking, and it understands how to follow section offsets.
661                 // Leaving in the relocation records confuses it (see
662                 // https://golang.org/issue/22068) so drop them for Darwin.
663                 if target.IsDarwin() {
664                         return rr, false
665                 }
666                 rs := r.Sym()
667                 rr.Xsym = loader.Sym(ldr.SymSect(rs).Sym)
668                 rr.Xadd = r.Add() + ldr.SymValue(rs) - int64(ldr.SymSect(rs).Vaddr)
669
670         // r.Sym() can be 0 when CALL $(constant) is transformed from absolute PC to relative PC call.
671         case objabi.R_GOTPCREL, objabi.R_CALL, objabi.R_PCREL:
672                 rs := r.Sym()
673                 if rt == objabi.R_GOTPCREL && target.IsDynlinkingGo() && target.IsDarwin() && rs != 0 {
674                         rr.Xadd = r.Add()
675                         rr.Xadd -= int64(siz) // relative to address after the relocated chunk
676                         rr.Xsym = rs
677                         break
678                 }
679                 if rs != 0 && ldr.SymType(rs) == sym.SUNDEFEXT {
680                         // pass through to the external linker.
681                         rr.Xadd = 0
682                         if target.IsElf() {
683                                 rr.Xadd -= int64(siz)
684                         }
685                         rr.Xsym = rs
686                         break
687                 }
688                 if rs != 0 && (ldr.SymSect(rs) != ldr.SymSect(s) || rt == objabi.R_GOTPCREL) {
689                         // set up addend for eventual relocation via outer symbol.
690                         rs := rs
691                         rs, off := FoldSubSymbolOffset(ldr, rs)
692                         rr.Xadd = r.Add() + off
693                         rr.Xadd -= int64(siz) // relative to address after the relocated chunk
694                         rr.Xsym = rs
695                         break
696                 }
697                 return rr, false
698
699         case objabi.R_XCOFFREF:
700                 return ExtrelocSimple(ldr, r), true
701
702         // These reloc types don't need external relocations.
703         case objabi.R_ADDROFF, objabi.R_METHODOFF, objabi.R_ADDRCUOFF,
704                 objabi.R_SIZE, objabi.R_CONST, objabi.R_GOTOFF:
705                 return rr, false
706         }
707         return rr, true
708 }
709
710 // ExtrelocSimple creates a simple external relocation from r, with the same
711 // symbol and addend.
712 func ExtrelocSimple(ldr *loader.Loader, r loader.Reloc) loader.ExtReloc {
713         var rr loader.ExtReloc
714         rs := r.Sym()
715         rr.Xsym = rs
716         rr.Xadd = r.Add()
717         rr.Type = r.Type()
718         rr.Size = r.Siz()
719         return rr
720 }
721
722 // ExtrelocViaOuterSym creates an external relocation from r targeting the
723 // outer symbol and folding the subsymbol's offset into the addend.
724 func ExtrelocViaOuterSym(ldr *loader.Loader, r loader.Reloc, s loader.Sym) loader.ExtReloc {
725         // set up addend for eventual relocation via outer symbol.
726         var rr loader.ExtReloc
727         rs := r.Sym()
728         rs, off := FoldSubSymbolOffset(ldr, rs)
729         rr.Xadd = r.Add() + off
730         rst := ldr.SymType(rs)
731         if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && rst != sym.SUNDEFEXT && ldr.SymSect(rs) == nil {
732                 ldr.Errorf(s, "missing section for %s", ldr.SymName(rs))
733         }
734         rr.Xsym = rs
735         rr.Type = r.Type()
736         rr.Size = r.Siz()
737         return rr
738 }
739
740 // relocSymState hold state information needed when making a series of
741 // successive calls to relocsym(). The items here are invariant
742 // (meaning that they are set up once initially and then don't change
743 // during the execution of relocsym), with the exception of a slice
744 // used to facilitate batch allocation of external relocations. Calls
745 // to relocsym happen in parallel; the assumption is that each
746 // parallel thread will have its own state object.
747 type relocSymState struct {
748         target *Target
749         ldr    *loader.Loader
750         err    *ErrorReporter
751         syms   *ArchSyms
752 }
753
754 // makeRelocSymState creates a relocSymState container object to
755 // pass to relocsym(). If relocsym() calls happen in parallel,
756 // each parallel thread should have its own state object.
757 func (ctxt *Link) makeRelocSymState() *relocSymState {
758         return &relocSymState{
759                 target: &ctxt.Target,
760                 ldr:    ctxt.loader,
761                 err:    &ctxt.ErrorReporter,
762                 syms:   &ctxt.ArchSyms,
763         }
764 }
765
766 // windynrelocsym examines a text symbol 's' and looks for relocations
767 // from it that correspond to references to symbols defined in DLLs,
768 // then fixes up those relocations as needed. A reference to a symbol
769 // XYZ from some DLL will fall into one of two categories: an indirect
770 // ref via "__imp_XYZ", or a direct ref to "XYZ". Here's an example of
771 // an indirect ref (this is an excerpt from objdump -ldr):
772 //
773 //           1c1: 48 89 c6                      movq    %rax, %rsi
774 //           1c4: ff 15 00 00 00 00             callq   *(%rip)
775 //                      00000000000001c6:  IMAGE_REL_AMD64_REL32        __imp__errno
776 //
777 // In the assembly above, the code loads up the value of __imp_errno
778 // and then does an indirect call to that value.
779 //
780 // Here is what a direct reference might look like:
781 //
782 //           137: e9 20 06 00 00                jmp     0x75c <pow+0x75c>
783 //           13c: e8 00 00 00 00                callq   0x141 <pow+0x141>
784 //                      000000000000013d:  IMAGE_REL_AMD64_REL32        _errno
785 //
786 // The assembly below dispenses with the import symbol and just makes
787 // a direct call to _errno.
788 //
789 // The code below handles indirect refs by redirecting the target of
790 // the relocation from "__imp_XYZ" to "XYZ" (since the latter symbol
791 // is what the Windows loader is expected to resolve). For direct refs
792 // the call is redirected to a stub, where the stub first loads the
793 // symbol and then direct an indirect call to that value.
794 //
795 // Note that for a given symbol (as above) it is perfectly legal to
796 // have both direct and indirect references.
797 func windynrelocsym(ctxt *Link, rel *loader.SymbolBuilder, s loader.Sym) error {
798         var su *loader.SymbolBuilder
799         relocs := ctxt.loader.Relocs(s)
800         for ri := 0; ri < relocs.Count(); ri++ {
801                 r := relocs.At(ri)
802                 if r.IsMarker() {
803                         continue // skip marker relocations
804                 }
805                 targ := r.Sym()
806                 if targ == 0 {
807                         continue
808                 }
809                 if !ctxt.loader.AttrReachable(targ) {
810                         if r.Weak() {
811                                 continue
812                         }
813                         return fmt.Errorf("dynamic relocation to unreachable symbol %s",
814                                 ctxt.loader.SymName(targ))
815                 }
816                 tgot := ctxt.loader.SymGot(targ)
817                 if tgot == loadpe.RedirectToDynImportGotToken {
818
819                         // Consistency check: name should be __imp_X
820                         sname := ctxt.loader.SymName(targ)
821                         if !strings.HasPrefix(sname, "__imp_") {
822                                 return fmt.Errorf("internal error in windynrelocsym: redirect GOT token applied to non-import symbol %s", sname)
823                         }
824
825                         // Locate underlying symbol (which originally had type
826                         // SDYNIMPORT but has since been retyped to SWINDOWS).
827                         ds, err := loadpe.LookupBaseFromImport(targ, ctxt.loader, ctxt.Arch)
828                         if err != nil {
829                                 return err
830                         }
831                         dstyp := ctxt.loader.SymType(ds)
832                         if dstyp != sym.SWINDOWS {
833                                 return fmt.Errorf("internal error in windynrelocsym: underlying sym for %q has wrong type %s", sname, dstyp.String())
834                         }
835
836                         // Redirect relocation to the dynimport.
837                         r.SetSym(ds)
838                         continue
839                 }
840
841                 tplt := ctxt.loader.SymPlt(targ)
842                 if tplt == loadpe.CreateImportStubPltToken {
843
844                         // Consistency check: don't want to see both PLT and GOT tokens.
845                         if tgot != -1 {
846                                 return fmt.Errorf("internal error in windynrelocsym: invalid GOT setting %d for reloc to %s", tgot, ctxt.loader.SymName(targ))
847                         }
848
849                         // make dynimport JMP table for PE object files.
850                         tplt := int32(rel.Size())
851                         ctxt.loader.SetPlt(targ, tplt)
852
853                         if su == nil {
854                                 su = ctxt.loader.MakeSymbolUpdater(s)
855                         }
856                         r.SetSym(rel.Sym())
857                         r.SetAdd(int64(tplt))
858
859                         // jmp *addr
860                         switch ctxt.Arch.Family {
861                         default:
862                                 return fmt.Errorf("internal error in windynrelocsym: unsupported arch %v", ctxt.Arch.Family)
863                         case sys.I386:
864                                 rel.AddUint8(0xff)
865                                 rel.AddUint8(0x25)
866                                 rel.AddAddrPlus(ctxt.Arch, targ, 0)
867                                 rel.AddUint8(0x90)
868                                 rel.AddUint8(0x90)
869                         case sys.AMD64:
870                                 rel.AddUint8(0xff)
871                                 rel.AddUint8(0x24)
872                                 rel.AddUint8(0x25)
873                                 rel.AddAddrPlus4(ctxt.Arch, targ, 0)
874                                 rel.AddUint8(0x90)
875                         }
876                 } else if tplt >= 0 {
877                         if su == nil {
878                                 su = ctxt.loader.MakeSymbolUpdater(s)
879                         }
880                         r.SetSym(rel.Sym())
881                         r.SetAdd(int64(tplt))
882                 }
883         }
884         return nil
885 }
886
887 // windynrelocsyms generates jump table to C library functions that will be
888 // added later. windynrelocsyms writes the table into .rel symbol.
889 func (ctxt *Link) windynrelocsyms() {
890         if !(ctxt.IsWindows() && iscgo && ctxt.IsInternal()) {
891                 return
892         }
893
894         rel := ctxt.loader.CreateSymForUpdate(".rel", 0)
895         rel.SetType(sym.STEXT)
896
897         for _, s := range ctxt.Textp {
898                 if err := windynrelocsym(ctxt, rel, s); err != nil {
899                         ctxt.Errorf(s, "%v", err)
900                 }
901         }
902
903         ctxt.Textp = append(ctxt.Textp, rel.Sym())
904 }
905
906 func dynrelocsym(ctxt *Link, s loader.Sym) {
907         target := &ctxt.Target
908         ldr := ctxt.loader
909         syms := &ctxt.ArchSyms
910         relocs := ldr.Relocs(s)
911         for ri := 0; ri < relocs.Count(); ri++ {
912                 r := relocs.At(ri)
913                 if r.IsMarker() {
914                         continue // skip marker relocations
915                 }
916                 rSym := r.Sym()
917                 if r.Weak() && !ldr.AttrReachable(rSym) {
918                         continue
919                 }
920                 if ctxt.BuildMode == BuildModePIE && ctxt.LinkMode == LinkInternal {
921                         // It's expected that some relocations will be done
922                         // later by relocsym (R_TLS_LE, R_ADDROFF), so
923                         // don't worry if Adddynrel returns false.
924                         thearch.Adddynrel(target, ldr, syms, s, r, ri)
925                         continue
926                 }
927
928                 if rSym != 0 && ldr.SymType(rSym) == sym.SDYNIMPORT || r.Type() >= objabi.ElfRelocOffset {
929                         if rSym != 0 && !ldr.AttrReachable(rSym) {
930                                 ctxt.Errorf(s, "dynamic relocation to unreachable symbol %s", ldr.SymName(rSym))
931                         }
932                         if !thearch.Adddynrel(target, ldr, syms, s, r, ri) {
933                                 ctxt.Errorf(s, "unsupported dynamic relocation for symbol %s (type=%d (%s) stype=%d (%s))", ldr.SymName(rSym), r.Type(), sym.RelocName(ctxt.Arch, r.Type()), ldr.SymType(rSym), ldr.SymType(rSym))
934                         }
935                 }
936         }
937 }
938
939 func (state *dodataState) dynreloc(ctxt *Link) {
940         if ctxt.HeadType == objabi.Hwindows {
941                 return
942         }
943         // -d suppresses dynamic loader format, so we may as well not
944         // compute these sections or mark their symbols as reachable.
945         if *FlagD {
946                 return
947         }
948
949         for _, s := range ctxt.Textp {
950                 dynrelocsym(ctxt, s)
951         }
952         for _, syms := range state.data {
953                 for _, s := range syms {
954                         dynrelocsym(ctxt, s)
955                 }
956         }
957         if ctxt.IsELF {
958                 elfdynhash(ctxt)
959         }
960 }
961
962 func CodeblkPad(ctxt *Link, out *OutBuf, addr int64, size int64, pad []byte) {
963         writeBlocks(ctxt, out, ctxt.outSem, ctxt.loader, ctxt.Textp, addr, size, pad)
964 }
965
966 const blockSize = 1 << 20 // 1MB chunks written at a time.
967
968 // writeBlocks writes a specified chunk of symbols to the output buffer. It
969 // breaks the write up into ≥blockSize chunks to write them out, and schedules
970 // as many goroutines as necessary to accomplish this task. This call then
971 // blocks, waiting on the writes to complete. Note that we use the sem parameter
972 // to limit the number of concurrent writes taking place.
973 func writeBlocks(ctxt *Link, out *OutBuf, sem chan int, ldr *loader.Loader, syms []loader.Sym, addr, size int64, pad []byte) {
974         for i, s := range syms {
975                 if ldr.SymValue(s) >= addr && !ldr.AttrSubSymbol(s) {
976                         syms = syms[i:]
977                         break
978                 }
979         }
980
981         var wg sync.WaitGroup
982         max, lastAddr, written := int64(blockSize), addr+size, int64(0)
983         for addr < lastAddr {
984                 // Find the last symbol we'd write.
985                 idx := -1
986                 for i, s := range syms {
987                         if ldr.AttrSubSymbol(s) {
988                                 continue
989                         }
990
991                         // If the next symbol's size would put us out of bounds on the total length,
992                         // stop looking.
993                         end := ldr.SymValue(s) + ldr.SymSize(s)
994                         if end > lastAddr {
995                                 break
996                         }
997
998                         // We're gonna write this symbol.
999                         idx = i
1000
1001                         // If we cross over the max size, we've got enough symbols.
1002                         if end > addr+max {
1003                                 break
1004                         }
1005                 }
1006
1007                 // If we didn't find any symbols to write, we're done here.
1008                 if idx < 0 {
1009                         break
1010                 }
1011
1012                 // Compute the length to write, including padding.
1013                 // We need to write to the end address (lastAddr), or the next symbol's
1014                 // start address, whichever comes first. If there is no more symbols,
1015                 // just write to lastAddr. This ensures we don't leave holes between the
1016                 // blocks or at the end.
1017                 length := int64(0)
1018                 if idx+1 < len(syms) {
1019                         // Find the next top-level symbol.
1020                         // Skip over sub symbols so we won't split a container symbol
1021                         // into two blocks.
1022                         next := syms[idx+1]
1023                         for ldr.AttrSubSymbol(next) {
1024                                 idx++
1025                                 next = syms[idx+1]
1026                         }
1027                         length = ldr.SymValue(next) - addr
1028                 }
1029                 if length == 0 || length > lastAddr-addr {
1030                         length = lastAddr - addr
1031                 }
1032
1033                 // Start the block output operator.
1034                 if o, err := out.View(uint64(out.Offset() + written)); err == nil {
1035                         sem <- 1
1036                         wg.Add(1)
1037                         go func(o *OutBuf, ldr *loader.Loader, syms []loader.Sym, addr, size int64, pad []byte) {
1038                                 writeBlock(ctxt, o, ldr, syms, addr, size, pad)
1039                                 wg.Done()
1040                                 <-sem
1041                         }(o, ldr, syms, addr, length, pad)
1042                 } else { // output not mmaped, don't parallelize.
1043                         writeBlock(ctxt, out, ldr, syms, addr, length, pad)
1044                 }
1045
1046                 // Prepare for the next loop.
1047                 if idx != -1 {
1048                         syms = syms[idx+1:]
1049                 }
1050                 written += length
1051                 addr += length
1052         }
1053         wg.Wait()
1054 }
1055
1056 func writeBlock(ctxt *Link, out *OutBuf, ldr *loader.Loader, syms []loader.Sym, addr, size int64, pad []byte) {
1057
1058         st := ctxt.makeRelocSymState()
1059
1060         // This doesn't distinguish the memory size from the file
1061         // size, and it lays out the file based on Symbol.Value, which
1062         // is the virtual address. DWARF compression changes file sizes,
1063         // so dwarfcompress will fix this up later if necessary.
1064         eaddr := addr + size
1065         for _, s := range syms {
1066                 if ldr.AttrSubSymbol(s) {
1067                         continue
1068                 }
1069                 val := ldr.SymValue(s)
1070                 if val >= eaddr {
1071                         break
1072                 }
1073                 if val < addr {
1074                         ldr.Errorf(s, "phase error: addr=%#x but sym=%#x type=%v sect=%v", addr, val, ldr.SymType(s), ldr.SymSect(s).Name)
1075                         errorexit()
1076                 }
1077                 if addr < val {
1078                         out.WriteStringPad("", int(val-addr), pad)
1079                         addr = val
1080                 }
1081                 P := out.WriteSym(ldr, s)
1082                 st.relocsym(s, P)
1083                 if ldr.IsGeneratedSym(s) {
1084                         f := ctxt.generatorSyms[s]
1085                         f(ctxt, s)
1086                 }
1087                 addr += int64(len(P))
1088                 siz := ldr.SymSize(s)
1089                 if addr < val+siz {
1090                         out.WriteStringPad("", int(val+siz-addr), pad)
1091                         addr = val + siz
1092                 }
1093                 if addr != val+siz {
1094                         ldr.Errorf(s, "phase error: addr=%#x value+size=%#x", addr, val+siz)
1095                         errorexit()
1096                 }
1097                 if val+siz >= eaddr {
1098                         break
1099                 }
1100         }
1101
1102         if addr < eaddr {
1103                 out.WriteStringPad("", int(eaddr-addr), pad)
1104         }
1105 }
1106
1107 type writeFn func(*Link, *OutBuf, int64, int64)
1108
1109 // writeParallel handles scheduling parallel execution of data write functions.
1110 func writeParallel(wg *sync.WaitGroup, fn writeFn, ctxt *Link, seek, vaddr, length uint64) {
1111         if out, err := ctxt.Out.View(seek); err != nil {
1112                 ctxt.Out.SeekSet(int64(seek))
1113                 fn(ctxt, ctxt.Out, int64(vaddr), int64(length))
1114         } else {
1115                 wg.Add(1)
1116                 go func() {
1117                         defer wg.Done()
1118                         fn(ctxt, out, int64(vaddr), int64(length))
1119                 }()
1120         }
1121 }
1122
1123 func datblk(ctxt *Link, out *OutBuf, addr, size int64) {
1124         writeDatblkToOutBuf(ctxt, out, addr, size)
1125 }
1126
1127 // Used only on Wasm for now.
1128 func DatblkBytes(ctxt *Link, addr int64, size int64) []byte {
1129         buf := make([]byte, size)
1130         out := &OutBuf{heap: buf}
1131         writeDatblkToOutBuf(ctxt, out, addr, size)
1132         return buf
1133 }
1134
1135 func writeDatblkToOutBuf(ctxt *Link, out *OutBuf, addr int64, size int64) {
1136         writeBlocks(ctxt, out, ctxt.outSem, ctxt.loader, ctxt.datap, addr, size, zeros[:])
1137 }
1138
1139 func dwarfblk(ctxt *Link, out *OutBuf, addr int64, size int64) {
1140         // Concatenate the section symbol lists into a single list to pass
1141         // to writeBlocks.
1142         //
1143         // NB: ideally we would do a separate writeBlocks call for each
1144         // section, but this would run the risk of undoing any file offset
1145         // adjustments made during layout.
1146         n := 0
1147         for i := range dwarfp {
1148                 n += len(dwarfp[i].syms)
1149         }
1150         syms := make([]loader.Sym, 0, n)
1151         for i := range dwarfp {
1152                 syms = append(syms, dwarfp[i].syms...)
1153         }
1154         writeBlocks(ctxt, out, ctxt.outSem, ctxt.loader, syms, addr, size, zeros[:])
1155 }
1156
1157 var covCounterDataStartOff, covCounterDataLen uint64
1158
1159 var zeros [512]byte
1160
1161 var (
1162         strdata  = make(map[string]string)
1163         strnames []string
1164 )
1165
1166 func addstrdata1(ctxt *Link, arg string) {
1167         eq := strings.Index(arg, "=")
1168         dot := strings.LastIndex(arg[:eq+1], ".")
1169         if eq < 0 || dot < 0 {
1170                 Exitf("-X flag requires argument of the form importpath.name=value")
1171         }
1172         pkg := arg[:dot]
1173         if ctxt.BuildMode == BuildModePlugin && pkg == "main" {
1174                 pkg = *flagPluginPath
1175         }
1176         pkg = objabi.PathToPrefix(pkg)
1177         name := pkg + arg[dot:eq]
1178         value := arg[eq+1:]
1179         if _, ok := strdata[name]; !ok {
1180                 strnames = append(strnames, name)
1181         }
1182         strdata[name] = value
1183 }
1184
1185 // addstrdata sets the initial value of the string variable name to value.
1186 func addstrdata(arch *sys.Arch, l *loader.Loader, name, value string) {
1187         s := l.Lookup(name, 0)
1188         if s == 0 {
1189                 return
1190         }
1191         if goType := l.SymGoType(s); goType == 0 {
1192                 return
1193         } else if typeName := l.SymName(goType); typeName != "type:string" {
1194                 Errorf(nil, "%s: cannot set with -X: not a var of type string (%s)", name, typeName)
1195                 return
1196         }
1197         if !l.AttrReachable(s) {
1198                 return // don't bother setting unreachable variable
1199         }
1200         bld := l.MakeSymbolUpdater(s)
1201         if bld.Type() == sym.SBSS {
1202                 bld.SetType(sym.SDATA)
1203         }
1204
1205         p := fmt.Sprintf("%s.str", name)
1206         sbld := l.CreateSymForUpdate(p, 0)
1207         sbld.Addstring(value)
1208         sbld.SetType(sym.SRODATA)
1209
1210         // Don't reset the variable's size. String variable usually has size of
1211         // 2*PtrSize, but in ASAN build it can be larger due to red zone.
1212         // (See issue 56175.)
1213         bld.SetData(make([]byte, arch.PtrSize*2))
1214         bld.SetReadOnly(false)
1215         bld.ResetRelocs()
1216         bld.SetAddrPlus(arch, 0, sbld.Sym(), 0)
1217         bld.SetUint(arch, int64(arch.PtrSize), uint64(len(value)))
1218 }
1219
1220 func (ctxt *Link) dostrdata() {
1221         for _, name := range strnames {
1222                 addstrdata(ctxt.Arch, ctxt.loader, name, strdata[name])
1223         }
1224 }
1225
1226 // addgostring adds str, as a Go string value, to s. symname is the name of the
1227 // symbol used to define the string data and must be unique per linked object.
1228 func addgostring(ctxt *Link, ldr *loader.Loader, s *loader.SymbolBuilder, symname, str string) {
1229         sdata := ldr.CreateSymForUpdate(symname, 0)
1230         if sdata.Type() != sym.Sxxx {
1231                 ctxt.Errorf(s.Sym(), "duplicate symname in addgostring: %s", symname)
1232         }
1233         sdata.SetLocal(true)
1234         sdata.SetType(sym.SRODATA)
1235         sdata.SetSize(int64(len(str)))
1236         sdata.SetData([]byte(str))
1237         s.AddAddr(ctxt.Arch, sdata.Sym())
1238         s.AddUint(ctxt.Arch, uint64(len(str)))
1239 }
1240
1241 func addinitarrdata(ctxt *Link, ldr *loader.Loader, s loader.Sym) {
1242         p := ldr.SymName(s) + ".ptr"
1243         sp := ldr.CreateSymForUpdate(p, 0)
1244         sp.SetType(sym.SINITARR)
1245         sp.SetSize(0)
1246         sp.SetDuplicateOK(true)
1247         sp.AddAddr(ctxt.Arch, s)
1248 }
1249
1250 // symalign returns the required alignment for the given symbol s.
1251 func symalign(ldr *loader.Loader, s loader.Sym) int32 {
1252         min := int32(thearch.Minalign)
1253         align := ldr.SymAlign(s)
1254         if align >= min {
1255                 return align
1256         } else if align != 0 {
1257                 return min
1258         }
1259         align = int32(thearch.Maxalign)
1260         ssz := ldr.SymSize(s)
1261         for int64(align) > ssz && align > min {
1262                 align >>= 1
1263         }
1264         ldr.SetSymAlign(s, align)
1265         return align
1266 }
1267
1268 func aligndatsize(state *dodataState, datsize int64, s loader.Sym) int64 {
1269         return Rnd(datsize, int64(symalign(state.ctxt.loader, s)))
1270 }
1271
1272 const debugGCProg = false
1273
1274 type GCProg struct {
1275         ctxt *Link
1276         sym  *loader.SymbolBuilder
1277         w    gcprog.Writer
1278 }
1279
1280 func (p *GCProg) Init(ctxt *Link, name string) {
1281         p.ctxt = ctxt
1282         p.sym = ctxt.loader.CreateSymForUpdate(name, 0)
1283         p.w.Init(p.writeByte())
1284         if debugGCProg {
1285                 fmt.Fprintf(os.Stderr, "ld: start GCProg %s\n", name)
1286                 p.w.Debug(os.Stderr)
1287         }
1288 }
1289
1290 func (p *GCProg) writeByte() func(x byte) {
1291         return func(x byte) {
1292                 p.sym.AddUint8(x)
1293         }
1294 }
1295
1296 func (p *GCProg) End(size int64) {
1297         p.w.ZeroUntil(size / int64(p.ctxt.Arch.PtrSize))
1298         p.w.End()
1299         if debugGCProg {
1300                 fmt.Fprintf(os.Stderr, "ld: end GCProg\n")
1301         }
1302 }
1303
1304 func (p *GCProg) AddSym(s loader.Sym) {
1305         ldr := p.ctxt.loader
1306         typ := ldr.SymGoType(s)
1307
1308         // Things without pointers should be in sym.SNOPTRDATA or sym.SNOPTRBSS;
1309         // everything we see should have pointers and should therefore have a type.
1310         if typ == 0 {
1311                 switch ldr.SymName(s) {
1312                 case "runtime.data", "runtime.edata", "runtime.bss", "runtime.ebss":
1313                         // Ignore special symbols that are sometimes laid out
1314                         // as real symbols. See comment about dyld on darwin in
1315                         // the address function.
1316                         return
1317                 }
1318                 p.ctxt.Errorf(p.sym.Sym(), "missing Go type information for global symbol %s: size %d", ldr.SymName(s), ldr.SymSize(s))
1319                 return
1320         }
1321
1322         ptrsize := int64(p.ctxt.Arch.PtrSize)
1323         typData := ldr.Data(typ)
1324         nptr := decodetypePtrdata(p.ctxt.Arch, typData) / ptrsize
1325
1326         if debugGCProg {
1327                 fmt.Fprintf(os.Stderr, "gcprog sym: %s at %d (ptr=%d+%d)\n", ldr.SymName(s), ldr.SymValue(s), ldr.SymValue(s)/ptrsize, nptr)
1328         }
1329
1330         sval := ldr.SymValue(s)
1331         if decodetypeUsegcprog(p.ctxt.Arch, typData) == 0 {
1332                 // Copy pointers from mask into program.
1333                 mask := decodetypeGcmask(p.ctxt, typ)
1334                 for i := int64(0); i < nptr; i++ {
1335                         if (mask[i/8]>>uint(i%8))&1 != 0 {
1336                                 p.w.Ptr(sval/ptrsize + i)
1337                         }
1338                 }
1339                 return
1340         }
1341
1342         // Copy program.
1343         prog := decodetypeGcprog(p.ctxt, typ)
1344         p.w.ZeroUntil(sval / ptrsize)
1345         p.w.Append(prog[4:], nptr)
1346 }
1347
1348 // cutoff is the maximum data section size permitted by the linker
1349 // (see issue #9862).
1350 const cutoff = 2e9 // 2 GB (or so; looks better in errors than 2^31)
1351
1352 func (state *dodataState) checkdatsize(symn sym.SymKind) {
1353         if state.datsize > cutoff {
1354                 Errorf(nil, "too much data in section %v (over %v bytes)", symn, cutoff)
1355         }
1356 }
1357
1358 // fixZeroSizedSymbols gives a few special symbols with zero size some space.
1359 func fixZeroSizedSymbols(ctxt *Link) {
1360         // The values in moduledata are filled out by relocations
1361         // pointing to the addresses of these special symbols.
1362         // Typically these symbols have no size and are not laid
1363         // out with their matching section.
1364         //
1365         // However on darwin, dyld will find the special symbol
1366         // in the first loaded module, even though it is local.
1367         //
1368         // (An hypothesis, formed without looking in the dyld sources:
1369         // these special symbols have no size, so their address
1370         // matches a real symbol. The dynamic linker assumes we
1371         // want the normal symbol with the same address and finds
1372         // it in the other module.)
1373         //
1374         // To work around this we lay out the symbls whose
1375         // addresses are vital for multi-module programs to work
1376         // as normal symbols, and give them a little size.
1377         //
1378         // On AIX, as all DATA sections are merged together, ld might not put
1379         // these symbols at the beginning of their respective section if there
1380         // aren't real symbols, their alignment might not match the
1381         // first symbol alignment. Therefore, there are explicitly put at the
1382         // beginning of their section with the same alignment.
1383         if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) && !(ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
1384                 return
1385         }
1386
1387         ldr := ctxt.loader
1388         bss := ldr.CreateSymForUpdate("runtime.bss", 0)
1389         bss.SetSize(8)
1390         ldr.SetAttrSpecial(bss.Sym(), false)
1391
1392         ebss := ldr.CreateSymForUpdate("runtime.ebss", 0)
1393         ldr.SetAttrSpecial(ebss.Sym(), false)
1394
1395         data := ldr.CreateSymForUpdate("runtime.data", 0)
1396         data.SetSize(8)
1397         ldr.SetAttrSpecial(data.Sym(), false)
1398
1399         edata := ldr.CreateSymForUpdate("runtime.edata", 0)
1400         ldr.SetAttrSpecial(edata.Sym(), false)
1401
1402         if ctxt.HeadType == objabi.Haix {
1403                 // XCOFFTOC symbols are part of .data section.
1404                 edata.SetType(sym.SXCOFFTOC)
1405         }
1406
1407         types := ldr.CreateSymForUpdate("runtime.types", 0)
1408         types.SetType(sym.STYPE)
1409         types.SetSize(8)
1410         ldr.SetAttrSpecial(types.Sym(), false)
1411
1412         etypes := ldr.CreateSymForUpdate("runtime.etypes", 0)
1413         etypes.SetType(sym.SFUNCTAB)
1414         ldr.SetAttrSpecial(etypes.Sym(), false)
1415
1416         if ctxt.HeadType == objabi.Haix {
1417                 rodata := ldr.CreateSymForUpdate("runtime.rodata", 0)
1418                 rodata.SetType(sym.SSTRING)
1419                 rodata.SetSize(8)
1420                 ldr.SetAttrSpecial(rodata.Sym(), false)
1421
1422                 erodata := ldr.CreateSymForUpdate("runtime.erodata", 0)
1423                 ldr.SetAttrSpecial(erodata.Sym(), false)
1424         }
1425 }
1426
1427 // makeRelroForSharedLib creates a section of readonly data if necessary.
1428 func (state *dodataState) makeRelroForSharedLib(target *Link) {
1429         if !target.UseRelro() {
1430                 return
1431         }
1432
1433         // "read only" data with relocations needs to go in its own section
1434         // when building a shared library. We do this by boosting objects of
1435         // type SXXX with relocations to type SXXXRELRO.
1436         ldr := target.loader
1437         for _, symnro := range sym.ReadOnly {
1438                 symnrelro := sym.RelROMap[symnro]
1439
1440                 ro := []loader.Sym{}
1441                 relro := state.data[symnrelro]
1442
1443                 for _, s := range state.data[symnro] {
1444                         relocs := ldr.Relocs(s)
1445                         isRelro := relocs.Count() > 0
1446                         switch state.symType(s) {
1447                         case sym.STYPE, sym.STYPERELRO, sym.SGOFUNCRELRO:
1448                                 // Symbols are not sorted yet, so it is possible
1449                                 // that an Outer symbol has been changed to a
1450                                 // relro Type before it reaches here.
1451                                 isRelro = true
1452                         case sym.SFUNCTAB:
1453                                 if ldr.SymName(s) == "runtime.etypes" {
1454                                         // runtime.etypes must be at the end of
1455                                         // the relro data.
1456                                         isRelro = true
1457                                 }
1458                         case sym.SGOFUNC:
1459                                 // The only SGOFUNC symbols that contain relocations are .stkobj,
1460                                 // and their relocations are of type objabi.R_ADDROFF,
1461                                 // which always get resolved during linking.
1462                                 isRelro = false
1463                         }
1464                         if isRelro {
1465                                 state.setSymType(s, symnrelro)
1466                                 if outer := ldr.OuterSym(s); outer != 0 {
1467                                         state.setSymType(outer, symnrelro)
1468                                 }
1469                                 relro = append(relro, s)
1470                         } else {
1471                                 ro = append(ro, s)
1472                         }
1473                 }
1474
1475                 // Check that we haven't made two symbols with the same .Outer into
1476                 // different types (because references two symbols with non-nil Outer
1477                 // become references to the outer symbol + offset it's vital that the
1478                 // symbol and the outer end up in the same section).
1479                 for _, s := range relro {
1480                         if outer := ldr.OuterSym(s); outer != 0 {
1481                                 st := state.symType(s)
1482                                 ost := state.symType(outer)
1483                                 if st != ost {
1484                                         state.ctxt.Errorf(s, "inconsistent types for symbol and its Outer %s (%v != %v)",
1485                                                 ldr.SymName(outer), st, ost)
1486                                 }
1487                         }
1488                 }
1489
1490                 state.data[symnro] = ro
1491                 state.data[symnrelro] = relro
1492         }
1493 }
1494
1495 // dodataState holds bits of state information needed by dodata() and the
1496 // various helpers it calls. The lifetime of these items should not extend
1497 // past the end of dodata().
1498 type dodataState struct {
1499         // Link context
1500         ctxt *Link
1501         // Data symbols bucketed by type.
1502         data [sym.SXREF][]loader.Sym
1503         // Max alignment for each flavor of data symbol.
1504         dataMaxAlign [sym.SXREF]int32
1505         // Overridden sym type
1506         symGroupType []sym.SymKind
1507         // Current data size so far.
1508         datsize int64
1509 }
1510
1511 // A note on symType/setSymType below:
1512 //
1513 // In the legacy linker, the types of symbols (notably data symbols) are
1514 // changed during the symtab() phase so as to insure that similar symbols
1515 // are bucketed together, then their types are changed back again during
1516 // dodata. Symbol to section assignment also plays tricks along these lines
1517 // in the case where a relro segment is needed.
1518 //
1519 // The value returned from setType() below reflects the effects of
1520 // any overrides made by symtab and/or dodata.
1521
1522 // symType returns the (possibly overridden) type of 's'.
1523 func (state *dodataState) symType(s loader.Sym) sym.SymKind {
1524         if int(s) < len(state.symGroupType) {
1525                 if override := state.symGroupType[s]; override != 0 {
1526                         return override
1527                 }
1528         }
1529         return state.ctxt.loader.SymType(s)
1530 }
1531
1532 // setSymType sets a new override type for 's'.
1533 func (state *dodataState) setSymType(s loader.Sym, kind sym.SymKind) {
1534         if s == 0 {
1535                 panic("bad")
1536         }
1537         if int(s) < len(state.symGroupType) {
1538                 state.symGroupType[s] = kind
1539         } else {
1540                 su := state.ctxt.loader.MakeSymbolUpdater(s)
1541                 su.SetType(kind)
1542         }
1543 }
1544
1545 func (ctxt *Link) dodata(symGroupType []sym.SymKind) {
1546
1547         // Give zeros sized symbols space if necessary.
1548         fixZeroSizedSymbols(ctxt)
1549
1550         // Collect data symbols by type into data.
1551         state := dodataState{ctxt: ctxt, symGroupType: symGroupType}
1552         ldr := ctxt.loader
1553         for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
1554                 if !ldr.AttrReachable(s) || ldr.AttrSpecial(s) || ldr.AttrSubSymbol(s) ||
1555                         !ldr.TopLevelSym(s) {
1556                         continue
1557                 }
1558
1559                 st := state.symType(s)
1560
1561                 if st <= sym.STEXT || st >= sym.SXREF {
1562                         continue
1563                 }
1564                 state.data[st] = append(state.data[st], s)
1565
1566                 // Similarly with checking the onlist attr.
1567                 if ldr.AttrOnList(s) {
1568                         log.Fatalf("symbol %s listed multiple times", ldr.SymName(s))
1569                 }
1570                 ldr.SetAttrOnList(s, true)
1571         }
1572
1573         // Now that we have the data symbols, but before we start
1574         // to assign addresses, record all the necessary
1575         // dynamic relocations. These will grow the relocation
1576         // symbol, which is itself data.
1577         //
1578         // On darwin, we need the symbol table numbers for dynreloc.
1579         if ctxt.HeadType == objabi.Hdarwin {
1580                 machosymorder(ctxt)
1581         }
1582         state.dynreloc(ctxt)
1583
1584         // Move any RO data with relocations to a separate section.
1585         state.makeRelroForSharedLib(ctxt)
1586
1587         // Set alignment for the symbol with the largest known index,
1588         // so as to trigger allocation of the loader's internal
1589         // alignment array. This will avoid data races in the parallel
1590         // section below.
1591         lastSym := loader.Sym(ldr.NSym() - 1)
1592         ldr.SetSymAlign(lastSym, ldr.SymAlign(lastSym))
1593
1594         // Sort symbols.
1595         var wg sync.WaitGroup
1596         for symn := range state.data {
1597                 symn := sym.SymKind(symn)
1598                 wg.Add(1)
1599                 go func() {
1600                         state.data[symn], state.dataMaxAlign[symn] = state.dodataSect(ctxt, symn, state.data[symn])
1601                         wg.Done()
1602                 }()
1603         }
1604         wg.Wait()
1605
1606         if ctxt.IsELF {
1607                 // Make .rela and .rela.plt contiguous, the ELF ABI requires this
1608                 // and Solaris actually cares.
1609                 syms := state.data[sym.SELFROSECT]
1610                 reli, plti := -1, -1
1611                 for i, s := range syms {
1612                         switch ldr.SymName(s) {
1613                         case ".rel.plt", ".rela.plt":
1614                                 plti = i
1615                         case ".rel", ".rela":
1616                                 reli = i
1617                         }
1618                 }
1619                 if reli >= 0 && plti >= 0 && plti != reli+1 {
1620                         var first, second int
1621                         if plti > reli {
1622                                 first, second = reli, plti
1623                         } else {
1624                                 first, second = plti, reli
1625                         }
1626                         rel, plt := syms[reli], syms[plti]
1627                         copy(syms[first+2:], syms[first+1:second])
1628                         syms[first+0] = rel
1629                         syms[first+1] = plt
1630
1631                         // Make sure alignment doesn't introduce a gap.
1632                         // Setting the alignment explicitly prevents
1633                         // symalign from basing it on the size and
1634                         // getting it wrong.
1635                         ldr.SetSymAlign(rel, int32(ctxt.Arch.RegSize))
1636                         ldr.SetSymAlign(plt, int32(ctxt.Arch.RegSize))
1637                 }
1638                 state.data[sym.SELFROSECT] = syms
1639         }
1640
1641         if ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal {
1642                 // These symbols must have the same alignment as their section.
1643                 // Otherwise, ld might change the layout of Go sections.
1644                 ldr.SetSymAlign(ldr.Lookup("runtime.data", 0), state.dataMaxAlign[sym.SDATA])
1645                 ldr.SetSymAlign(ldr.Lookup("runtime.bss", 0), state.dataMaxAlign[sym.SBSS])
1646         }
1647
1648         // Create *sym.Section objects and assign symbols to sections for
1649         // data/rodata (and related) symbols.
1650         state.allocateDataSections(ctxt)
1651
1652         // Create *sym.Section objects and assign symbols to sections for
1653         // DWARF symbols.
1654         state.allocateDwarfSections(ctxt)
1655
1656         /* number the sections */
1657         n := int16(1)
1658
1659         for _, sect := range Segtext.Sections {
1660                 sect.Extnum = n
1661                 n++
1662         }
1663         for _, sect := range Segrodata.Sections {
1664                 sect.Extnum = n
1665                 n++
1666         }
1667         for _, sect := range Segrelrodata.Sections {
1668                 sect.Extnum = n
1669                 n++
1670         }
1671         for _, sect := range Segdata.Sections {
1672                 sect.Extnum = n
1673                 n++
1674         }
1675         for _, sect := range Segdwarf.Sections {
1676                 sect.Extnum = n
1677                 n++
1678         }
1679 }
1680
1681 // allocateDataSectionForSym creates a new sym.Section into which a
1682 // single symbol will be placed. Here "seg" is the segment into which
1683 // the section will go, "s" is the symbol to be placed into the new
1684 // section, and "rwx" contains permissions for the section.
1685 func (state *dodataState) allocateDataSectionForSym(seg *sym.Segment, s loader.Sym, rwx int) *sym.Section {
1686         ldr := state.ctxt.loader
1687         sname := ldr.SymName(s)
1688         if strings.HasPrefix(sname, "go:") {
1689                 sname = ".go." + sname[len("go:"):]
1690         }
1691         sect := addsection(ldr, state.ctxt.Arch, seg, sname, rwx)
1692         sect.Align = symalign(ldr, s)
1693         state.datsize = Rnd(state.datsize, int64(sect.Align))
1694         sect.Vaddr = uint64(state.datsize)
1695         return sect
1696 }
1697
1698 // allocateNamedDataSection creates a new sym.Section for a category
1699 // of data symbols. Here "seg" is the segment into which the section
1700 // will go, "sName" is the name to give to the section, "types" is a
1701 // range of symbol types to be put into the section, and "rwx"
1702 // contains permissions for the section.
1703 func (state *dodataState) allocateNamedDataSection(seg *sym.Segment, sName string, types []sym.SymKind, rwx int) *sym.Section {
1704         sect := addsection(state.ctxt.loader, state.ctxt.Arch, seg, sName, rwx)
1705         if len(types) == 0 {
1706                 sect.Align = 1
1707         } else if len(types) == 1 {
1708                 sect.Align = state.dataMaxAlign[types[0]]
1709         } else {
1710                 for _, symn := range types {
1711                         align := state.dataMaxAlign[symn]
1712                         if sect.Align < align {
1713                                 sect.Align = align
1714                         }
1715                 }
1716         }
1717         state.datsize = Rnd(state.datsize, int64(sect.Align))
1718         sect.Vaddr = uint64(state.datsize)
1719         return sect
1720 }
1721
1722 // assignDsymsToSection assigns a collection of data symbols to a
1723 // newly created section. "sect" is the section into which to place
1724 // the symbols, "syms" holds the list of symbols to assign,
1725 // "forceType" (if non-zero) contains a new sym type to apply to each
1726 // sym during the assignment, and "aligner" is a hook to call to
1727 // handle alignment during the assignment process.
1728 func (state *dodataState) assignDsymsToSection(sect *sym.Section, syms []loader.Sym, forceType sym.SymKind, aligner func(state *dodataState, datsize int64, s loader.Sym) int64) {
1729         ldr := state.ctxt.loader
1730         for _, s := range syms {
1731                 state.datsize = aligner(state, state.datsize, s)
1732                 ldr.SetSymSect(s, sect)
1733                 if forceType != sym.Sxxx {
1734                         state.setSymType(s, forceType)
1735                 }
1736                 ldr.SetSymValue(s, int64(uint64(state.datsize)-sect.Vaddr))
1737                 state.datsize += ldr.SymSize(s)
1738         }
1739         sect.Length = uint64(state.datsize) - sect.Vaddr
1740 }
1741
1742 func (state *dodataState) assignToSection(sect *sym.Section, symn sym.SymKind, forceType sym.SymKind) {
1743         state.assignDsymsToSection(sect, state.data[symn], forceType, aligndatsize)
1744         state.checkdatsize(symn)
1745 }
1746
1747 // allocateSingleSymSections walks through the bucketed data symbols
1748 // with type 'symn', creates a new section for each sym, and assigns
1749 // the sym to a newly created section. Section name is set from the
1750 // symbol name. "Seg" is the segment into which to place the new
1751 // section, "forceType" is the new sym.SymKind to assign to the symbol
1752 // within the section, and "rwx" holds section permissions.
1753 func (state *dodataState) allocateSingleSymSections(seg *sym.Segment, symn sym.SymKind, forceType sym.SymKind, rwx int) {
1754         ldr := state.ctxt.loader
1755         for _, s := range state.data[symn] {
1756                 sect := state.allocateDataSectionForSym(seg, s, rwx)
1757                 ldr.SetSymSect(s, sect)
1758                 state.setSymType(s, forceType)
1759                 ldr.SetSymValue(s, int64(uint64(state.datsize)-sect.Vaddr))
1760                 state.datsize += ldr.SymSize(s)
1761                 sect.Length = uint64(state.datsize) - sect.Vaddr
1762         }
1763         state.checkdatsize(symn)
1764 }
1765
1766 // allocateNamedSectionAndAssignSyms creates a new section with the
1767 // specified name, then walks through the bucketed data symbols with
1768 // type 'symn' and assigns each of them to this new section. "Seg" is
1769 // the segment into which to place the new section, "secName" is the
1770 // name to give to the new section, "forceType" (if non-zero) contains
1771 // a new sym type to apply to each sym during the assignment, and
1772 // "rwx" holds section permissions.
1773 func (state *dodataState) allocateNamedSectionAndAssignSyms(seg *sym.Segment, secName string, symn sym.SymKind, forceType sym.SymKind, rwx int) *sym.Section {
1774
1775         sect := state.allocateNamedDataSection(seg, secName, []sym.SymKind{symn}, rwx)
1776         state.assignDsymsToSection(sect, state.data[symn], forceType, aligndatsize)
1777         return sect
1778 }
1779
1780 // allocateDataSections allocates sym.Section objects for data/rodata
1781 // (and related) symbols, and then assigns symbols to those sections.
1782 func (state *dodataState) allocateDataSections(ctxt *Link) {
1783         // Allocate sections.
1784         // Data is processed before segtext, because we need
1785         // to see all symbols in the .data and .bss sections in order
1786         // to generate garbage collection information.
1787
1788         // Writable data sections that do not need any specialized handling.
1789         writable := []sym.SymKind{
1790                 sym.SBUILDINFO,
1791                 sym.SELFSECT,
1792                 sym.SMACHO,
1793                 sym.SMACHOGOT,
1794                 sym.SWINDOWS,
1795         }
1796         for _, symn := range writable {
1797                 state.allocateSingleSymSections(&Segdata, symn, sym.SDATA, 06)
1798         }
1799         ldr := ctxt.loader
1800
1801         // .got
1802         if len(state.data[sym.SELFGOT]) > 0 {
1803                 state.allocateNamedSectionAndAssignSyms(&Segdata, ".got", sym.SELFGOT, sym.SDATA, 06)
1804         }
1805
1806         /* pointer-free data */
1807         sect := state.allocateNamedSectionAndAssignSyms(&Segdata, ".noptrdata", sym.SNOPTRDATA, sym.SDATA, 06)
1808         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.noptrdata", 0), sect)
1809         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.enoptrdata", 0), sect)
1810
1811         hasinitarr := ctxt.linkShared
1812
1813         /* shared library initializer */
1814         switch ctxt.BuildMode {
1815         case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin:
1816                 hasinitarr = true
1817         }
1818
1819         if ctxt.HeadType == objabi.Haix {
1820                 if len(state.data[sym.SINITARR]) > 0 {
1821                         Errorf(nil, "XCOFF format doesn't allow .init_array section")
1822                 }
1823         }
1824
1825         if hasinitarr && len(state.data[sym.SINITARR]) > 0 {
1826                 state.allocateNamedSectionAndAssignSyms(&Segdata, ".init_array", sym.SINITARR, sym.Sxxx, 06)
1827         }
1828
1829         /* data */
1830         sect = state.allocateNamedSectionAndAssignSyms(&Segdata, ".data", sym.SDATA, sym.SDATA, 06)
1831         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.data", 0), sect)
1832         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.edata", 0), sect)
1833         dataGcEnd := state.datsize - int64(sect.Vaddr)
1834
1835         // On AIX, TOC entries must be the last of .data
1836         // These aren't part of gc as they won't change during the runtime.
1837         state.assignToSection(sect, sym.SXCOFFTOC, sym.SDATA)
1838         state.checkdatsize(sym.SDATA)
1839         sect.Length = uint64(state.datsize) - sect.Vaddr
1840
1841         /* bss */
1842         sect = state.allocateNamedSectionAndAssignSyms(&Segdata, ".bss", sym.SBSS, sym.Sxxx, 06)
1843         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.bss", 0), sect)
1844         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.ebss", 0), sect)
1845         bssGcEnd := state.datsize - int64(sect.Vaddr)
1846
1847         // Emit gcdata for bss symbols now that symbol values have been assigned.
1848         gcsToEmit := []struct {
1849                 symName string
1850                 symKind sym.SymKind
1851                 gcEnd   int64
1852         }{
1853                 {"runtime.gcdata", sym.SDATA, dataGcEnd},
1854                 {"runtime.gcbss", sym.SBSS, bssGcEnd},
1855         }
1856         for _, g := range gcsToEmit {
1857                 var gc GCProg
1858                 gc.Init(ctxt, g.symName)
1859                 for _, s := range state.data[g.symKind] {
1860                         gc.AddSym(s)
1861                 }
1862                 gc.End(g.gcEnd)
1863         }
1864
1865         /* pointer-free bss */
1866         sect = state.allocateNamedSectionAndAssignSyms(&Segdata, ".noptrbss", sym.SNOPTRBSS, sym.Sxxx, 06)
1867         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.noptrbss", 0), sect)
1868         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.enoptrbss", 0), sect)
1869         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.end", 0), sect)
1870
1871         // Code coverage counters are assigned to the .noptrbss section.
1872         // We assign them in a separate pass so that they stay aggregated
1873         // together in a single blob (coverage runtime depends on this).
1874         covCounterDataStartOff = sect.Length
1875         state.assignToSection(sect, sym.SCOVERAGE_COUNTER, sym.SNOPTRBSS)
1876         covCounterDataLen = sect.Length - covCounterDataStartOff
1877         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.covctrs", 0), sect)
1878         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.ecovctrs", 0), sect)
1879
1880         // Coverage instrumentation counters for libfuzzer.
1881         if len(state.data[sym.SLIBFUZZER_8BIT_COUNTER]) > 0 {
1882                 sect := state.allocateNamedSectionAndAssignSyms(&Segdata, ".go.fuzzcntrs", sym.SLIBFUZZER_8BIT_COUNTER, sym.Sxxx, 06)
1883                 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.__start___sancov_cntrs", 0), sect)
1884                 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.__stop___sancov_cntrs", 0), sect)
1885                 ldr.SetSymSect(ldr.LookupOrCreateSym("internal/fuzz._counters", 0), sect)
1886                 ldr.SetSymSect(ldr.LookupOrCreateSym("internal/fuzz._ecounters", 0), sect)
1887         }
1888
1889         if len(state.data[sym.STLSBSS]) > 0 {
1890                 var sect *sym.Section
1891                 // FIXME: not clear why it is sometimes necessary to suppress .tbss section creation.
1892                 if (ctxt.IsELF || ctxt.HeadType == objabi.Haix) && (ctxt.LinkMode == LinkExternal || !*FlagD) {
1893                         sect = addsection(ldr, ctxt.Arch, &Segdata, ".tbss", 06)
1894                         sect.Align = int32(ctxt.Arch.PtrSize)
1895                         // FIXME: why does this need to be set to zero?
1896                         sect.Vaddr = 0
1897                 }
1898                 state.datsize = 0
1899
1900                 for _, s := range state.data[sym.STLSBSS] {
1901                         state.datsize = aligndatsize(state, state.datsize, s)
1902                         if sect != nil {
1903                                 ldr.SetSymSect(s, sect)
1904                         }
1905                         ldr.SetSymValue(s, state.datsize)
1906                         state.datsize += ldr.SymSize(s)
1907                 }
1908                 state.checkdatsize(sym.STLSBSS)
1909
1910                 if sect != nil {
1911                         sect.Length = uint64(state.datsize)
1912                 }
1913         }
1914
1915         /*
1916          * We finished data, begin read-only data.
1917          * Not all systems support a separate read-only non-executable data section.
1918          * ELF and Windows PE systems do.
1919          * OS X and Plan 9 do not.
1920          * And if we're using external linking mode, the point is moot,
1921          * since it's not our decision; that code expects the sections in
1922          * segtext.
1923          */
1924         var segro *sym.Segment
1925         if ctxt.IsELF && ctxt.LinkMode == LinkInternal {
1926                 segro = &Segrodata
1927         } else if ctxt.HeadType == objabi.Hwindows {
1928                 segro = &Segrodata
1929         } else {
1930                 segro = &Segtext
1931         }
1932
1933         state.datsize = 0
1934
1935         /* read-only executable ELF, Mach-O sections */
1936         if len(state.data[sym.STEXT]) != 0 {
1937                 culprit := ldr.SymName(state.data[sym.STEXT][0])
1938                 Errorf(nil, "dodata found an sym.STEXT symbol: %s", culprit)
1939         }
1940         state.allocateSingleSymSections(&Segtext, sym.SELFRXSECT, sym.SRODATA, 05)
1941         state.allocateSingleSymSections(&Segtext, sym.SMACHOPLT, sym.SRODATA, 05)
1942
1943         /* read-only data */
1944         sect = state.allocateNamedDataSection(segro, ".rodata", sym.ReadOnly, 04)
1945         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.rodata", 0), sect)
1946         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.erodata", 0), sect)
1947         if !ctxt.UseRelro() {
1948                 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.types", 0), sect)
1949                 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.etypes", 0), sect)
1950         }
1951         for _, symn := range sym.ReadOnly {
1952                 symnStartValue := state.datsize
1953                 if len(state.data[symn]) != 0 {
1954                         symnStartValue = aligndatsize(state, symnStartValue, state.data[symn][0])
1955                 }
1956                 state.assignToSection(sect, symn, sym.SRODATA)
1957                 setCarrierSize(symn, state.datsize-symnStartValue)
1958                 if ctxt.HeadType == objabi.Haix {
1959                         // Read-only symbols might be wrapped inside their outer
1960                         // symbol.
1961                         // XCOFF symbol table needs to know the size of
1962                         // these outer symbols.
1963                         xcoffUpdateOuterSize(ctxt, state.datsize-symnStartValue, symn)
1964                 }
1965         }
1966
1967         /* read-only ELF, Mach-O sections */
1968         state.allocateSingleSymSections(segro, sym.SELFROSECT, sym.SRODATA, 04)
1969
1970         // There is some data that are conceptually read-only but are written to by
1971         // relocations. On GNU systems, we can arrange for the dynamic linker to
1972         // mprotect sections after relocations are applied by giving them write
1973         // permissions in the object file and calling them ".data.rel.ro.FOO". We
1974         // divide the .rodata section between actual .rodata and .data.rel.ro.rodata,
1975         // but for the other sections that this applies to, we just write a read-only
1976         // .FOO section or a read-write .data.rel.ro.FOO section depending on the
1977         // situation.
1978         // TODO(mwhudson): It would make sense to do this more widely, but it makes
1979         // the system linker segfault on darwin.
1980         const relroPerm = 06
1981         const fallbackPerm = 04
1982         relroSecPerm := fallbackPerm
1983         genrelrosecname := func(suffix string) string {
1984                 if suffix == "" {
1985                         return ".rodata"
1986                 }
1987                 return suffix
1988         }
1989         seg := segro
1990
1991         if ctxt.UseRelro() {
1992                 segrelro := &Segrelrodata
1993                 if ctxt.LinkMode == LinkExternal && !ctxt.IsAIX() && !ctxt.IsDarwin() {
1994                         // Using a separate segment with an external
1995                         // linker results in some programs moving
1996                         // their data sections unexpectedly, which
1997                         // corrupts the moduledata. So we use the
1998                         // rodata segment and let the external linker
1999                         // sort out a rel.ro segment.
2000                         segrelro = segro
2001                 } else {
2002                         // Reset datsize for new segment.
2003                         state.datsize = 0
2004                 }
2005
2006                 if !ctxt.IsDarwin() { // We don't need the special names on darwin.
2007                         genrelrosecname = func(suffix string) string {
2008                                 return ".data.rel.ro" + suffix
2009                         }
2010                 }
2011
2012                 relroReadOnly := []sym.SymKind{}
2013                 for _, symnro := range sym.ReadOnly {
2014                         symn := sym.RelROMap[symnro]
2015                         relroReadOnly = append(relroReadOnly, symn)
2016                 }
2017                 seg = segrelro
2018                 relroSecPerm = relroPerm
2019
2020                 /* data only written by relocations */
2021                 sect = state.allocateNamedDataSection(segrelro, genrelrosecname(""), relroReadOnly, relroSecPerm)
2022
2023                 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.types", 0), sect)
2024                 ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.etypes", 0), sect)
2025
2026                 for i, symnro := range sym.ReadOnly {
2027                         if i == 0 && symnro == sym.STYPE && ctxt.HeadType != objabi.Haix {
2028                                 // Skip forward so that no type
2029                                 // reference uses a zero offset.
2030                                 // This is unlikely but possible in small
2031                                 // programs with no other read-only data.
2032                                 state.datsize++
2033                         }
2034
2035                         symn := sym.RelROMap[symnro]
2036                         symnStartValue := state.datsize
2037                         if len(state.data[symn]) != 0 {
2038                                 symnStartValue = aligndatsize(state, symnStartValue, state.data[symn][0])
2039                         }
2040
2041                         for _, s := range state.data[symn] {
2042                                 outer := ldr.OuterSym(s)
2043                                 if s != 0 && ldr.SymSect(outer) != nil && ldr.SymSect(outer) != sect {
2044                                         ctxt.Errorf(s, "s.Outer (%s) in different section from s, %s != %s", ldr.SymName(outer), ldr.SymSect(outer).Name, sect.Name)
2045                                 }
2046                         }
2047                         state.assignToSection(sect, symn, sym.SRODATA)
2048                         setCarrierSize(symn, state.datsize-symnStartValue)
2049                         if ctxt.HeadType == objabi.Haix {
2050                                 // Read-only symbols might be wrapped inside their outer
2051                                 // symbol.
2052                                 // XCOFF symbol table needs to know the size of
2053                                 // these outer symbols.
2054                                 xcoffUpdateOuterSize(ctxt, state.datsize-symnStartValue, symn)
2055                         }
2056                 }
2057
2058                 sect.Length = uint64(state.datsize) - sect.Vaddr
2059         }
2060
2061         /* typelink */
2062         sect = state.allocateNamedDataSection(seg, genrelrosecname(".typelink"), []sym.SymKind{sym.STYPELINK}, relroSecPerm)
2063
2064         typelink := ldr.CreateSymForUpdate("runtime.typelink", 0)
2065         ldr.SetSymSect(typelink.Sym(), sect)
2066         typelink.SetType(sym.SRODATA)
2067         state.datsize += typelink.Size()
2068         state.checkdatsize(sym.STYPELINK)
2069         sect.Length = uint64(state.datsize) - sect.Vaddr
2070
2071         /* itablink */
2072         sect = state.allocateNamedDataSection(seg, genrelrosecname(".itablink"), []sym.SymKind{sym.SITABLINK}, relroSecPerm)
2073
2074         itablink := ldr.CreateSymForUpdate("runtime.itablink", 0)
2075         ldr.SetSymSect(itablink.Sym(), sect)
2076         itablink.SetType(sym.SRODATA)
2077         state.datsize += itablink.Size()
2078         state.checkdatsize(sym.SITABLINK)
2079         sect.Length = uint64(state.datsize) - sect.Vaddr
2080
2081         /* gosymtab */
2082         sect = state.allocateNamedSectionAndAssignSyms(seg, genrelrosecname(".gosymtab"), sym.SSYMTAB, sym.SRODATA, relroSecPerm)
2083         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.symtab", 0), sect)
2084         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.esymtab", 0), sect)
2085
2086         /* gopclntab */
2087         sect = state.allocateNamedSectionAndAssignSyms(seg, genrelrosecname(".gopclntab"), sym.SPCLNTAB, sym.SRODATA, relroSecPerm)
2088         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pclntab", 0), sect)
2089         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pcheader", 0), sect)
2090         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.funcnametab", 0), sect)
2091         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.cutab", 0), sect)
2092         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.filetab", 0), sect)
2093         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pctab", 0), sect)
2094         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.functab", 0), sect)
2095         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.epclntab", 0), sect)
2096         setCarrierSize(sym.SPCLNTAB, int64(sect.Length))
2097         if ctxt.HeadType == objabi.Haix {
2098                 xcoffUpdateOuterSize(ctxt, int64(sect.Length), sym.SPCLNTAB)
2099         }
2100
2101         // 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
2102         if state.datsize != int64(uint32(state.datsize)) {
2103                 Errorf(nil, "read-only data segment too large: %d", state.datsize)
2104         }
2105
2106         siz := 0
2107         for symn := sym.SELFRXSECT; symn < sym.SXREF; symn++ {
2108                 siz += len(state.data[symn])
2109         }
2110         ctxt.datap = make([]loader.Sym, 0, siz)
2111         for symn := sym.SELFRXSECT; symn < sym.SXREF; symn++ {
2112                 ctxt.datap = append(ctxt.datap, state.data[symn]...)
2113         }
2114 }
2115
2116 // allocateDwarfSections allocates sym.Section objects for DWARF
2117 // symbols, and assigns symbols to sections.
2118 func (state *dodataState) allocateDwarfSections(ctxt *Link) {
2119
2120         alignOne := func(state *dodataState, datsize int64, s loader.Sym) int64 { return datsize }
2121
2122         ldr := ctxt.loader
2123         for i := 0; i < len(dwarfp); i++ {
2124                 // First the section symbol.
2125                 s := dwarfp[i].secSym()
2126                 sect := state.allocateNamedDataSection(&Segdwarf, ldr.SymName(s), []sym.SymKind{}, 04)
2127                 ldr.SetSymSect(s, sect)
2128                 sect.Sym = sym.LoaderSym(s)
2129                 curType := ldr.SymType(s)
2130                 state.setSymType(s, sym.SRODATA)
2131                 ldr.SetSymValue(s, int64(uint64(state.datsize)-sect.Vaddr))
2132                 state.datsize += ldr.SymSize(s)
2133
2134                 // Then any sub-symbols for the section symbol.
2135                 subSyms := dwarfp[i].subSyms()
2136                 state.assignDsymsToSection(sect, subSyms, sym.SRODATA, alignOne)
2137
2138                 for j := 0; j < len(subSyms); j++ {
2139                         s := subSyms[j]
2140                         if ctxt.HeadType == objabi.Haix && curType == sym.SDWARFLOC {
2141                                 // Update the size of .debug_loc for this symbol's
2142                                 // package.
2143                                 addDwsectCUSize(".debug_loc", ldr.SymPkg(s), uint64(ldr.SymSize(s)))
2144                         }
2145                 }
2146                 sect.Length = uint64(state.datsize) - sect.Vaddr
2147                 state.checkdatsize(curType)
2148         }
2149 }
2150
2151 type symNameSize struct {
2152         name string
2153         sz   int64
2154         val  int64
2155         sym  loader.Sym
2156 }
2157
2158 func (state *dodataState) dodataSect(ctxt *Link, symn sym.SymKind, syms []loader.Sym) (result []loader.Sym, maxAlign int32) {
2159         var head, tail loader.Sym
2160         ldr := ctxt.loader
2161         sl := make([]symNameSize, len(syms))
2162
2163         // For ppc64, we want to interleave the .got and .toc sections
2164         // from input files. Both are type sym.SELFGOT, so in that case
2165         // we skip size comparison and do the name comparison instead
2166         // (conveniently, .got sorts before .toc).
2167         checkSize := symn != sym.SELFGOT
2168
2169         for k, s := range syms {
2170                 ss := ldr.SymSize(s)
2171                 sl[k] = symNameSize{sz: ss, sym: s}
2172                 if !checkSize {
2173                         sl[k].name = ldr.SymName(s)
2174                 }
2175                 ds := int64(len(ldr.Data(s)))
2176                 switch {
2177                 case ss < ds:
2178                         ctxt.Errorf(s, "initialize bounds (%d < %d)", ss, ds)
2179                 case ss < 0:
2180                         ctxt.Errorf(s, "negative size (%d bytes)", ss)
2181                 case ss > cutoff:
2182                         ctxt.Errorf(s, "symbol too large (%d bytes)", ss)
2183                 }
2184
2185                 // If the usually-special section-marker symbols are being laid
2186                 // out as regular symbols, put them either at the beginning or
2187                 // end of their section.
2188                 if (ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
2189                         switch ldr.SymName(s) {
2190                         case "runtime.text", "runtime.bss", "runtime.data", "runtime.types", "runtime.rodata":
2191                                 head = s
2192                                 continue
2193                         case "runtime.etext", "runtime.ebss", "runtime.edata", "runtime.etypes", "runtime.erodata":
2194                                 tail = s
2195                                 continue
2196                         }
2197                 }
2198         }
2199
2200         // Perform the sort.
2201         if symn != sym.SPCLNTAB {
2202                 sort.Slice(sl, func(i, j int) bool {
2203                         si, sj := sl[i].sym, sl[j].sym
2204                         switch {
2205                         case si == head, sj == tail:
2206                                 return true
2207                         case sj == head, si == tail:
2208                                 return false
2209                         }
2210                         if checkSize {
2211                                 isz := sl[i].sz
2212                                 jsz := sl[j].sz
2213                                 if isz != jsz {
2214                                         return isz < jsz
2215                                 }
2216                         } else {
2217                                 iname := sl[i].name
2218                                 jname := sl[j].name
2219                                 if iname != jname {
2220                                         return iname < jname
2221                                 }
2222                         }
2223                         return si < sj
2224                 })
2225         } else {
2226                 // PCLNTAB was built internally, and already has the proper order.
2227         }
2228
2229         // Set alignment, construct result
2230         syms = syms[:0]
2231         for k := range sl {
2232                 s := sl[k].sym
2233                 if s != head && s != tail {
2234                         align := symalign(ldr, s)
2235                         if maxAlign < align {
2236                                 maxAlign = align
2237                         }
2238                 }
2239                 syms = append(syms, s)
2240         }
2241
2242         return syms, maxAlign
2243 }
2244
2245 // Add buildid to beginning of text segment, on non-ELF systems.
2246 // Non-ELF binary formats are not always flexible enough to
2247 // give us a place to put the Go build ID. On those systems, we put it
2248 // at the very beginning of the text segment.
2249 // This “header” is read by cmd/go.
2250 func (ctxt *Link) textbuildid() {
2251         if ctxt.IsELF || *flagBuildid == "" {
2252                 return
2253         }
2254
2255         ldr := ctxt.loader
2256         s := ldr.CreateSymForUpdate("go:buildid", 0)
2257         // The \xff is invalid UTF-8, meant to make it less likely
2258         // to find one of these accidentally.
2259         data := "\xff Go build ID: " + strconv.Quote(*flagBuildid) + "\n \xff"
2260         s.SetType(sym.STEXT)
2261         s.SetData([]byte(data))
2262         s.SetSize(int64(len(data)))
2263
2264         ctxt.Textp = append(ctxt.Textp, 0)
2265         copy(ctxt.Textp[1:], ctxt.Textp)
2266         ctxt.Textp[0] = s.Sym()
2267 }
2268
2269 func (ctxt *Link) buildinfo() {
2270         // Write the buildinfo symbol, which go version looks for.
2271         // The code reading this data is in package debug/buildinfo.
2272         ldr := ctxt.loader
2273         s := ldr.CreateSymForUpdate("go:buildinfo", 0)
2274         s.SetType(sym.SBUILDINFO)
2275         s.SetAlign(16)
2276         // The \xff is invalid UTF-8, meant to make it less likely
2277         // to find one of these accidentally.
2278         const prefix = "\xff Go buildinf:" // 14 bytes, plus 2 data bytes filled in below
2279         data := make([]byte, 32)
2280         copy(data, prefix)
2281         data[len(prefix)] = byte(ctxt.Arch.PtrSize)
2282         data[len(prefix)+1] = 0
2283         if ctxt.Arch.ByteOrder == binary.BigEndian {
2284                 data[len(prefix)+1] = 1
2285         }
2286         data[len(prefix)+1] |= 2 // signals new pointer-free format
2287         data = appendString(data, strdata["runtime.buildVersion"])
2288         data = appendString(data, strdata["runtime.modinfo"])
2289         // MacOS linker gets very upset if the size os not a multiple of alignment.
2290         for len(data)%16 != 0 {
2291                 data = append(data, 0)
2292         }
2293         s.SetData(data)
2294         s.SetSize(int64(len(data)))
2295
2296         // Add reference to go:buildinfo from the rodata section,
2297         // so that external linking with -Wl,--gc-sections does not
2298         // delete the build info.
2299         sr := ldr.CreateSymForUpdate("go:buildinfo.ref", 0)
2300         sr.SetType(sym.SRODATA)
2301         sr.SetAlign(int32(ctxt.Arch.PtrSize))
2302         sr.AddAddr(ctxt.Arch, s.Sym())
2303 }
2304
2305 // appendString appends s to data, prefixed by its varint-encoded length.
2306 func appendString(data []byte, s string) []byte {
2307         var v [binary.MaxVarintLen64]byte
2308         n := binary.PutUvarint(v[:], uint64(len(s)))
2309         data = append(data, v[:n]...)
2310         data = append(data, s...)
2311         return data
2312 }
2313
2314 // assign addresses to text
2315 func (ctxt *Link) textaddress() {
2316         addsection(ctxt.loader, ctxt.Arch, &Segtext, ".text", 05)
2317
2318         // Assign PCs in text segment.
2319         // Could parallelize, by assigning to text
2320         // and then letting threads copy down, but probably not worth it.
2321         sect := Segtext.Sections[0]
2322
2323         sect.Align = int32(Funcalign)
2324
2325         ldr := ctxt.loader
2326
2327         text := ctxt.xdefine("runtime.text", sym.STEXT, 0)
2328         etext := ctxt.xdefine("runtime.etext", sym.STEXT, 0)
2329         ldr.SetSymSect(text, sect)
2330         if ctxt.IsAIX() && ctxt.IsExternal() {
2331                 // Setting runtime.text has a real symbol prevents ld to
2332                 // change its base address resulting in wrong offsets for
2333                 // reflect methods.
2334                 u := ldr.MakeSymbolUpdater(text)
2335                 u.SetAlign(sect.Align)
2336                 u.SetSize(8)
2337         }
2338
2339         if (ctxt.DynlinkingGo() && ctxt.IsDarwin()) || (ctxt.IsAIX() && ctxt.IsExternal()) {
2340                 ldr.SetSymSect(etext, sect)
2341                 ctxt.Textp = append(ctxt.Textp, etext, 0)
2342                 copy(ctxt.Textp[1:], ctxt.Textp)
2343                 ctxt.Textp[0] = text
2344         }
2345
2346         start := uint64(Rnd(*FlagTextAddr, int64(Funcalign)))
2347         va := start
2348         n := 1
2349         sect.Vaddr = va
2350
2351         limit := thearch.TrampLimit
2352         if limit == 0 {
2353                 limit = 1 << 63 // unlimited
2354         }
2355         if *FlagDebugTextSize != 0 {
2356                 limit = uint64(*FlagDebugTextSize)
2357         }
2358         if *FlagDebugTramp > 1 {
2359                 limit = 1 // debug mode, force generating trampolines for everything
2360         }
2361
2362         if ctxt.IsAIX() && ctxt.IsExternal() {
2363                 // On AIX, normally we won't generate direct calls to external symbols,
2364                 // except in one test, cmd/go/testdata/script/link_syso_issue33139.txt.
2365                 // That test doesn't make much sense, and I'm not sure it ever works.
2366                 // Just generate trampoline for now (which will turn a direct call to
2367                 // an indirect call, which at least builds).
2368                 limit = 1
2369         }
2370
2371         // First pass: assign addresses assuming the program is small and
2372         // don't generate trampolines.
2373         big := false
2374         for _, s := range ctxt.Textp {
2375                 sect, n, va = assignAddress(ctxt, sect, n, s, va, false, big)
2376                 if va-start >= limit {
2377                         big = true
2378                         break
2379                 }
2380         }
2381
2382         // Second pass: only if it is too big, insert trampolines for too-far
2383         // jumps and targets with unknown addresses.
2384         if big {
2385                 // reset addresses
2386                 for _, s := range ctxt.Textp {
2387                         if ldr.OuterSym(s) != 0 || s == text {
2388                                 continue
2389                         }
2390                         oldv := ldr.SymValue(s)
2391                         for sub := s; sub != 0; sub = ldr.SubSym(sub) {
2392                                 ldr.SetSymValue(sub, ldr.SymValue(sub)-oldv)
2393                         }
2394                 }
2395                 va = start
2396
2397                 ntramps := 0
2398                 for _, s := range ctxt.Textp {
2399                         sect, n, va = assignAddress(ctxt, sect, n, s, va, false, big)
2400
2401                         trampoline(ctxt, s) // resolve jumps, may add trampolines if jump too far
2402
2403                         // lay down trampolines after each function
2404                         for ; ntramps < len(ctxt.tramps); ntramps++ {
2405                                 tramp := ctxt.tramps[ntramps]
2406                                 if ctxt.IsAIX() && strings.HasPrefix(ldr.SymName(tramp), "runtime.text.") {
2407                                         // Already set in assignAddress
2408                                         continue
2409                                 }
2410                                 sect, n, va = assignAddress(ctxt, sect, n, tramp, va, true, big)
2411                         }
2412                 }
2413
2414                 // merge tramps into Textp, keeping Textp in address order
2415                 if ntramps != 0 {
2416                         newtextp := make([]loader.Sym, 0, len(ctxt.Textp)+ntramps)
2417                         i := 0
2418                         for _, s := range ctxt.Textp {
2419                                 for ; i < ntramps && ldr.SymValue(ctxt.tramps[i]) < ldr.SymValue(s); i++ {
2420                                         newtextp = append(newtextp, ctxt.tramps[i])
2421                                 }
2422                                 newtextp = append(newtextp, s)
2423                         }
2424                         newtextp = append(newtextp, ctxt.tramps[i:ntramps]...)
2425
2426                         ctxt.Textp = newtextp
2427                 }
2428         }
2429
2430         // Add MinLC size after etext, so it won't collide with the next symbol
2431         // (which may confuse some symbolizer).
2432         sect.Length = va - sect.Vaddr + uint64(ctxt.Arch.MinLC)
2433         ldr.SetSymSect(etext, sect)
2434         if ldr.SymValue(etext) == 0 {
2435                 // Set the address of the start/end symbols, if not already
2436                 // (i.e. not darwin+dynlink or AIX+external, see above).
2437                 ldr.SetSymValue(etext, int64(va))
2438                 ldr.SetSymValue(text, int64(Segtext.Sections[0].Vaddr))
2439         }
2440 }
2441
2442 // assigns address for a text symbol, returns (possibly new) section, its number, and the address.
2443 func assignAddress(ctxt *Link, sect *sym.Section, n int, s loader.Sym, va uint64, isTramp, big bool) (*sym.Section, int, uint64) {
2444         ldr := ctxt.loader
2445         if thearch.AssignAddress != nil {
2446                 return thearch.AssignAddress(ldr, sect, n, s, va, isTramp)
2447         }
2448
2449         ldr.SetSymSect(s, sect)
2450         if ldr.AttrSubSymbol(s) {
2451                 return sect, n, va
2452         }
2453
2454         align := ldr.SymAlign(s)
2455         if align == 0 {
2456                 align = int32(Funcalign)
2457         }
2458         va = uint64(Rnd(int64(va), int64(align)))
2459         if sect.Align < align {
2460                 sect.Align = align
2461         }
2462
2463         funcsize := uint64(MINFUNC) // spacing required for findfunctab
2464         if ldr.SymSize(s) > MINFUNC {
2465                 funcsize = uint64(ldr.SymSize(s))
2466         }
2467
2468         // If we need to split text sections, and this function doesn't fit in the current
2469         // section, then create a new one.
2470         //
2471         // Only break at outermost syms.
2472         if big && splitTextSections(ctxt) && ldr.OuterSym(s) == 0 {
2473                 // For debugging purposes, allow text size limit to be cranked down,
2474                 // so as to stress test the code that handles multiple text sections.
2475                 var textSizelimit uint64 = thearch.TrampLimit
2476                 if *FlagDebugTextSize != 0 {
2477                         textSizelimit = uint64(*FlagDebugTextSize)
2478                 }
2479
2480                 // Sanity check: make sure the limit is larger than any
2481                 // individual text symbol.
2482                 if funcsize > textSizelimit {
2483                         panic(fmt.Sprintf("error: text size limit %d less than text symbol %s size of %d", textSizelimit, ldr.SymName(s), funcsize))
2484                 }
2485
2486                 if va-sect.Vaddr+funcsize+maxSizeTrampolines(ctxt, ldr, s, isTramp) > textSizelimit {
2487                         sectAlign := int32(thearch.Funcalign)
2488                         if ctxt.IsPPC64() {
2489                                 // Align the next text section to the worst case function alignment likely
2490                                 // to be encountered when processing function symbols. The start address
2491                                 // is rounded against the final alignment of the text section later on in
2492                                 // (*Link).address. This may happen due to usage of PCALIGN directives
2493                                 // larger than Funcalign, or usage of ISA 3.1 prefixed instructions
2494                                 // (see ISA 3.1 Book I 1.9).
2495                                 const ppc64maxFuncalign = 64
2496                                 sectAlign = ppc64maxFuncalign
2497                                 va = uint64(Rnd(int64(va), ppc64maxFuncalign))
2498                         }
2499
2500                         // Set the length for the previous text section
2501                         sect.Length = va - sect.Vaddr
2502
2503                         // Create new section, set the starting Vaddr
2504                         sect = addsection(ctxt.loader, ctxt.Arch, &Segtext, ".text", 05)
2505
2506                         sect.Vaddr = va
2507                         sect.Align = sectAlign
2508                         ldr.SetSymSect(s, sect)
2509
2510                         // Create a symbol for the start of the secondary text sections
2511                         ntext := ldr.CreateSymForUpdate(fmt.Sprintf("runtime.text.%d", n), 0)
2512                         ntext.SetSect(sect)
2513                         if ctxt.IsAIX() {
2514                                 // runtime.text.X must be a real symbol on AIX.
2515                                 // Assign its address directly in order to be the
2516                                 // first symbol of this new section.
2517                                 ntext.SetType(sym.STEXT)
2518                                 ntext.SetSize(int64(MINFUNC))
2519                                 ntext.SetOnList(true)
2520                                 ntext.SetAlign(sectAlign)
2521                                 ctxt.tramps = append(ctxt.tramps, ntext.Sym())
2522
2523                                 ntext.SetValue(int64(va))
2524                                 va += uint64(ntext.Size())
2525
2526                                 if align := ldr.SymAlign(s); align != 0 {
2527                                         va = uint64(Rnd(int64(va), int64(align)))
2528                                 } else {
2529                                         va = uint64(Rnd(int64(va), int64(Funcalign)))
2530                                 }
2531                         }
2532                         n++
2533                 }
2534         }
2535
2536         ldr.SetSymValue(s, 0)
2537         for sub := s; sub != 0; sub = ldr.SubSym(sub) {
2538                 ldr.SetSymValue(sub, ldr.SymValue(sub)+int64(va))
2539                 if ctxt.Debugvlog > 2 {
2540                         fmt.Println("assign text address:", ldr.SymName(sub), ldr.SymValue(sub))
2541                 }
2542         }
2543
2544         va += funcsize
2545
2546         return sect, n, va
2547 }
2548
2549 // Return whether we may need to split text sections.
2550 //
2551 // On PPC64x whem external linking a text section should not be larger than 2^25 bytes
2552 // due to the size of call target offset field in the bl instruction.  Splitting into
2553 // smaller text sections smaller than this limit allows the system linker to modify the long
2554 // calls appropriately. The limit allows for the space needed for tables inserted by the
2555 // linker.
2556 //
2557 // The same applies to Darwin/ARM64, with 2^27 byte threshold.
2558 func splitTextSections(ctxt *Link) bool {
2559         return (ctxt.IsPPC64() || (ctxt.IsARM64() && ctxt.IsDarwin())) && ctxt.IsExternal()
2560 }
2561
2562 // On Wasm, we reserve 4096 bytes for zero page, then 8192 bytes for wasm_exec.js
2563 // to store command line args and environment variables.
2564 // Data sections starts from at least address 12288.
2565 // Keep in sync with wasm_exec.js.
2566 const wasmMinDataAddr = 4096 + 8192
2567
2568 // address assigns virtual addresses to all segments and sections and
2569 // returns all segments in file order.
2570 func (ctxt *Link) address() []*sym.Segment {
2571         var order []*sym.Segment // Layout order
2572
2573         va := uint64(*FlagTextAddr)
2574         order = append(order, &Segtext)
2575         Segtext.Rwx = 05
2576         Segtext.Vaddr = va
2577         for i, s := range Segtext.Sections {
2578                 va = uint64(Rnd(int64(va), int64(s.Align)))
2579                 s.Vaddr = va
2580                 va += s.Length
2581
2582                 if ctxt.IsWasm() && i == 0 && va < wasmMinDataAddr {
2583                         va = wasmMinDataAddr
2584                 }
2585         }
2586
2587         Segtext.Length = va - uint64(*FlagTextAddr)
2588
2589         if len(Segrodata.Sections) > 0 {
2590                 // align to page boundary so as not to mix
2591                 // rodata and executable text.
2592                 //
2593                 // Note: gold or GNU ld will reduce the size of the executable
2594                 // file by arranging for the relro segment to end at a page
2595                 // boundary, and overlap the end of the text segment with the
2596                 // start of the relro segment in the file.  The PT_LOAD segments
2597                 // will be such that the last page of the text segment will be
2598                 // mapped twice, once r-x and once starting out rw- and, after
2599                 // relocation processing, changed to r--.
2600                 //
2601                 // Ideally the last page of the text segment would not be
2602                 // writable even for this short period.
2603                 va = uint64(Rnd(int64(va), int64(*FlagRound)))
2604
2605                 order = append(order, &Segrodata)
2606                 Segrodata.Rwx = 04
2607                 Segrodata.Vaddr = va
2608                 for _, s := range Segrodata.Sections {
2609                         va = uint64(Rnd(int64(va), int64(s.Align)))
2610                         s.Vaddr = va
2611                         va += s.Length
2612                 }
2613
2614                 Segrodata.Length = va - Segrodata.Vaddr
2615         }
2616         if len(Segrelrodata.Sections) > 0 {
2617                 // align to page boundary so as not to mix
2618                 // rodata, rel-ro data, and executable text.
2619                 va = uint64(Rnd(int64(va), int64(*FlagRound)))
2620                 if ctxt.HeadType == objabi.Haix {
2621                         // Relro data are inside data segment on AIX.
2622                         va += uint64(XCOFFDATABASE) - uint64(XCOFFTEXTBASE)
2623                 }
2624
2625                 order = append(order, &Segrelrodata)
2626                 Segrelrodata.Rwx = 06
2627                 Segrelrodata.Vaddr = va
2628                 for _, s := range Segrelrodata.Sections {
2629                         va = uint64(Rnd(int64(va), int64(s.Align)))
2630                         s.Vaddr = va
2631                         va += s.Length
2632                 }
2633
2634                 Segrelrodata.Length = va - Segrelrodata.Vaddr
2635         }
2636
2637         va = uint64(Rnd(int64(va), int64(*FlagRound)))
2638         if ctxt.HeadType == objabi.Haix && len(Segrelrodata.Sections) == 0 {
2639                 // Data sections are moved to an unreachable segment
2640                 // to ensure that they are position-independent.
2641                 // Already done if relro sections exist.
2642                 va += uint64(XCOFFDATABASE) - uint64(XCOFFTEXTBASE)
2643         }
2644         order = append(order, &Segdata)
2645         Segdata.Rwx = 06
2646         Segdata.Vaddr = va
2647         var data *sym.Section
2648         var noptr *sym.Section
2649         var bss *sym.Section
2650         var noptrbss *sym.Section
2651         var fuzzCounters *sym.Section
2652         for i, s := range Segdata.Sections {
2653                 if (ctxt.IsELF || ctxt.HeadType == objabi.Haix) && s.Name == ".tbss" {
2654                         continue
2655                 }
2656                 vlen := int64(s.Length)
2657                 if i+1 < len(Segdata.Sections) && !((ctxt.IsELF || ctxt.HeadType == objabi.Haix) && Segdata.Sections[i+1].Name == ".tbss") {
2658                         vlen = int64(Segdata.Sections[i+1].Vaddr - s.Vaddr)
2659                 }
2660                 s.Vaddr = va
2661                 va += uint64(vlen)
2662                 Segdata.Length = va - Segdata.Vaddr
2663                 switch s.Name {
2664                 case ".data":
2665                         data = s
2666                 case ".noptrdata":
2667                         noptr = s
2668                 case ".bss":
2669                         bss = s
2670                 case ".noptrbss":
2671                         noptrbss = s
2672                 case ".go.fuzzcntrs":
2673                         fuzzCounters = s
2674                 }
2675         }
2676
2677         // Assign Segdata's Filelen omitting the BSS. We do this here
2678         // simply because right now we know where the BSS starts.
2679         Segdata.Filelen = bss.Vaddr - Segdata.Vaddr
2680
2681         va = uint64(Rnd(int64(va), int64(*FlagRound)))
2682         order = append(order, &Segdwarf)
2683         Segdwarf.Rwx = 06
2684         Segdwarf.Vaddr = va
2685         for i, s := range Segdwarf.Sections {
2686                 vlen := int64(s.Length)
2687                 if i+1 < len(Segdwarf.Sections) {
2688                         vlen = int64(Segdwarf.Sections[i+1].Vaddr - s.Vaddr)
2689                 }
2690                 s.Vaddr = va
2691                 va += uint64(vlen)
2692                 if ctxt.HeadType == objabi.Hwindows {
2693                         va = uint64(Rnd(int64(va), PEFILEALIGN))
2694                 }
2695                 Segdwarf.Length = va - Segdwarf.Vaddr
2696         }
2697
2698         ldr := ctxt.loader
2699         var (
2700                 rodata  = ldr.SymSect(ldr.LookupOrCreateSym("runtime.rodata", 0))
2701                 symtab  = ldr.SymSect(ldr.LookupOrCreateSym("runtime.symtab", 0))
2702                 pclntab = ldr.SymSect(ldr.LookupOrCreateSym("runtime.pclntab", 0))
2703                 types   = ldr.SymSect(ldr.LookupOrCreateSym("runtime.types", 0))
2704         )
2705
2706         for _, s := range ctxt.datap {
2707                 if sect := ldr.SymSect(s); sect != nil {
2708                         ldr.AddToSymValue(s, int64(sect.Vaddr))
2709                 }
2710                 v := ldr.SymValue(s)
2711                 for sub := ldr.SubSym(s); sub != 0; sub = ldr.SubSym(sub) {
2712                         ldr.AddToSymValue(sub, v)
2713                 }
2714         }
2715
2716         for _, si := range dwarfp {
2717                 for _, s := range si.syms {
2718                         if sect := ldr.SymSect(s); sect != nil {
2719                                 ldr.AddToSymValue(s, int64(sect.Vaddr))
2720                         }
2721                         sub := ldr.SubSym(s)
2722                         if sub != 0 {
2723                                 panic(fmt.Sprintf("unexpected sub-sym for %s %s", ldr.SymName(s), ldr.SymType(s).String()))
2724                         }
2725                         v := ldr.SymValue(s)
2726                         for ; sub != 0; sub = ldr.SubSym(sub) {
2727                                 ldr.AddToSymValue(s, v)
2728                         }
2729                 }
2730         }
2731
2732         if ctxt.BuildMode == BuildModeShared {
2733                 s := ldr.LookupOrCreateSym("go:link.abihashbytes", 0)
2734                 sect := ldr.SymSect(ldr.LookupOrCreateSym(".note.go.abihash", 0))
2735                 ldr.SetSymSect(s, sect)
2736                 ldr.SetSymValue(s, int64(sect.Vaddr+16))
2737         }
2738
2739         // If there are multiple text sections, create runtime.text.n for
2740         // their section Vaddr, using n for index
2741         n := 1
2742         for _, sect := range Segtext.Sections[1:] {
2743                 if sect.Name != ".text" {
2744                         break
2745                 }
2746                 symname := fmt.Sprintf("runtime.text.%d", n)
2747                 if ctxt.HeadType != objabi.Haix || ctxt.LinkMode != LinkExternal {
2748                         // Addresses are already set on AIX with external linker
2749                         // because these symbols are part of their sections.
2750                         ctxt.xdefine(symname, sym.STEXT, int64(sect.Vaddr))
2751                 }
2752                 n++
2753         }
2754
2755         ctxt.xdefine("runtime.rodata", sym.SRODATA, int64(rodata.Vaddr))
2756         ctxt.xdefine("runtime.erodata", sym.SRODATA, int64(rodata.Vaddr+rodata.Length))
2757         ctxt.xdefine("runtime.types", sym.SRODATA, int64(types.Vaddr))
2758         ctxt.xdefine("runtime.etypes", sym.SRODATA, int64(types.Vaddr+types.Length))
2759
2760         s := ldr.Lookup("runtime.gcdata", 0)
2761         ldr.SetAttrLocal(s, true)
2762         ctxt.xdefine("runtime.egcdata", sym.SRODATA, ldr.SymAddr(s)+ldr.SymSize(s))
2763         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.egcdata", 0), ldr.SymSect(s))
2764
2765         s = ldr.LookupOrCreateSym("runtime.gcbss", 0)
2766         ldr.SetAttrLocal(s, true)
2767         ctxt.xdefine("runtime.egcbss", sym.SRODATA, ldr.SymAddr(s)+ldr.SymSize(s))
2768         ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.egcbss", 0), ldr.SymSect(s))
2769
2770         ctxt.xdefine("runtime.symtab", sym.SRODATA, int64(symtab.Vaddr))
2771         ctxt.xdefine("runtime.esymtab", sym.SRODATA, int64(symtab.Vaddr+symtab.Length))
2772         ctxt.xdefine("runtime.pclntab", sym.SRODATA, int64(pclntab.Vaddr))
2773         ctxt.defineInternal("runtime.pcheader", sym.SRODATA)
2774         ctxt.defineInternal("runtime.funcnametab", sym.SRODATA)
2775         ctxt.defineInternal("runtime.cutab", sym.SRODATA)
2776         ctxt.defineInternal("runtime.filetab", sym.SRODATA)
2777         ctxt.defineInternal("runtime.pctab", sym.SRODATA)
2778         ctxt.defineInternal("runtime.functab", sym.SRODATA)
2779         ctxt.xdefine("runtime.epclntab", sym.SRODATA, int64(pclntab.Vaddr+pclntab.Length))
2780         ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr))
2781         ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr+noptr.Length))
2782         ctxt.xdefine("runtime.bss", sym.SBSS, int64(bss.Vaddr))
2783         ctxt.xdefine("runtime.ebss", sym.SBSS, int64(bss.Vaddr+bss.Length))
2784         ctxt.xdefine("runtime.data", sym.SDATA, int64(data.Vaddr))
2785         ctxt.xdefine("runtime.edata", sym.SDATA, int64(data.Vaddr+data.Length))
2786         ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr))
2787         ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length))
2788         ctxt.xdefine("runtime.covctrs", sym.SCOVERAGE_COUNTER, int64(noptrbss.Vaddr+covCounterDataStartOff))
2789         ctxt.xdefine("runtime.ecovctrs", sym.SCOVERAGE_COUNTER, int64(noptrbss.Vaddr+covCounterDataStartOff+covCounterDataLen))
2790         ctxt.xdefine("runtime.end", sym.SBSS, int64(Segdata.Vaddr+Segdata.Length))
2791
2792         if fuzzCounters != nil {
2793                 ctxt.xdefine("runtime.__start___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr))
2794                 ctxt.xdefine("runtime.__stop___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr+fuzzCounters.Length))
2795                 ctxt.xdefine("internal/fuzz._counters", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr))
2796                 ctxt.xdefine("internal/fuzz._ecounters", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr+fuzzCounters.Length))
2797         }
2798
2799         if ctxt.IsSolaris() {
2800                 // On Solaris, in the runtime it sets the external names of the
2801                 // end symbols. Unset them and define separate symbols, so we
2802                 // keep both.
2803                 etext := ldr.Lookup("runtime.etext", 0)
2804                 edata := ldr.Lookup("runtime.edata", 0)
2805                 end := ldr.Lookup("runtime.end", 0)
2806                 ldr.SetSymExtname(etext, "runtime.etext")
2807                 ldr.SetSymExtname(edata, "runtime.edata")
2808                 ldr.SetSymExtname(end, "runtime.end")
2809                 ctxt.xdefine("_etext", ldr.SymType(etext), ldr.SymValue(etext))
2810                 ctxt.xdefine("_edata", ldr.SymType(edata), ldr.SymValue(edata))
2811                 ctxt.xdefine("_end", ldr.SymType(end), ldr.SymValue(end))
2812                 ldr.SetSymSect(ldr.Lookup("_etext", 0), ldr.SymSect(etext))
2813                 ldr.SetSymSect(ldr.Lookup("_edata", 0), ldr.SymSect(edata))
2814                 ldr.SetSymSect(ldr.Lookup("_end", 0), ldr.SymSect(end))
2815         }
2816
2817         if ctxt.IsPPC64() && ctxt.IsElf() {
2818                 // Resolve .TOC. symbols for all objects. Only one TOC region is supported. If a
2819                 // GOT section is present, compute it as suggested by the ELFv2 ABI. Otherwise,
2820                 // choose a similar offset from the start of the data segment.
2821                 tocAddr := int64(Segdata.Vaddr) + 0x8000
2822                 if gotAddr := ldr.SymValue(ctxt.GOT); gotAddr != 0 {
2823                         tocAddr = gotAddr + 0x8000
2824                 }
2825                 for i := range ctxt.DotTOC {
2826                         if i >= sym.SymVerABICount && i < sym.SymVerStatic { // these versions are not used currently
2827                                 continue
2828                         }
2829                         if toc := ldr.Lookup(".TOC.", i); toc != 0 {
2830                                 ldr.SetSymValue(toc, tocAddr)
2831                         }
2832                 }
2833         }
2834
2835         return order
2836 }
2837
2838 // layout assigns file offsets and lengths to the segments in order.
2839 // Returns the file size containing all the segments.
2840 func (ctxt *Link) layout(order []*sym.Segment) uint64 {
2841         var prev *sym.Segment
2842         for _, seg := range order {
2843                 if prev == nil {
2844                         seg.Fileoff = uint64(HEADR)
2845                 } else {
2846                         switch ctxt.HeadType {
2847                         default:
2848                                 // Assuming the previous segment was
2849                                 // aligned, the following rounding
2850                                 // should ensure that this segment's
2851                                 // VA ≡ Fileoff mod FlagRound.
2852                                 seg.Fileoff = uint64(Rnd(int64(prev.Fileoff+prev.Filelen), int64(*FlagRound)))
2853                                 if seg.Vaddr%uint64(*FlagRound) != seg.Fileoff%uint64(*FlagRound) {
2854                                         Exitf("bad segment rounding (Vaddr=%#x Fileoff=%#x FlagRound=%#x)", seg.Vaddr, seg.Fileoff, *FlagRound)
2855                                 }
2856                         case objabi.Hwindows:
2857                                 seg.Fileoff = prev.Fileoff + uint64(Rnd(int64(prev.Filelen), PEFILEALIGN))
2858                         case objabi.Hplan9:
2859                                 seg.Fileoff = prev.Fileoff + prev.Filelen
2860                         }
2861                 }
2862                 if seg != &Segdata {
2863                         // Link.address already set Segdata.Filelen to
2864                         // account for BSS.
2865                         seg.Filelen = seg.Length
2866                 }
2867                 prev = seg
2868         }
2869         return prev.Fileoff + prev.Filelen
2870 }
2871
2872 // add a trampoline with symbol s (to be laid down after the current function)
2873 func (ctxt *Link) AddTramp(s *loader.SymbolBuilder) {
2874         s.SetType(sym.STEXT)
2875         s.SetReachable(true)
2876         s.SetOnList(true)
2877         ctxt.tramps = append(ctxt.tramps, s.Sym())
2878         if *FlagDebugTramp > 0 && ctxt.Debugvlog > 0 {
2879                 ctxt.Logf("trampoline %s inserted\n", s.Name())
2880         }
2881 }
2882
2883 // compressSyms compresses syms and returns the contents of the
2884 // compressed section. If the section would get larger, it returns nil.
2885 func compressSyms(ctxt *Link, syms []loader.Sym) []byte {
2886         ldr := ctxt.loader
2887         var total int64
2888         for _, sym := range syms {
2889                 total += ldr.SymSize(sym)
2890         }
2891
2892         var buf bytes.Buffer
2893         if ctxt.IsELF {
2894                 switch ctxt.Arch.PtrSize {
2895                 case 8:
2896                         binary.Write(&buf, ctxt.Arch.ByteOrder, elf.Chdr64{
2897                                 Type:      uint32(elf.COMPRESS_ZLIB),
2898                                 Size:      uint64(total),
2899                                 Addralign: uint64(ctxt.Arch.Alignment),
2900                         })
2901                 case 4:
2902                         binary.Write(&buf, ctxt.Arch.ByteOrder, elf.Chdr32{
2903                                 Type:      uint32(elf.COMPRESS_ZLIB),
2904                                 Size:      uint32(total),
2905                                 Addralign: uint32(ctxt.Arch.Alignment),
2906                         })
2907                 default:
2908                         log.Fatalf("can't compress header size:%d", ctxt.Arch.PtrSize)
2909                 }
2910         } else {
2911                 buf.Write([]byte("ZLIB"))
2912                 var sizeBytes [8]byte
2913                 binary.BigEndian.PutUint64(sizeBytes[:], uint64(total))
2914                 buf.Write(sizeBytes[:])
2915         }
2916
2917         var relocbuf []byte // temporary buffer for applying relocations
2918
2919         // Using zlib.BestSpeed achieves very nearly the same
2920         // compression levels of zlib.DefaultCompression, but takes
2921         // substantially less time. This is important because DWARF
2922         // compression can be a significant fraction of link time.
2923         z, err := zlib.NewWriterLevel(&buf, zlib.BestSpeed)
2924         if err != nil {
2925                 log.Fatalf("NewWriterLevel failed: %s", err)
2926         }
2927         st := ctxt.makeRelocSymState()
2928         for _, s := range syms {
2929                 // Symbol data may be read-only. Apply relocations in a
2930                 // temporary buffer, and immediately write it out.
2931                 P := ldr.Data(s)
2932                 relocs := ldr.Relocs(s)
2933                 if relocs.Count() != 0 {
2934                         relocbuf = append(relocbuf[:0], P...)
2935                         P = relocbuf
2936                         st.relocsym(s, P)
2937                 }
2938                 if _, err := z.Write(P); err != nil {
2939                         log.Fatalf("compression failed: %s", err)
2940                 }
2941                 for i := ldr.SymSize(s) - int64(len(P)); i > 0; {
2942                         b := zeros[:]
2943                         if i < int64(len(b)) {
2944                                 b = b[:i]
2945                         }
2946                         n, err := z.Write(b)
2947                         if err != nil {
2948                                 log.Fatalf("compression failed: %s", err)
2949                         }
2950                         i -= int64(n)
2951                 }
2952         }
2953         if err := z.Close(); err != nil {
2954                 log.Fatalf("compression failed: %s", err)
2955         }
2956         if int64(buf.Len()) >= total {
2957                 // Compression didn't save any space.
2958                 return nil
2959         }
2960         return buf.Bytes()
2961 }