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