]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/link/internal/ld/elf.go
all: make copyright headers consistent with one space after period
[gostls13.git] / src / cmd / link / internal / ld / elf.go
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package ld
6
7 import (
8         "cmd/internal/obj"
9         "cmd/internal/sys"
10         "crypto/sha1"
11         "encoding/binary"
12         "encoding/hex"
13         "path/filepath"
14         "sort"
15         "strings"
16 )
17
18 /*
19  * Derived from:
20  * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $
21  * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $
22  * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $
23  * $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $
24  * $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $
25  * $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $
26  * $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $
27  * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $
28  * $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $
29  *
30  * Copyright (c) 1996-1998 John D. Polstra.  All rights reserved.
31  * Copyright (c) 2001 David E. O'Brien
32  * Portions Copyright 2009 The Go Authors. All rights reserved.
33  *
34  * Redistribution and use in source and binary forms, with or without
35  * modification, are permitted provided that the following conditions
36  * are met:
37  * 1. Redistributions of source code must retain the above copyright
38  *    notice, this list of conditions and the following disclaimer.
39  * 2. Redistributions in binary form must reproduce the above copyright
40  *    notice, this list of conditions and the following disclaimer in the
41  *    documentation and/or other materials provided with the distribution.
42  *
43  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
44  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
47  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53  * SUCH DAMAGE.
54  *
55  */
56
57 /*
58  * ELF definitions that are independent of architecture or word size.
59  */
60
61 /*
62  * Note header.  The ".note" section contains an array of notes.  Each
63  * begins with this header, aligned to a word boundary.  Immediately
64  * following the note header is n_namesz bytes of name, padded to the
65  * next word boundary.  Then comes n_descsz bytes of descriptor, again
66  * padded to a word boundary.  The values of n_namesz and n_descsz do
67  * not include the padding.
68  */
69 type Elf_Note struct {
70         n_namesz uint32
71         n_descsz uint32
72         n_type   uint32
73 }
74
75 const (
76         EI_MAG0              = 0
77         EI_MAG1              = 1
78         EI_MAG2              = 2
79         EI_MAG3              = 3
80         EI_CLASS             = 4
81         EI_DATA              = 5
82         EI_VERSION           = 6
83         EI_OSABI             = 7
84         EI_ABIVERSION        = 8
85         OLD_EI_BRAND         = 8
86         EI_PAD               = 9
87         EI_NIDENT            = 16
88         ELFMAG0              = 0x7f
89         ELFMAG1              = 'E'
90         ELFMAG2              = 'L'
91         ELFMAG3              = 'F'
92         SELFMAG              = 4
93         EV_NONE              = 0
94         EV_CURRENT           = 1
95         ELFCLASSNONE         = 0
96         ELFCLASS32           = 1
97         ELFCLASS64           = 2
98         ELFDATANONE          = 0
99         ELFDATA2LSB          = 1
100         ELFDATA2MSB          = 2
101         ELFOSABI_NONE        = 0
102         ELFOSABI_HPUX        = 1
103         ELFOSABI_NETBSD      = 2
104         ELFOSABI_LINUX       = 3
105         ELFOSABI_HURD        = 4
106         ELFOSABI_86OPEN      = 5
107         ELFOSABI_SOLARIS     = 6
108         ELFOSABI_AIX         = 7
109         ELFOSABI_IRIX        = 8
110         ELFOSABI_FREEBSD     = 9
111         ELFOSABI_TRU64       = 10
112         ELFOSABI_MODESTO     = 11
113         ELFOSABI_OPENBSD     = 12
114         ELFOSABI_OPENVMS     = 13
115         ELFOSABI_NSK         = 14
116         ELFOSABI_ARM         = 97
117         ELFOSABI_STANDALONE  = 255
118         ELFOSABI_SYSV        = ELFOSABI_NONE
119         ELFOSABI_MONTEREY    = ELFOSABI_AIX
120         ET_NONE              = 0
121         ET_REL               = 1
122         ET_EXEC              = 2
123         ET_DYN               = 3
124         ET_CORE              = 4
125         ET_LOOS              = 0xfe00
126         ET_HIOS              = 0xfeff
127         ET_LOPROC            = 0xff00
128         ET_HIPROC            = 0xffff
129         EM_NONE              = 0
130         EM_M32               = 1
131         EM_SPARC             = 2
132         EM_386               = 3
133         EM_68K               = 4
134         EM_88K               = 5
135         EM_860               = 7
136         EM_MIPS              = 8
137         EM_S370              = 9
138         EM_MIPS_RS3_LE       = 10
139         EM_PARISC            = 15
140         EM_VPP500            = 17
141         EM_SPARC32PLUS       = 18
142         EM_960               = 19
143         EM_PPC               = 20
144         EM_PPC64             = 21
145         EM_S390              = 22
146         EM_V800              = 36
147         EM_FR20              = 37
148         EM_RH32              = 38
149         EM_RCE               = 39
150         EM_ARM               = 40
151         EM_SH                = 42
152         EM_SPARCV9           = 43
153         EM_TRICORE           = 44
154         EM_ARC               = 45
155         EM_H8_300            = 46
156         EM_H8_300H           = 47
157         EM_H8S               = 48
158         EM_H8_500            = 49
159         EM_IA_64             = 50
160         EM_MIPS_X            = 51
161         EM_COLDFIRE          = 52
162         EM_68HC12            = 53
163         EM_MMA               = 54
164         EM_PCP               = 55
165         EM_NCPU              = 56
166         EM_NDR1              = 57
167         EM_STARCORE          = 58
168         EM_ME16              = 59
169         EM_ST100             = 60
170         EM_TINYJ             = 61
171         EM_X86_64            = 62
172         EM_AARCH64           = 183
173         EM_486               = 6
174         EM_MIPS_RS4_BE       = 10
175         EM_ALPHA_STD         = 41
176         EM_ALPHA             = 0x9026
177         SHN_UNDEF            = 0
178         SHN_LORESERVE        = 0xff00
179         SHN_LOPROC           = 0xff00
180         SHN_HIPROC           = 0xff1f
181         SHN_LOOS             = 0xff20
182         SHN_HIOS             = 0xff3f
183         SHN_ABS              = 0xfff1
184         SHN_COMMON           = 0xfff2
185         SHN_XINDEX           = 0xffff
186         SHN_HIRESERVE        = 0xffff
187         SHT_NULL             = 0
188         SHT_PROGBITS         = 1
189         SHT_SYMTAB           = 2
190         SHT_STRTAB           = 3
191         SHT_RELA             = 4
192         SHT_HASH             = 5
193         SHT_DYNAMIC          = 6
194         SHT_NOTE             = 7
195         SHT_NOBITS           = 8
196         SHT_REL              = 9
197         SHT_SHLIB            = 10
198         SHT_DYNSYM           = 11
199         SHT_INIT_ARRAY       = 14
200         SHT_FINI_ARRAY       = 15
201         SHT_PREINIT_ARRAY    = 16
202         SHT_GROUP            = 17
203         SHT_SYMTAB_SHNDX     = 18
204         SHT_LOOS             = 0x60000000
205         SHT_HIOS             = 0x6fffffff
206         SHT_GNU_VERDEF       = 0x6ffffffd
207         SHT_GNU_VERNEED      = 0x6ffffffe
208         SHT_GNU_VERSYM       = 0x6fffffff
209         SHT_LOPROC           = 0x70000000
210         SHT_ARM_ATTRIBUTES   = 0x70000003
211         SHT_HIPROC           = 0x7fffffff
212         SHT_LOUSER           = 0x80000000
213         SHT_HIUSER           = 0xffffffff
214         SHF_WRITE            = 0x1
215         SHF_ALLOC            = 0x2
216         SHF_EXECINSTR        = 0x4
217         SHF_MERGE            = 0x10
218         SHF_STRINGS          = 0x20
219         SHF_INFO_LINK        = 0x40
220         SHF_LINK_ORDER       = 0x80
221         SHF_OS_NONCONFORMING = 0x100
222         SHF_GROUP            = 0x200
223         SHF_TLS              = 0x400
224         SHF_MASKOS           = 0x0ff00000
225         SHF_MASKPROC         = 0xf0000000
226         PT_NULL              = 0
227         PT_LOAD              = 1
228         PT_DYNAMIC           = 2
229         PT_INTERP            = 3
230         PT_NOTE              = 4
231         PT_SHLIB             = 5
232         PT_PHDR              = 6
233         PT_TLS               = 7
234         PT_LOOS              = 0x60000000
235         PT_HIOS              = 0x6fffffff
236         PT_LOPROC            = 0x70000000
237         PT_HIPROC            = 0x7fffffff
238         PT_GNU_STACK         = 0x6474e551
239         PT_PAX_FLAGS         = 0x65041580
240         PF_X                 = 0x1
241         PF_W                 = 0x2
242         PF_R                 = 0x4
243         PF_MASKOS            = 0x0ff00000
244         PF_MASKPROC          = 0xf0000000
245         DT_NULL              = 0
246         DT_NEEDED            = 1
247         DT_PLTRELSZ          = 2
248         DT_PLTGOT            = 3
249         DT_HASH              = 4
250         DT_STRTAB            = 5
251         DT_SYMTAB            = 6
252         DT_RELA              = 7
253         DT_RELASZ            = 8
254         DT_RELAENT           = 9
255         DT_STRSZ             = 10
256         DT_SYMENT            = 11
257         DT_INIT              = 12
258         DT_FINI              = 13
259         DT_SONAME            = 14
260         DT_RPATH             = 15
261         DT_SYMBOLIC          = 16
262         DT_REL               = 17
263         DT_RELSZ             = 18
264         DT_RELENT            = 19
265         DT_PLTREL            = 20
266         DT_DEBUG             = 21
267         DT_TEXTREL           = 22
268         DT_JMPREL            = 23
269         DT_BIND_NOW          = 24
270         DT_INIT_ARRAY        = 25
271         DT_FINI_ARRAY        = 26
272         DT_INIT_ARRAYSZ      = 27
273         DT_FINI_ARRAYSZ      = 28
274         DT_RUNPATH           = 29
275         DT_FLAGS             = 30
276         DT_ENCODING          = 32
277         DT_PREINIT_ARRAY     = 32
278         DT_PREINIT_ARRAYSZ   = 33
279         DT_LOOS              = 0x6000000d
280         DT_HIOS              = 0x6ffff000
281         DT_LOPROC            = 0x70000000
282         DT_HIPROC            = 0x7fffffff
283         DT_VERNEED           = 0x6ffffffe
284         DT_VERNEEDNUM        = 0x6fffffff
285         DT_VERSYM            = 0x6ffffff0
286         DT_PPC64_GLINK       = DT_LOPROC + 0
287         DT_PPC64_OPT         = DT_LOPROC + 3
288         DF_ORIGIN            = 0x0001
289         DF_SYMBOLIC          = 0x0002
290         DF_TEXTREL           = 0x0004
291         DF_BIND_NOW          = 0x0008
292         DF_STATIC_TLS        = 0x0010
293         NT_PRSTATUS          = 1
294         NT_FPREGSET          = 2
295         NT_PRPSINFO          = 3
296         STB_LOCAL            = 0
297         STB_GLOBAL           = 1
298         STB_WEAK             = 2
299         STB_LOOS             = 10
300         STB_HIOS             = 12
301         STB_LOPROC           = 13
302         STB_HIPROC           = 15
303         STT_NOTYPE           = 0
304         STT_OBJECT           = 1
305         STT_FUNC             = 2
306         STT_SECTION          = 3
307         STT_FILE             = 4
308         STT_COMMON           = 5
309         STT_TLS              = 6
310         STT_LOOS             = 10
311         STT_HIOS             = 12
312         STT_LOPROC           = 13
313         STT_HIPROC           = 15
314         STV_DEFAULT          = 0x0
315         STV_INTERNAL         = 0x1
316         STV_HIDDEN           = 0x2
317         STV_PROTECTED        = 0x3
318         STN_UNDEF            = 0
319 )
320
321 /* For accessing the fields of r_info. */
322
323 /* For constructing r_info from field values. */
324
325 /*
326  * Relocation types.
327  */
328 const (
329         R_X86_64_NONE           = 0
330         R_X86_64_64             = 1
331         R_X86_64_PC32           = 2
332         R_X86_64_GOT32          = 3
333         R_X86_64_PLT32          = 4
334         R_X86_64_COPY           = 5
335         R_X86_64_GLOB_DAT       = 6
336         R_X86_64_JMP_SLOT       = 7
337         R_X86_64_RELATIVE       = 8
338         R_X86_64_GOTPCREL       = 9
339         R_X86_64_32             = 10
340         R_X86_64_32S            = 11
341         R_X86_64_16             = 12
342         R_X86_64_PC16           = 13
343         R_X86_64_8              = 14
344         R_X86_64_PC8            = 15
345         R_X86_64_DTPMOD64       = 16
346         R_X86_64_DTPOFF64       = 17
347         R_X86_64_TPOFF64        = 18
348         R_X86_64_TLSGD          = 19
349         R_X86_64_TLSLD          = 20
350         R_X86_64_DTPOFF32       = 21
351         R_X86_64_GOTTPOFF       = 22
352         R_X86_64_TPOFF32        = 23
353         R_X86_64_PC64           = 24
354         R_X86_64_GOTOFF64       = 25
355         R_X86_64_GOTPC32        = 26
356         R_X86_64_GOT64          = 27
357         R_X86_64_GOTPCREL64     = 28
358         R_X86_64_GOTPC64        = 29
359         R_X86_64_GOTPLT64       = 30
360         R_X86_64_PLTOFF64       = 31
361         R_X86_64_SIZE32         = 32
362         R_X86_64_SIZE64         = 33
363         R_X86_64_GOTPC32_TLSDEC = 34
364         R_X86_64_TLSDESC_CALL   = 35
365         R_X86_64_TLSDESC        = 36
366         R_X86_64_IRELATIVE      = 37
367         R_X86_64_PC32_BND       = 40
368         R_X86_64_GOTPCRELX      = 41
369         R_X86_64_REX_GOTPCRELX  = 42
370
371         R_AARCH64_ABS64                       = 257
372         R_AARCH64_ABS32                       = 258
373         R_AARCH64_CALL26                      = 283
374         R_AARCH64_ADR_PREL_PG_HI21            = 275
375         R_AARCH64_ADD_ABS_LO12_NC             = 277
376         R_AARCH64_LDST8_ABS_LO12_NC           = 278
377         R_AARCH64_LDST16_ABS_LO12_NC          = 284
378         R_AARCH64_LDST32_ABS_LO12_NC          = 285
379         R_AARCH64_LDST64_ABS_LO12_NC          = 286
380         R_AARCH64_ADR_GOT_PAGE                = 311
381         R_AARCH64_LD64_GOT_LO12_NC            = 312
382         R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21   = 541
383         R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC = 542
384         R_AARCH64_TLSLE_MOVW_TPREL_G0         = 547
385
386         R_ALPHA_NONE           = 0
387         R_ALPHA_REFLONG        = 1
388         R_ALPHA_REFQUAD        = 2
389         R_ALPHA_GPREL32        = 3
390         R_ALPHA_LITERAL        = 4
391         R_ALPHA_LITUSE         = 5
392         R_ALPHA_GPDISP         = 6
393         R_ALPHA_BRADDR         = 7
394         R_ALPHA_HINT           = 8
395         R_ALPHA_SREL16         = 9
396         R_ALPHA_SREL32         = 10
397         R_ALPHA_SREL64         = 11
398         R_ALPHA_OP_PUSH        = 12
399         R_ALPHA_OP_STORE       = 13
400         R_ALPHA_OP_PSUB        = 14
401         R_ALPHA_OP_PRSHIFT     = 15
402         R_ALPHA_GPVALUE        = 16
403         R_ALPHA_GPRELHIGH      = 17
404         R_ALPHA_GPRELLOW       = 18
405         R_ALPHA_IMMED_GP_16    = 19
406         R_ALPHA_IMMED_GP_HI32  = 20
407         R_ALPHA_IMMED_SCN_HI32 = 21
408         R_ALPHA_IMMED_BR_HI32  = 22
409         R_ALPHA_IMMED_LO32     = 23
410         R_ALPHA_COPY           = 24
411         R_ALPHA_GLOB_DAT       = 25
412         R_ALPHA_JMP_SLOT       = 26
413         R_ALPHA_RELATIVE       = 27
414
415         R_ARM_NONE          = 0
416         R_ARM_PC24          = 1
417         R_ARM_ABS32         = 2
418         R_ARM_REL32         = 3
419         R_ARM_PC13          = 4
420         R_ARM_ABS16         = 5
421         R_ARM_ABS12         = 6
422         R_ARM_THM_ABS5      = 7
423         R_ARM_ABS8          = 8
424         R_ARM_SBREL32       = 9
425         R_ARM_THM_PC22      = 10
426         R_ARM_THM_PC8       = 11
427         R_ARM_AMP_VCALL9    = 12
428         R_ARM_SWI24         = 13
429         R_ARM_THM_SWI8      = 14
430         R_ARM_XPC25         = 15
431         R_ARM_THM_XPC22     = 16
432         R_ARM_COPY          = 20
433         R_ARM_GLOB_DAT      = 21
434         R_ARM_JUMP_SLOT     = 22
435         R_ARM_RELATIVE      = 23
436         R_ARM_GOTOFF        = 24
437         R_ARM_GOTPC         = 25
438         R_ARM_GOT32         = 26
439         R_ARM_PLT32         = 27
440         R_ARM_CALL          = 28
441         R_ARM_JUMP24        = 29
442         R_ARM_V4BX          = 40
443         R_ARM_GOT_PREL      = 96
444         R_ARM_GNU_VTENTRY   = 100
445         R_ARM_GNU_VTINHERIT = 101
446         R_ARM_TLS_IE32      = 107
447         R_ARM_TLS_LE32      = 108
448         R_ARM_RSBREL32      = 250
449         R_ARM_THM_RPC22     = 251
450         R_ARM_RREL32        = 252
451         R_ARM_RABS32        = 253
452         R_ARM_RPC24         = 254
453         R_ARM_RBASE         = 255
454
455         R_386_NONE          = 0
456         R_386_32            = 1
457         R_386_PC32          = 2
458         R_386_GOT32         = 3
459         R_386_PLT32         = 4
460         R_386_COPY          = 5
461         R_386_GLOB_DAT      = 6
462         R_386_JMP_SLOT      = 7
463         R_386_RELATIVE      = 8
464         R_386_GOTOFF        = 9
465         R_386_GOTPC         = 10
466         R_386_TLS_TPOFF     = 14
467         R_386_TLS_IE        = 15
468         R_386_TLS_GOTIE     = 16
469         R_386_TLS_LE        = 17
470         R_386_TLS_GD        = 18
471         R_386_TLS_LDM       = 19
472         R_386_TLS_GD_32     = 24
473         R_386_TLS_GD_PUSH   = 25
474         R_386_TLS_GD_CALL   = 26
475         R_386_TLS_GD_POP    = 27
476         R_386_TLS_LDM_32    = 28
477         R_386_TLS_LDM_PUSH  = 29
478         R_386_TLS_LDM_CALL  = 30
479         R_386_TLS_LDM_POP   = 31
480         R_386_TLS_LDO_32    = 32
481         R_386_TLS_IE_32     = 33
482         R_386_TLS_LE_32     = 34
483         R_386_TLS_DTPMOD32  = 35
484         R_386_TLS_DTPOFF32  = 36
485         R_386_TLS_TPOFF32   = 37
486         R_386_TLS_GOTDESC   = 39
487         R_386_TLS_DESC_CALL = 40
488         R_386_TLS_DESC      = 41
489         R_386_IRELATIVE     = 42
490         R_386_GOT32X        = 43
491
492         R_MIPS_NONE            = 0
493         R_MIPS_16              = 1
494         R_MIPS_32              = 2
495         R_MIPS_REL32           = 3
496         R_MIPS_26              = 4
497         R_MIPS_HI16            = 5
498         R_MIPS_LO16            = 6
499         R_MIPS_GPREL16         = 7
500         R_MIPS_LITERAL         = 8
501         R_MIPS_GOT16           = 9
502         R_MIPS_PC16            = 10
503         R_MIPS_CALL16          = 11
504         R_MIPS_GPREL32         = 12
505         R_MIPS_SHIFT5          = 16
506         R_MIPS_SHIFT6          = 17
507         R_MIPS_64              = 18
508         R_MIPS_GOT_DISP        = 19
509         R_MIPS_GOT_PAGE        = 20
510         R_MIPS_GOT_OFST        = 21
511         R_MIPS_GOT_HI16        = 22
512         R_MIPS_GOT_LO16        = 23
513         R_MIPS_SUB             = 24
514         R_MIPS_INSERT_A        = 25
515         R_MIPS_INSERT_B        = 26
516         R_MIPS_DELETE          = 27
517         R_MIPS_HIGHER          = 28
518         R_MIPS_HIGHEST         = 29
519         R_MIPS_CALL_HI16       = 30
520         R_MIPS_CALL_LO16       = 31
521         R_MIPS_SCN_DISP        = 32
522         R_MIPS_REL16           = 33
523         R_MIPS_ADD_IMMEDIATE   = 34
524         R_MIPS_PJUMP           = 35
525         R_MIPS_RELGOT          = 36
526         R_MIPS_JALR            = 37
527         R_MIPS_TLS_DTPMOD32    = 38
528         R_MIPS_TLS_DTPREL32    = 39
529         R_MIPS_TLS_DTPMOD64    = 40
530         R_MIPS_TLS_DTPREL64    = 41
531         R_MIPS_TLS_GD          = 42
532         R_MIPS_TLS_LDM         = 43
533         R_MIPS_TLS_DTPREL_HI16 = 44
534         R_MIPS_TLS_DTPREL_LO16 = 45
535         R_MIPS_TLS_GOTTPREL    = 46
536         R_MIPS_TLS_TPREL32     = 47
537         R_MIPS_TLS_TPREL64     = 48
538         R_MIPS_TLS_TPREL_HI16  = 49
539         R_MIPS_TLS_TPREL_LO16  = 50
540
541         R_PPC_NONE            = 0
542         R_PPC_ADDR32          = 1
543         R_PPC_ADDR24          = 2
544         R_PPC_ADDR16          = 3
545         R_PPC_ADDR16_LO       = 4
546         R_PPC_ADDR16_HI       = 5
547         R_PPC_ADDR16_HA       = 6
548         R_PPC_ADDR14          = 7
549         R_PPC_ADDR14_BRTAKEN  = 8
550         R_PPC_ADDR14_BRNTAKEN = 9
551         R_PPC_REL24           = 10
552         R_PPC_REL14           = 11
553         R_PPC_REL14_BRTAKEN   = 12
554         R_PPC_REL14_BRNTAKEN  = 13
555         R_PPC_GOT16           = 14
556         R_PPC_GOT16_LO        = 15
557         R_PPC_GOT16_HI        = 16
558         R_PPC_GOT16_HA        = 17
559         R_PPC_PLTREL24        = 18
560         R_PPC_COPY            = 19
561         R_PPC_GLOB_DAT        = 20
562         R_PPC_JMP_SLOT        = 21
563         R_PPC_RELATIVE        = 22
564         R_PPC_LOCAL24PC       = 23
565         R_PPC_UADDR32         = 24
566         R_PPC_UADDR16         = 25
567         R_PPC_REL32           = 26
568         R_PPC_PLT32           = 27
569         R_PPC_PLTREL32        = 28
570         R_PPC_PLT16_LO        = 29
571         R_PPC_PLT16_HI        = 30
572         R_PPC_PLT16_HA        = 31
573         R_PPC_SDAREL16        = 32
574         R_PPC_SECTOFF         = 33
575         R_PPC_SECTOFF_LO      = 34
576         R_PPC_SECTOFF_HI      = 35
577         R_PPC_SECTOFF_HA      = 36
578         R_PPC_TLS             = 67
579         R_PPC_DTPMOD32        = 68
580         R_PPC_TPREL16         = 69
581         R_PPC_TPREL16_LO      = 70
582         R_PPC_TPREL16_HI      = 71
583         R_PPC_TPREL16_HA      = 72
584         R_PPC_TPREL32         = 73
585         R_PPC_DTPREL16        = 74
586         R_PPC_DTPREL16_LO     = 75
587         R_PPC_DTPREL16_HI     = 76
588         R_PPC_DTPREL16_HA     = 77
589         R_PPC_DTPREL32        = 78
590         R_PPC_GOT_TLSGD16     = 79
591         R_PPC_GOT_TLSGD16_LO  = 80
592         R_PPC_GOT_TLSGD16_HI  = 81
593         R_PPC_GOT_TLSGD16_HA  = 82
594         R_PPC_GOT_TLSLD16     = 83
595         R_PPC_GOT_TLSLD16_LO  = 84
596         R_PPC_GOT_TLSLD16_HI  = 85
597         R_PPC_GOT_TLSLD16_HA  = 86
598         R_PPC_GOT_TPREL16     = 87
599         R_PPC_GOT_TPREL16_LO  = 88
600         R_PPC_GOT_TPREL16_HI  = 89
601         R_PPC_GOT_TPREL16_HA  = 90
602         R_PPC_EMB_NADDR32     = 101
603         R_PPC_EMB_NADDR16     = 102
604         R_PPC_EMB_NADDR16_LO  = 103
605         R_PPC_EMB_NADDR16_HI  = 104
606         R_PPC_EMB_NADDR16_HA  = 105
607         R_PPC_EMB_SDAI16      = 106
608         R_PPC_EMB_SDA2I16     = 107
609         R_PPC_EMB_SDA2REL     = 108
610         R_PPC_EMB_SDA21       = 109
611         R_PPC_EMB_MRKREF      = 110
612         R_PPC_EMB_RELSEC16    = 111
613         R_PPC_EMB_RELST_LO    = 112
614         R_PPC_EMB_RELST_HI    = 113
615         R_PPC_EMB_RELST_HA    = 114
616         R_PPC_EMB_BIT_FLD     = 115
617         R_PPC_EMB_RELSDA      = 116
618
619         R_PPC64_ADDR32            = R_PPC_ADDR32
620         R_PPC64_ADDR16_LO         = R_PPC_ADDR16_LO
621         R_PPC64_ADDR16_HA         = R_PPC_ADDR16_HA
622         R_PPC64_REL24             = R_PPC_REL24
623         R_PPC64_GOT16_HA          = R_PPC_GOT16_HA
624         R_PPC64_JMP_SLOT          = R_PPC_JMP_SLOT
625         R_PPC64_TPREL16           = R_PPC_TPREL16
626         R_PPC64_ADDR64            = 38
627         R_PPC64_TOC16             = 47
628         R_PPC64_TOC16_LO          = 48
629         R_PPC64_TOC16_HI          = 49
630         R_PPC64_TOC16_HA          = 50
631         R_PPC64_ADDR16_LO_DS      = 57
632         R_PPC64_GOT16_LO_DS       = 59
633         R_PPC64_TOC16_DS          = 63
634         R_PPC64_TOC16_LO_DS       = 64
635         R_PPC64_TLS               = 67
636         R_PPC64_GOT_TPREL16_LO_DS = 88
637         R_PPC64_GOT_TPREL16_HA    = 90
638         R_PPC64_REL16_LO          = 250
639         R_PPC64_REL16_HI          = 251
640         R_PPC64_REL16_HA          = 252
641
642         R_SPARC_NONE     = 0
643         R_SPARC_8        = 1
644         R_SPARC_16       = 2
645         R_SPARC_32       = 3
646         R_SPARC_DISP8    = 4
647         R_SPARC_DISP16   = 5
648         R_SPARC_DISP32   = 6
649         R_SPARC_WDISP30  = 7
650         R_SPARC_WDISP22  = 8
651         R_SPARC_HI22     = 9
652         R_SPARC_22       = 10
653         R_SPARC_13       = 11
654         R_SPARC_LO10     = 12
655         R_SPARC_GOT10    = 13
656         R_SPARC_GOT13    = 14
657         R_SPARC_GOT22    = 15
658         R_SPARC_PC10     = 16
659         R_SPARC_PC22     = 17
660         R_SPARC_WPLT30   = 18
661         R_SPARC_COPY     = 19
662         R_SPARC_GLOB_DAT = 20
663         R_SPARC_JMP_SLOT = 21
664         R_SPARC_RELATIVE = 22
665         R_SPARC_UA32     = 23
666         R_SPARC_PLT32    = 24
667         R_SPARC_HIPLT22  = 25
668         R_SPARC_LOPLT10  = 26
669         R_SPARC_PCPLT32  = 27
670         R_SPARC_PCPLT22  = 28
671         R_SPARC_PCPLT10  = 29
672         R_SPARC_10       = 30
673         R_SPARC_11       = 31
674         R_SPARC_64       = 32
675         R_SPARC_OLO10    = 33
676         R_SPARC_HH22     = 34
677         R_SPARC_HM10     = 35
678         R_SPARC_LM22     = 36
679         R_SPARC_PC_HH22  = 37
680         R_SPARC_PC_HM10  = 38
681         R_SPARC_PC_LM22  = 39
682         R_SPARC_WDISP16  = 40
683         R_SPARC_WDISP19  = 41
684         R_SPARC_GLOB_JMP = 42
685         R_SPARC_7        = 43
686         R_SPARC_5        = 44
687         R_SPARC_6        = 45
688         R_SPARC_DISP64   = 46
689         R_SPARC_PLT64    = 47
690         R_SPARC_HIX22    = 48
691         R_SPARC_LOX10    = 49
692         R_SPARC_H44      = 50
693         R_SPARC_M44      = 51
694         R_SPARC_L44      = 52
695         R_SPARC_REGISTER = 53
696         R_SPARC_UA64     = 54
697         R_SPARC_UA16     = 55
698
699         R_390_NONE        = 0
700         R_390_8           = 1
701         R_390_12          = 2
702         R_390_16          = 3
703         R_390_32          = 4
704         R_390_PC32        = 5
705         R_390_GOT12       = 6
706         R_390_GOT32       = 7
707         R_390_PLT32       = 8
708         R_390_COPY        = 9
709         R_390_GLOB_DAT    = 10
710         R_390_JMP_SLOT    = 11
711         R_390_RELATIVE    = 12
712         R_390_GOTOFF      = 13
713         R_390_GOTPC       = 14
714         R_390_GOT16       = 15
715         R_390_PC16        = 16
716         R_390_PC16DBL     = 17
717         R_390_PLT16DBL    = 18
718         R_390_PC32DBL     = 19
719         R_390_PLT32DBL    = 20
720         R_390_GOTPCDBL    = 21
721         R_390_64          = 22
722         R_390_PC64        = 23
723         R_390_GOT64       = 24
724         R_390_PLT64       = 25
725         R_390_GOTENT      = 26
726         R_390_GOTOFF16    = 27
727         R_390_GOTOFF64    = 28
728         R_390_GOTPLT12    = 29
729         R_390_GOTPLT16    = 30
730         R_390_GOTPLT32    = 31
731         R_390_GOTPLT64    = 32
732         R_390_GOTPLTENT   = 33
733         R_390_GOTPLTOFF16 = 34
734         R_390_GOTPLTOFF32 = 35
735         R_390_GOTPLTOFF64 = 36
736         R_390_TLS_LOAD    = 37
737         R_390_TLS_GDCALL  = 38
738         R_390_TLS_LDCALL  = 39
739         R_390_TLS_GD32    = 40
740         R_390_TLS_GD64    = 41
741         R_390_TLS_GOTIE12 = 42
742         R_390_TLS_GOTIE32 = 43
743         R_390_TLS_GOTIE64 = 44
744         R_390_TLS_LDM32   = 45
745         R_390_TLS_LDM64   = 46
746         R_390_TLS_IE32    = 47
747         R_390_TLS_IE64    = 48
748         R_390_TLS_IEENT   = 49
749         R_390_TLS_LE32    = 50
750         R_390_TLS_LE64    = 51
751         R_390_TLS_LDO32   = 52
752         R_390_TLS_LDO64   = 53
753         R_390_TLS_DTPMOD  = 54
754         R_390_TLS_DTPOFF  = 55
755         R_390_TLS_TPOFF   = 56
756         R_390_20          = 57
757         R_390_GOT20       = 58
758         R_390_GOTPLT20    = 59
759         R_390_TLS_GOTIE20 = 60
760
761         ARM_MAGIC_TRAMP_NUMBER = 0x5c000003
762 )
763
764 /*
765  * Symbol table entries.
766  */
767
768 /* For accessing the fields of st_info. */
769
770 /* For constructing st_info from field values. */
771
772 /* For accessing the fields of st_other. */
773
774 /*
775  * ELF header.
776  */
777 type ElfEhdr struct {
778         ident     [EI_NIDENT]uint8
779         type_     uint16
780         machine   uint16
781         version   uint32
782         entry     uint64
783         phoff     uint64
784         shoff     uint64
785         flags     uint32
786         ehsize    uint16
787         phentsize uint16
788         phnum     uint16
789         shentsize uint16
790         shnum     uint16
791         shstrndx  uint16
792 }
793
794 /*
795  * Section header.
796  */
797 type ElfShdr struct {
798         name      uint32
799         type_     uint32
800         flags     uint64
801         addr      uint64
802         off       uint64
803         size      uint64
804         link      uint32
805         info      uint32
806         addralign uint64
807         entsize   uint64
808         shnum     int
809         secsym    *LSym
810 }
811
812 /*
813  * Program header.
814  */
815 type ElfPhdr struct {
816         type_  uint32
817         flags  uint32
818         off    uint64
819         vaddr  uint64
820         paddr  uint64
821         filesz uint64
822         memsz  uint64
823         align  uint64
824 }
825
826 /* For accessing the fields of r_info. */
827
828 /* For constructing r_info from field values. */
829
830 /*
831  * Symbol table entries.
832  */
833
834 /* For accessing the fields of st_info. */
835
836 /* For constructing st_info from field values. */
837
838 /* For accessing the fields of st_other. */
839
840 /*
841  * Go linker interface
842  */
843 const (
844         ELF64HDRSIZE  = 64
845         ELF64PHDRSIZE = 56
846         ELF64SHDRSIZE = 64
847         ELF64RELSIZE  = 16
848         ELF64RELASIZE = 24
849         ELF64SYMSIZE  = 24
850         ELF32HDRSIZE  = 52
851         ELF32PHDRSIZE = 32
852         ELF32SHDRSIZE = 40
853         ELF32SYMSIZE  = 16
854         ELF32RELSIZE  = 8
855 )
856
857 /*
858  * The interface uses the 64-bit structures always,
859  * to avoid code duplication.  The writers know how to
860  * marshal a 32-bit representation from the 64-bit structure.
861  */
862
863 var Elfstrdat []byte
864
865 /*
866  * Total amount of space to reserve at the start of the file
867  * for Header, PHeaders, SHeaders, and interp.
868  * May waste some.
869  * On FreeBSD, cannot be larger than a page.
870  */
871 const (
872         ELFRESERVE = 4096
873 )
874
875 /*
876  * We use the 64-bit data structures on both 32- and 64-bit machines
877  * in order to write the code just once.  The 64-bit data structure is
878  * written in the 32-bit format on the 32-bit machines.
879  */
880 const (
881         NSECT = 48
882 )
883
884 var (
885         Iself bool
886
887         Nelfsym int = 1
888
889         elf64 bool
890         // Either ".rel" or ".rela" depending on which type of relocation the
891         // target platform uses.
892         elfRelType string
893
894         ehdr ElfEhdr
895         phdr [NSECT]*ElfPhdr
896         shdr [NSECT]*ElfShdr
897
898         interp string
899 )
900
901 type Elfstring struct {
902         s   string
903         off int
904 }
905
906 var elfstr [100]Elfstring
907
908 var nelfstr int
909
910 var buildinfo []byte
911
912 /*
913  Initialize the global variable that describes the ELF header. It will be updated as
914  we write section and prog headers.
915 */
916 func Elfinit() {
917         Iself = true
918
919         if SysArch.InFamily(sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.S390X) {
920                 elfRelType = ".rela"
921         } else {
922                 elfRelType = ".rel"
923         }
924
925         switch SysArch.Family {
926         // 64-bit architectures
927         case sys.PPC64, sys.S390X:
928                 if Ctxt.Arch.ByteOrder == binary.BigEndian {
929                         ehdr.flags = 1 /* Version 1 ABI */
930                 } else {
931                         ehdr.flags = 2 /* Version 2 ABI */
932                 }
933                 fallthrough
934         case sys.AMD64, sys.ARM64, sys.MIPS64:
935                 if SysArch.Family == sys.MIPS64 {
936                         ehdr.flags = 0x20000000 /* MIPS 3 */
937                 }
938                 elf64 = true
939
940                 ehdr.phoff = ELF64HDRSIZE      /* Must be be ELF64HDRSIZE: first PHdr must follow ELF header */
941                 ehdr.shoff = ELF64HDRSIZE      /* Will move as we add PHeaders */
942                 ehdr.ehsize = ELF64HDRSIZE     /* Must be ELF64HDRSIZE */
943                 ehdr.phentsize = ELF64PHDRSIZE /* Must be ELF64PHDRSIZE */
944                 ehdr.shentsize = ELF64SHDRSIZE /* Must be ELF64SHDRSIZE */
945
946         // we use EABI on both linux/arm and freebsd/arm.
947         // 32-bit architectures
948         case sys.ARM:
949                 // we use EABI on both linux/arm and freebsd/arm.
950                 if HEADTYPE == obj.Hlinux || HEADTYPE == obj.Hfreebsd {
951                         // We set a value here that makes no indication of which
952                         // float ABI the object uses, because this is information
953                         // used by the dynamic linker to compare executables and
954                         // shared libraries -- so it only matters for cgo calls, and
955                         // the information properly comes from the object files
956                         // produced by the host C compiler. parseArmAttributes in
957                         // ldelf.go reads that information and updates this field as
958                         // appropriate.
959                         ehdr.flags = 0x5000002 // has entry point, Version5 EABI
960                 }
961                 fallthrough
962         default:
963                 ehdr.phoff = ELF32HDRSIZE
964                 /* Must be be ELF32HDRSIZE: first PHdr must follow ELF header */
965                 ehdr.shoff = ELF32HDRSIZE      /* Will move as we add PHeaders */
966                 ehdr.ehsize = ELF32HDRSIZE     /* Must be ELF32HDRSIZE */
967                 ehdr.phentsize = ELF32PHDRSIZE /* Must be ELF32PHDRSIZE */
968                 ehdr.shentsize = ELF32SHDRSIZE /* Must be ELF32SHDRSIZE */
969         }
970 }
971
972 // Make sure PT_LOAD is aligned properly and
973 // that there is no gap,
974 // correct ELF loaders will do this implicitly,
975 // but buggy ELF loaders like the one in some
976 // versions of QEMU and UPX won't.
977 func fixElfPhdr(e *ElfPhdr) {
978         frag := int(e.vaddr & (e.align - 1))
979
980         e.off -= uint64(frag)
981         e.vaddr -= uint64(frag)
982         e.paddr -= uint64(frag)
983         e.filesz += uint64(frag)
984         e.memsz += uint64(frag)
985 }
986
987 func elf64phdr(e *ElfPhdr) {
988         if e.type_ == PT_LOAD {
989                 fixElfPhdr(e)
990         }
991
992         Thearch.Lput(e.type_)
993         Thearch.Lput(e.flags)
994         Thearch.Vput(e.off)
995         Thearch.Vput(e.vaddr)
996         Thearch.Vput(e.paddr)
997         Thearch.Vput(e.filesz)
998         Thearch.Vput(e.memsz)
999         Thearch.Vput(e.align)
1000 }
1001
1002 func elf32phdr(e *ElfPhdr) {
1003         if e.type_ == PT_LOAD {
1004                 fixElfPhdr(e)
1005         }
1006
1007         Thearch.Lput(e.type_)
1008         Thearch.Lput(uint32(e.off))
1009         Thearch.Lput(uint32(e.vaddr))
1010         Thearch.Lput(uint32(e.paddr))
1011         Thearch.Lput(uint32(e.filesz))
1012         Thearch.Lput(uint32(e.memsz))
1013         Thearch.Lput(e.flags)
1014         Thearch.Lput(uint32(e.align))
1015 }
1016
1017 func elf64shdr(e *ElfShdr) {
1018         Thearch.Lput(e.name)
1019         Thearch.Lput(e.type_)
1020         Thearch.Vput(e.flags)
1021         Thearch.Vput(e.addr)
1022         Thearch.Vput(e.off)
1023         Thearch.Vput(e.size)
1024         Thearch.Lput(e.link)
1025         Thearch.Lput(e.info)
1026         Thearch.Vput(e.addralign)
1027         Thearch.Vput(e.entsize)
1028 }
1029
1030 func elf32shdr(e *ElfShdr) {
1031         Thearch.Lput(e.name)
1032         Thearch.Lput(e.type_)
1033         Thearch.Lput(uint32(e.flags))
1034         Thearch.Lput(uint32(e.addr))
1035         Thearch.Lput(uint32(e.off))
1036         Thearch.Lput(uint32(e.size))
1037         Thearch.Lput(e.link)
1038         Thearch.Lput(e.info)
1039         Thearch.Lput(uint32(e.addralign))
1040         Thearch.Lput(uint32(e.entsize))
1041 }
1042
1043 func elfwriteshdrs() uint32 {
1044         if elf64 {
1045                 for i := 0; i < int(ehdr.shnum); i++ {
1046                         elf64shdr(shdr[i])
1047                 }
1048                 return uint32(ehdr.shnum) * ELF64SHDRSIZE
1049         }
1050
1051         for i := 0; i < int(ehdr.shnum); i++ {
1052                 elf32shdr(shdr[i])
1053         }
1054         return uint32(ehdr.shnum) * ELF32SHDRSIZE
1055 }
1056
1057 func elfsetstring(s string, off int) {
1058         if nelfstr >= len(elfstr) {
1059                 Diag("too many elf strings")
1060                 errorexit()
1061         }
1062
1063         elfstr[nelfstr].s = s
1064         elfstr[nelfstr].off = off
1065         nelfstr++
1066 }
1067
1068 func elfwritephdrs() uint32 {
1069         if elf64 {
1070                 for i := 0; i < int(ehdr.phnum); i++ {
1071                         elf64phdr(phdr[i])
1072                 }
1073                 return uint32(ehdr.phnum) * ELF64PHDRSIZE
1074         }
1075
1076         for i := 0; i < int(ehdr.phnum); i++ {
1077                 elf32phdr(phdr[i])
1078         }
1079         return uint32(ehdr.phnum) * ELF32PHDRSIZE
1080 }
1081
1082 func newElfPhdr() *ElfPhdr {
1083         e := new(ElfPhdr)
1084         if ehdr.phnum >= NSECT {
1085                 Diag("too many phdrs")
1086         } else {
1087                 phdr[ehdr.phnum] = e
1088                 ehdr.phnum++
1089         }
1090         if elf64 {
1091                 ehdr.shoff += ELF64PHDRSIZE
1092         } else {
1093                 ehdr.shoff += ELF32PHDRSIZE
1094         }
1095         return e
1096 }
1097
1098 func newElfShdr(name int64) *ElfShdr {
1099         e := new(ElfShdr)
1100         e.name = uint32(name)
1101         e.shnum = int(ehdr.shnum)
1102         if ehdr.shnum >= NSECT {
1103                 Diag("too many shdrs")
1104         } else {
1105                 shdr[ehdr.shnum] = e
1106                 ehdr.shnum++
1107         }
1108
1109         return e
1110 }
1111
1112 func getElfEhdr() *ElfEhdr {
1113         return &ehdr
1114 }
1115
1116 func elf64writehdr() uint32 {
1117         for i := 0; i < EI_NIDENT; i++ {
1118                 Cput(ehdr.ident[i])
1119         }
1120         Thearch.Wput(ehdr.type_)
1121         Thearch.Wput(ehdr.machine)
1122         Thearch.Lput(ehdr.version)
1123         Thearch.Vput(ehdr.entry)
1124         Thearch.Vput(ehdr.phoff)
1125         Thearch.Vput(ehdr.shoff)
1126         Thearch.Lput(ehdr.flags)
1127         Thearch.Wput(ehdr.ehsize)
1128         Thearch.Wput(ehdr.phentsize)
1129         Thearch.Wput(ehdr.phnum)
1130         Thearch.Wput(ehdr.shentsize)
1131         Thearch.Wput(ehdr.shnum)
1132         Thearch.Wput(ehdr.shstrndx)
1133         return ELF64HDRSIZE
1134 }
1135
1136 func elf32writehdr() uint32 {
1137         for i := 0; i < EI_NIDENT; i++ {
1138                 Cput(ehdr.ident[i])
1139         }
1140         Thearch.Wput(ehdr.type_)
1141         Thearch.Wput(ehdr.machine)
1142         Thearch.Lput(ehdr.version)
1143         Thearch.Lput(uint32(ehdr.entry))
1144         Thearch.Lput(uint32(ehdr.phoff))
1145         Thearch.Lput(uint32(ehdr.shoff))
1146         Thearch.Lput(ehdr.flags)
1147         Thearch.Wput(ehdr.ehsize)
1148         Thearch.Wput(ehdr.phentsize)
1149         Thearch.Wput(ehdr.phnum)
1150         Thearch.Wput(ehdr.shentsize)
1151         Thearch.Wput(ehdr.shnum)
1152         Thearch.Wput(ehdr.shstrndx)
1153         return ELF32HDRSIZE
1154 }
1155
1156 func elfwritehdr() uint32 {
1157         if elf64 {
1158                 return elf64writehdr()
1159         }
1160         return elf32writehdr()
1161 }
1162
1163 /* Taken directly from the definition document for ELF64 */
1164 func elfhash(name string) uint32 {
1165         var h uint32
1166         for i := 0; i < len(name); i++ {
1167                 h = (h << 4) + uint32(name[i])
1168                 if g := h & 0xf0000000; g != 0 {
1169                         h ^= g >> 24
1170                 }
1171                 h &= 0x0fffffff
1172         }
1173         return h
1174 }
1175
1176 func Elfwritedynent(s *LSym, tag int, val uint64) {
1177         if elf64 {
1178                 Adduint64(Ctxt, s, uint64(tag))
1179                 Adduint64(Ctxt, s, val)
1180         } else {
1181                 Adduint32(Ctxt, s, uint32(tag))
1182                 Adduint32(Ctxt, s, uint32(val))
1183         }
1184 }
1185
1186 func elfwritedynentsym(s *LSym, tag int, t *LSym) {
1187         Elfwritedynentsymplus(s, tag, t, 0)
1188 }
1189
1190 func Elfwritedynentsymplus(s *LSym, tag int, t *LSym, add int64) {
1191         if elf64 {
1192                 Adduint64(Ctxt, s, uint64(tag))
1193         } else {
1194                 Adduint32(Ctxt, s, uint32(tag))
1195         }
1196         Addaddrplus(Ctxt, s, t, add)
1197 }
1198
1199 func elfwritedynentsymsize(s *LSym, tag int, t *LSym) {
1200         if elf64 {
1201                 Adduint64(Ctxt, s, uint64(tag))
1202         } else {
1203                 Adduint32(Ctxt, s, uint32(tag))
1204         }
1205         addsize(Ctxt, s, t)
1206 }
1207
1208 func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int {
1209         interp = p
1210         n := len(interp) + 1
1211         sh.addr = startva + resoff - uint64(n)
1212         sh.off = resoff - uint64(n)
1213         sh.size = uint64(n)
1214
1215         return n
1216 }
1217
1218 func elfwriteinterp() int {
1219         sh := elfshname(".interp")
1220         Cseek(int64(sh.off))
1221         coutbuf.WriteString(interp)
1222         Cput(0)
1223         return int(sh.size)
1224 }
1225
1226 func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int, alloc bool) int {
1227         n := 3*4 + uint64(sz) + resoff%4
1228
1229         sh.type_ = SHT_NOTE
1230         if alloc {
1231                 sh.flags = SHF_ALLOC
1232         }
1233         sh.addralign = 4
1234         sh.addr = startva + resoff - n
1235         sh.off = resoff - n
1236         sh.size = n - resoff%4
1237
1238         return int(n)
1239 }
1240
1241 func elfwritenotehdr(str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr {
1242         sh := elfshname(str)
1243
1244         // Write Elf_Note header.
1245         Cseek(int64(sh.off))
1246
1247         Thearch.Lput(namesz)
1248         Thearch.Lput(descsz)
1249         Thearch.Lput(tag)
1250
1251         return sh
1252 }
1253
1254 // NetBSD Signature (as per sys/exec_elf.h)
1255 const (
1256         ELF_NOTE_NETBSD_NAMESZ  = 7
1257         ELF_NOTE_NETBSD_DESCSZ  = 4
1258         ELF_NOTE_NETBSD_TAG     = 1
1259         ELF_NOTE_NETBSD_VERSION = 599000000 /* NetBSD 5.99 */
1260 )
1261
1262 var ELF_NOTE_NETBSD_NAME = []byte("NetBSD\x00")
1263
1264 func elfnetbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
1265         n := int(Rnd(ELF_NOTE_NETBSD_NAMESZ, 4) + Rnd(ELF_NOTE_NETBSD_DESCSZ, 4))
1266         return elfnote(sh, startva, resoff, n, true)
1267 }
1268
1269 func elfwritenetbsdsig() int {
1270         // Write Elf_Note header.
1271         sh := elfwritenotehdr(".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG)
1272
1273         if sh == nil {
1274                 return 0
1275         }
1276
1277         // Followed by NetBSD string and version.
1278         Cwrite(ELF_NOTE_NETBSD_NAME)
1279         Cput(0)
1280
1281         Thearch.Lput(ELF_NOTE_NETBSD_VERSION)
1282
1283         return int(sh.size)
1284 }
1285
1286 // OpenBSD Signature
1287 const (
1288         ELF_NOTE_OPENBSD_NAMESZ  = 8
1289         ELF_NOTE_OPENBSD_DESCSZ  = 4
1290         ELF_NOTE_OPENBSD_TAG     = 1
1291         ELF_NOTE_OPENBSD_VERSION = 0
1292 )
1293
1294 var ELF_NOTE_OPENBSD_NAME = []byte("OpenBSD\x00")
1295
1296 func elfopenbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
1297         n := ELF_NOTE_OPENBSD_NAMESZ + ELF_NOTE_OPENBSD_DESCSZ
1298         return elfnote(sh, startva, resoff, n, true)
1299 }
1300
1301 func elfwriteopenbsdsig() int {
1302         // Write Elf_Note header.
1303         sh := elfwritenotehdr(".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG)
1304
1305         if sh == nil {
1306                 return 0
1307         }
1308
1309         // Followed by OpenBSD string and version.
1310         Cwrite(ELF_NOTE_OPENBSD_NAME)
1311
1312         Thearch.Lput(ELF_NOTE_OPENBSD_VERSION)
1313
1314         return int(sh.size)
1315 }
1316
1317 func addbuildinfo(val string) {
1318         if !strings.HasPrefix(val, "0x") {
1319                 Exitf("-B argument must start with 0x: %s", val)
1320         }
1321
1322         ov := val
1323         val = val[2:]
1324
1325         const maxLen = 32
1326         if hex.DecodedLen(len(val)) > maxLen {
1327                 Exitf("-B option too long (max %d digits): %s", maxLen, ov)
1328         }
1329
1330         b, err := hex.DecodeString(val)
1331         if err != nil {
1332                 if err == hex.ErrLength {
1333                         Exitf("-B argument must have even number of digits: %s", ov)
1334                 }
1335                 if inv, ok := err.(hex.InvalidByteError); ok {
1336                         Exitf("-B argument contains invalid hex digit %c: %s", byte(inv), ov)
1337                 }
1338                 Exitf("-B argument contains invalid hex: %s", ov)
1339         }
1340
1341         buildinfo = b
1342 }
1343
1344 // Build info note
1345 const (
1346         ELF_NOTE_BUILDINFO_NAMESZ = 4
1347         ELF_NOTE_BUILDINFO_TAG    = 3
1348 )
1349
1350 var ELF_NOTE_BUILDINFO_NAME = []byte("GNU\x00")
1351
1352 func elfbuildinfo(sh *ElfShdr, startva uint64, resoff uint64) int {
1353         n := int(ELF_NOTE_BUILDINFO_NAMESZ + Rnd(int64(len(buildinfo)), 4))
1354         return elfnote(sh, startva, resoff, n, true)
1355 }
1356
1357 func elfgobuildid(sh *ElfShdr, startva uint64, resoff uint64) int {
1358         n := len(ELF_NOTE_GO_NAME) + int(Rnd(int64(len(buildid)), 4))
1359         return elfnote(sh, startva, resoff, n, true)
1360 }
1361
1362 func elfwritebuildinfo() int {
1363         sh := elfwritenotehdr(".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG)
1364         if sh == nil {
1365                 return 0
1366         }
1367
1368         Cwrite(ELF_NOTE_BUILDINFO_NAME)
1369         Cwrite(buildinfo)
1370         var zero = make([]byte, 4)
1371         Cwrite(zero[:int(Rnd(int64(len(buildinfo)), 4)-int64(len(buildinfo)))])
1372
1373         return int(sh.size)
1374 }
1375
1376 func elfwritegobuildid() int {
1377         sh := elfwritenotehdr(".note.go.buildid", uint32(len(ELF_NOTE_GO_NAME)), uint32(len(buildid)), ELF_NOTE_GOBUILDID_TAG)
1378         if sh == nil {
1379                 return 0
1380         }
1381
1382         Cwrite(ELF_NOTE_GO_NAME)
1383         Cwrite([]byte(buildid))
1384         var zero = make([]byte, 4)
1385         Cwrite(zero[:int(Rnd(int64(len(buildid)), 4)-int64(len(buildid)))])
1386
1387         return int(sh.size)
1388 }
1389
1390 // Go specific notes
1391 const (
1392         ELF_NOTE_GOPKGLIST_TAG = 1
1393         ELF_NOTE_GOABIHASH_TAG = 2
1394         ELF_NOTE_GODEPS_TAG    = 3
1395         ELF_NOTE_GOBUILDID_TAG = 4
1396 )
1397
1398 var ELF_NOTE_GO_NAME = []byte("Go\x00\x00")
1399
1400 var elfverneed int
1401
1402 type Elfaux struct {
1403         next *Elfaux
1404         num  int
1405         vers string
1406 }
1407
1408 type Elflib struct {
1409         next *Elflib
1410         aux  *Elfaux
1411         file string
1412 }
1413
1414 func addelflib(list **Elflib, file string, vers string) *Elfaux {
1415         var lib *Elflib
1416
1417         for lib = *list; lib != nil; lib = lib.next {
1418                 if lib.file == file {
1419                         goto havelib
1420                 }
1421         }
1422         lib = new(Elflib)
1423         lib.next = *list
1424         lib.file = file
1425         *list = lib
1426
1427 havelib:
1428         for aux := lib.aux; aux != nil; aux = aux.next {
1429                 if aux.vers == vers {
1430                         return aux
1431                 }
1432         }
1433         aux := new(Elfaux)
1434         aux.next = lib.aux
1435         aux.vers = vers
1436         lib.aux = aux
1437
1438         return aux
1439 }
1440
1441 func elfdynhash() {
1442         if !Iself {
1443                 return
1444         }
1445
1446         nsym := Nelfsym
1447         s := Linklookup(Ctxt, ".hash", 0)
1448         s.Type = obj.SELFROSECT
1449         s.Attr |= AttrReachable
1450
1451         i := nsym
1452         nbucket := 1
1453         for i > 0 {
1454                 nbucket++
1455                 i >>= 1
1456         }
1457
1458         var needlib *Elflib
1459         need := make([]*Elfaux, nsym)
1460         chain := make([]uint32, nsym)
1461         buckets := make([]uint32, nbucket)
1462
1463         var b int
1464         for _, sy := range Ctxt.Allsym {
1465                 if sy.Dynid <= 0 {
1466                         continue
1467                 }
1468
1469                 if sy.Dynimpvers != "" {
1470                         need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib, sy.Dynimpvers)
1471                 }
1472
1473                 name := sy.Extname
1474                 hc := elfhash(name)
1475
1476                 b = int(hc % uint32(nbucket))
1477                 chain[sy.Dynid] = buckets[b]
1478                 buckets[b] = uint32(sy.Dynid)
1479         }
1480
1481         // s390x (ELF64) hash table entries are 8 bytes
1482         if SysArch.Family == sys.S390X {
1483                 Adduint64(Ctxt, s, uint64(nbucket))
1484                 Adduint64(Ctxt, s, uint64(nsym))
1485                 for i := 0; i < nbucket; i++ {
1486                         Adduint64(Ctxt, s, uint64(buckets[i]))
1487                 }
1488                 for i := 0; i < nsym; i++ {
1489                         Adduint64(Ctxt, s, uint64(chain[i]))
1490                 }
1491         } else {
1492                 Adduint32(Ctxt, s, uint32(nbucket))
1493                 Adduint32(Ctxt, s, uint32(nsym))
1494                 for i := 0; i < nbucket; i++ {
1495                         Adduint32(Ctxt, s, buckets[i])
1496                 }
1497                 for i := 0; i < nsym; i++ {
1498                         Adduint32(Ctxt, s, chain[i])
1499                 }
1500         }
1501
1502         // version symbols
1503         dynstr := Linklookup(Ctxt, ".dynstr", 0)
1504
1505         s = Linklookup(Ctxt, ".gnu.version_r", 0)
1506         i = 2
1507         nfile := 0
1508         var j int
1509         var x *Elfaux
1510         for l := needlib; l != nil; l = l.next {
1511                 nfile++
1512
1513                 // header
1514                 Adduint16(Ctxt, s, 1) // table version
1515                 j = 0
1516                 for x = l.aux; x != nil; x = x.next {
1517                         j++
1518                 }
1519                 Adduint16(Ctxt, s, uint16(j))                         // aux count
1520                 Adduint32(Ctxt, s, uint32(Addstring(dynstr, l.file))) // file string offset
1521                 Adduint32(Ctxt, s, 16)                                // offset from header to first aux
1522                 if l.next != nil {
1523                         Adduint32(Ctxt, s, 16+uint32(j)*16) // offset from this header to next
1524                 } else {
1525                         Adduint32(Ctxt, s, 0)
1526                 }
1527
1528                 for x = l.aux; x != nil; x = x.next {
1529                         x.num = i
1530                         i++
1531
1532                         // aux struct
1533                         Adduint32(Ctxt, s, elfhash(x.vers))                   // hash
1534                         Adduint16(Ctxt, s, 0)                                 // flags
1535                         Adduint16(Ctxt, s, uint16(x.num))                     // other - index we refer to this by
1536                         Adduint32(Ctxt, s, uint32(Addstring(dynstr, x.vers))) // version string offset
1537                         if x.next != nil {
1538                                 Adduint32(Ctxt, s, 16) // offset from this aux to next
1539                         } else {
1540                                 Adduint32(Ctxt, s, 0)
1541                         }
1542                 }
1543         }
1544
1545         // version references
1546         s = Linklookup(Ctxt, ".gnu.version", 0)
1547
1548         for i := 0; i < nsym; i++ {
1549                 if i == 0 {
1550                         Adduint16(Ctxt, s, 0) // first entry - no symbol
1551                 } else if need[i] == nil {
1552                         Adduint16(Ctxt, s, 1) // global
1553                 } else {
1554                         Adduint16(Ctxt, s, uint16(need[i].num))
1555                 }
1556         }
1557
1558         s = Linklookup(Ctxt, ".dynamic", 0)
1559         elfverneed = nfile
1560         if elfverneed != 0 {
1561                 elfwritedynentsym(s, DT_VERNEED, Linklookup(Ctxt, ".gnu.version_r", 0))
1562                 Elfwritedynent(s, DT_VERNEEDNUM, uint64(nfile))
1563                 elfwritedynentsym(s, DT_VERSYM, Linklookup(Ctxt, ".gnu.version", 0))
1564         }
1565
1566         sy := Linklookup(Ctxt, elfRelType+".plt", 0)
1567         if sy.Size > 0 {
1568                 if elfRelType == ".rela" {
1569                         Elfwritedynent(s, DT_PLTREL, DT_RELA)
1570                 } else {
1571                         Elfwritedynent(s, DT_PLTREL, DT_REL)
1572                 }
1573                 elfwritedynentsymsize(s, DT_PLTRELSZ, sy)
1574                 elfwritedynentsym(s, DT_JMPREL, sy)
1575         }
1576
1577         Elfwritedynent(s, DT_NULL, 0)
1578 }
1579
1580 func elfphload(seg *Segment) *ElfPhdr {
1581         ph := newElfPhdr()
1582         ph.type_ = PT_LOAD
1583         if seg.Rwx&4 != 0 {
1584                 ph.flags |= PF_R
1585         }
1586         if seg.Rwx&2 != 0 {
1587                 ph.flags |= PF_W
1588         }
1589         if seg.Rwx&1 != 0 {
1590                 ph.flags |= PF_X
1591         }
1592         ph.vaddr = seg.Vaddr
1593         ph.paddr = seg.Vaddr
1594         ph.memsz = seg.Length
1595         ph.off = seg.Fileoff
1596         ph.filesz = seg.Filelen
1597         ph.align = uint64(INITRND)
1598
1599         return ph
1600 }
1601
1602 func elfshname(name string) *ElfShdr {
1603         var off int
1604         var sh *ElfShdr
1605
1606         for i := 0; i < nelfstr; i++ {
1607                 if name == elfstr[i].s {
1608                         off = elfstr[i].off
1609                         for i = 0; i < int(ehdr.shnum); i++ {
1610                                 sh = shdr[i]
1611                                 if sh.name == uint32(off) {
1612                                         return sh
1613                                 }
1614                         }
1615
1616                         sh = newElfShdr(int64(off))
1617                         return sh
1618                 }
1619         }
1620
1621         Diag("cannot find elf name %s", name)
1622         errorexit()
1623         return nil
1624 }
1625
1626 func elfshalloc(sect *Section) *ElfShdr {
1627         sh := elfshname(sect.Name)
1628         sect.Elfsect = sh
1629         return sh
1630 }
1631
1632 func elfshbits(sect *Section) *ElfShdr {
1633         sh := elfshalloc(sect)
1634         // If this section has already been set up as a note, we assume type_ and
1635         // flags are already correct, but the other fields still need filling in.
1636         if sh.type_ == SHT_NOTE {
1637                 if Linkmode != LinkExternal {
1638                         // TODO(mwhudson): the approach here will work OK when
1639                         // linking internally for notes that we want to be included
1640                         // in a loadable segment (e.g. the abihash note) but not for
1641                         // notes that we do not want to be mapped (e.g. the package
1642                         // list note). The real fix is probably to define new values
1643                         // for LSym.Type corresponding to mapped and unmapped notes
1644                         // and handle them in dodata().
1645                         Diag("sh.type_ == SHT_NOTE in elfshbits when linking internally")
1646                 }
1647                 sh.addralign = uint64(sect.Align)
1648                 sh.size = sect.Length
1649                 sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
1650                 return sh
1651         }
1652         if sh.type_ > 0 {
1653                 return sh
1654         }
1655
1656         if sect.Vaddr < sect.Seg.Vaddr+sect.Seg.Filelen {
1657                 sh.type_ = SHT_PROGBITS
1658         } else {
1659                 sh.type_ = SHT_NOBITS
1660         }
1661         sh.flags = SHF_ALLOC
1662         if sect.Rwx&1 != 0 {
1663                 sh.flags |= SHF_EXECINSTR
1664         }
1665         if sect.Rwx&2 != 0 {
1666                 sh.flags |= SHF_WRITE
1667         }
1668         if sect.Name == ".tbss" {
1669                 sh.flags |= SHF_TLS
1670                 sh.type_ = SHT_NOBITS
1671         }
1672         if strings.HasPrefix(sect.Name, ".debug") {
1673                 sh.flags = 0
1674         }
1675
1676         if Linkmode != LinkExternal {
1677                 sh.addr = sect.Vaddr
1678         }
1679         sh.addralign = uint64(sect.Align)
1680         sh.size = sect.Length
1681         if sect.Name != ".tbss" {
1682                 sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
1683         }
1684
1685         return sh
1686 }
1687
1688 func elfshreloc(sect *Section) *ElfShdr {
1689         // If main section is SHT_NOBITS, nothing to relocate.
1690         // Also nothing to relocate in .shstrtab or notes.
1691         if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
1692                 return nil
1693         }
1694         if sect.Name == ".shstrtab" || sect.Name == ".tbss" {
1695                 return nil
1696         }
1697         if sect.Elfsect.type_ == SHT_NOTE {
1698                 return nil
1699         }
1700
1701         var typ int
1702         if elfRelType == ".rela" {
1703                 typ = SHT_RELA
1704         } else {
1705                 typ = SHT_REL
1706         }
1707
1708         sh := elfshname(elfRelType + sect.Name)
1709         sh.type_ = uint32(typ)
1710         sh.entsize = uint64(SysArch.RegSize) * 2
1711         if typ == SHT_RELA {
1712                 sh.entsize += uint64(SysArch.RegSize)
1713         }
1714         sh.link = uint32(elfshname(".symtab").shnum)
1715         sh.info = uint32(sect.Elfsect.shnum)
1716         sh.off = sect.Reloff
1717         sh.size = sect.Rellen
1718         sh.addralign = uint64(SysArch.RegSize)
1719         return sh
1720 }
1721
1722 func elfrelocsect(sect *Section, syms []*LSym) {
1723         // If main section is SHT_NOBITS, nothing to relocate.
1724         // Also nothing to relocate in .shstrtab.
1725         if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
1726                 return
1727         }
1728         if sect.Name == ".shstrtab" {
1729                 return
1730         }
1731
1732         sect.Reloff = uint64(Cpos())
1733         for i, s := range syms {
1734                 if !s.Attr.Reachable() {
1735                         continue
1736                 }
1737                 if uint64(s.Value) >= sect.Vaddr {
1738                         syms = syms[i:]
1739                         break
1740                 }
1741         }
1742
1743         eaddr := int32(sect.Vaddr + sect.Length)
1744         for _, sym := range syms {
1745                 if !sym.Attr.Reachable() {
1746                         continue
1747                 }
1748                 if sym.Value >= int64(eaddr) {
1749                         break
1750                 }
1751                 Ctxt.Cursym = sym
1752
1753                 for ri := 0; ri < len(sym.R); ri++ {
1754                         r := &sym.R[ri]
1755                         if r.Done != 0 {
1756                                 continue
1757                         }
1758                         if r.Xsym == nil {
1759                                 Diag("missing xsym in relocation")
1760                                 continue
1761                         }
1762                         if r.Xsym.ElfsymForReloc() == 0 {
1763                                 Diag("reloc %d to non-elf symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type)
1764                         }
1765                         if Thearch.Elfreloc1(r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) < 0 {
1766                                 Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
1767                         }
1768                 }
1769         }
1770
1771         sect.Rellen = uint64(Cpos()) - sect.Reloff
1772 }
1773
1774 func Elfemitreloc() {
1775         for Cpos()&7 != 0 {
1776                 Cput(0)
1777         }
1778
1779         elfrelocsect(Segtext.Sect, Ctxt.Textp)
1780         for sect := Segtext.Sect.Next; sect != nil; sect = sect.Next {
1781                 elfrelocsect(sect, datap)
1782         }
1783         for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
1784                 elfrelocsect(sect, datap)
1785         }
1786         for sect := Segdata.Sect; sect != nil; sect = sect.Next {
1787                 elfrelocsect(sect, datap)
1788         }
1789         for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
1790                 elfrelocsect(sect, list2slice(dwarfp))
1791         }
1792 }
1793
1794 func addgonote(sectionName string, tag uint32, desc []byte) {
1795         s := Linklookup(Ctxt, sectionName, 0)
1796         s.Attr |= AttrReachable
1797         s.Type = obj.SELFROSECT
1798         // namesz
1799         Adduint32(Ctxt, s, uint32(len(ELF_NOTE_GO_NAME)))
1800         // descsz
1801         Adduint32(Ctxt, s, uint32(len(desc)))
1802         // tag
1803         Adduint32(Ctxt, s, tag)
1804         // name + padding
1805         s.P = append(s.P, ELF_NOTE_GO_NAME...)
1806         for len(s.P)%4 != 0 {
1807                 s.P = append(s.P, 0)
1808         }
1809         // desc + padding
1810         s.P = append(s.P, desc...)
1811         for len(s.P)%4 != 0 {
1812                 s.P = append(s.P, 0)
1813         }
1814         s.Size = int64(len(s.P))
1815 }
1816
1817 func doelf() {
1818         if !Iself {
1819                 return
1820         }
1821
1822         /* predefine strings we need for section headers */
1823         shstrtab := Linklookup(Ctxt, ".shstrtab", 0)
1824
1825         shstrtab.Type = obj.SELFROSECT
1826         shstrtab.Attr |= AttrReachable
1827
1828         Addstring(shstrtab, "")
1829         Addstring(shstrtab, ".text")
1830         Addstring(shstrtab, ".noptrdata")
1831         Addstring(shstrtab, ".data")
1832         Addstring(shstrtab, ".bss")
1833         Addstring(shstrtab, ".noptrbss")
1834
1835         // generate .tbss section (except for OpenBSD where it's not supported)
1836         // for dynamic internal linker or external linking, so that various
1837         // binutils could correctly calculate PT_TLS size.
1838         // see https://golang.org/issue/5200.
1839         if HEADTYPE != obj.Hopenbsd {
1840                 if Debug['d'] == 0 || Linkmode == LinkExternal {
1841                         Addstring(shstrtab, ".tbss")
1842                 }
1843         }
1844         if HEADTYPE == obj.Hnetbsd {
1845                 Addstring(shstrtab, ".note.netbsd.ident")
1846         }
1847         if HEADTYPE == obj.Hopenbsd {
1848                 Addstring(shstrtab, ".note.openbsd.ident")
1849         }
1850         if len(buildinfo) > 0 {
1851                 Addstring(shstrtab, ".note.gnu.build-id")
1852         }
1853         if buildid != "" {
1854                 Addstring(shstrtab, ".note.go.buildid")
1855         }
1856         Addstring(shstrtab, ".elfdata")
1857         Addstring(shstrtab, ".rodata")
1858         // See the comment about data.rel.ro.FOO section names in data.go.
1859         relro_prefix := ""
1860         if UseRelro() {
1861                 Addstring(shstrtab, ".data.rel.ro")
1862                 relro_prefix = ".data.rel.ro"
1863         }
1864         Addstring(shstrtab, relro_prefix+".typelink")
1865         Addstring(shstrtab, relro_prefix+".itablink")
1866         Addstring(shstrtab, relro_prefix+".gosymtab")
1867         Addstring(shstrtab, relro_prefix+".gopclntab")
1868
1869         if Linkmode == LinkExternal {
1870                 Debug['d'] = 1
1871
1872                 Addstring(shstrtab, elfRelType+".text")
1873                 Addstring(shstrtab, elfRelType+".rodata")
1874                 Addstring(shstrtab, elfRelType+relro_prefix+".typelink")
1875                 Addstring(shstrtab, elfRelType+relro_prefix+".itablink")
1876                 Addstring(shstrtab, elfRelType+relro_prefix+".gosymtab")
1877                 Addstring(shstrtab, elfRelType+relro_prefix+".gopclntab")
1878                 Addstring(shstrtab, elfRelType+".noptrdata")
1879                 Addstring(shstrtab, elfRelType+".data")
1880                 if UseRelro() {
1881                         Addstring(shstrtab, elfRelType+".data.rel.ro")
1882                 }
1883
1884                 // add a .note.GNU-stack section to mark the stack as non-executable
1885                 Addstring(shstrtab, ".note.GNU-stack")
1886
1887                 if Buildmode == BuildmodeShared {
1888                         Addstring(shstrtab, ".note.go.abihash")
1889                         Addstring(shstrtab, ".note.go.pkg-list")
1890                         Addstring(shstrtab, ".note.go.deps")
1891                 }
1892         }
1893
1894         hasinitarr := Linkshared
1895
1896         /* shared library initializer */
1897         switch Buildmode {
1898         case BuildmodeCArchive, BuildmodeCShared, BuildmodeShared:
1899                 hasinitarr = true
1900         }
1901
1902         if hasinitarr {
1903                 Addstring(shstrtab, ".init_array")
1904                 Addstring(shstrtab, elfRelType+".init_array")
1905         }
1906
1907         if Debug['s'] == 0 {
1908                 Addstring(shstrtab, ".symtab")
1909                 Addstring(shstrtab, ".strtab")
1910                 dwarfaddshstrings(shstrtab)
1911         }
1912
1913         Addstring(shstrtab, ".shstrtab")
1914
1915         if Debug['d'] == 0 { /* -d suppresses dynamic loader format */
1916                 Addstring(shstrtab, ".interp")
1917                 Addstring(shstrtab, ".hash")
1918                 Addstring(shstrtab, ".got")
1919                 if SysArch.Family == sys.PPC64 {
1920                         Addstring(shstrtab, ".glink")
1921                 }
1922                 Addstring(shstrtab, ".got.plt")
1923                 Addstring(shstrtab, ".dynamic")
1924                 Addstring(shstrtab, ".dynsym")
1925                 Addstring(shstrtab, ".dynstr")
1926                 Addstring(shstrtab, elfRelType)
1927                 Addstring(shstrtab, elfRelType+".plt")
1928
1929                 Addstring(shstrtab, ".plt")
1930                 Addstring(shstrtab, ".gnu.version")
1931                 Addstring(shstrtab, ".gnu.version_r")
1932
1933                 /* dynamic symbol table - first entry all zeros */
1934                 s := Linklookup(Ctxt, ".dynsym", 0)
1935
1936                 s.Type = obj.SELFROSECT
1937                 s.Attr |= AttrReachable
1938                 if elf64 {
1939                         s.Size += ELF64SYMSIZE
1940                 } else {
1941                         s.Size += ELF32SYMSIZE
1942                 }
1943
1944                 /* dynamic string table */
1945                 s = Linklookup(Ctxt, ".dynstr", 0)
1946
1947                 s.Type = obj.SELFROSECT
1948                 s.Attr |= AttrReachable
1949                 if s.Size == 0 {
1950                         Addstring(s, "")
1951                 }
1952                 dynstr := s
1953
1954                 /* relocation table */
1955                 s = Linklookup(Ctxt, elfRelType, 0)
1956                 s.Attr |= AttrReachable
1957                 s.Type = obj.SELFROSECT
1958
1959                 /* global offset table */
1960                 s = Linklookup(Ctxt, ".got", 0)
1961
1962                 s.Attr |= AttrReachable
1963                 s.Type = obj.SELFGOT // writable
1964
1965                 /* ppc64 glink resolver */
1966                 if SysArch.Family == sys.PPC64 {
1967                         s := Linklookup(Ctxt, ".glink", 0)
1968                         s.Attr |= AttrReachable
1969                         s.Type = obj.SELFRXSECT
1970                 }
1971
1972                 /* hash */
1973                 s = Linklookup(Ctxt, ".hash", 0)
1974
1975                 s.Attr |= AttrReachable
1976                 s.Type = obj.SELFROSECT
1977
1978                 s = Linklookup(Ctxt, ".got.plt", 0)
1979                 s.Attr |= AttrReachable
1980                 s.Type = obj.SELFSECT // writable
1981
1982                 s = Linklookup(Ctxt, ".plt", 0)
1983
1984                 s.Attr |= AttrReachable
1985                 if SysArch.Family == sys.PPC64 {
1986                         // In the ppc64 ABI, .plt is a data section
1987                         // written by the dynamic linker.
1988                         s.Type = obj.SELFSECT
1989                 } else {
1990                         s.Type = obj.SELFRXSECT
1991                 }
1992
1993                 Thearch.Elfsetupplt()
1994
1995                 s = Linklookup(Ctxt, elfRelType+".plt", 0)
1996                 s.Attr |= AttrReachable
1997                 s.Type = obj.SELFROSECT
1998
1999                 s = Linklookup(Ctxt, ".gnu.version", 0)
2000                 s.Attr |= AttrReachable
2001                 s.Type = obj.SELFROSECT
2002
2003                 s = Linklookup(Ctxt, ".gnu.version_r", 0)
2004                 s.Attr |= AttrReachable
2005                 s.Type = obj.SELFROSECT
2006
2007                 /* define dynamic elf table */
2008                 s = Linklookup(Ctxt, ".dynamic", 0)
2009
2010                 s.Attr |= AttrReachable
2011                 s.Type = obj.SELFSECT // writable
2012
2013                 /*
2014                  * .dynamic table
2015                  */
2016                 elfwritedynentsym(s, DT_HASH, Linklookup(Ctxt, ".hash", 0))
2017
2018                 elfwritedynentsym(s, DT_SYMTAB, Linklookup(Ctxt, ".dynsym", 0))
2019                 if elf64 {
2020                         Elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE)
2021                 } else {
2022                         Elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE)
2023                 }
2024                 elfwritedynentsym(s, DT_STRTAB, Linklookup(Ctxt, ".dynstr", 0))
2025                 elfwritedynentsymsize(s, DT_STRSZ, Linklookup(Ctxt, ".dynstr", 0))
2026                 if elfRelType == ".rela" {
2027                         elfwritedynentsym(s, DT_RELA, Linklookup(Ctxt, ".rela", 0))
2028                         elfwritedynentsymsize(s, DT_RELASZ, Linklookup(Ctxt, ".rela", 0))
2029                         Elfwritedynent(s, DT_RELAENT, ELF64RELASIZE)
2030                 } else {
2031                         elfwritedynentsym(s, DT_REL, Linklookup(Ctxt, ".rel", 0))
2032                         elfwritedynentsymsize(s, DT_RELSZ, Linklookup(Ctxt, ".rel", 0))
2033                         Elfwritedynent(s, DT_RELENT, ELF32RELSIZE)
2034                 }
2035
2036                 if rpath.val != "" {
2037                         Elfwritedynent(s, DT_RUNPATH, uint64(Addstring(dynstr, rpath.val)))
2038                 }
2039
2040                 if SysArch.Family == sys.PPC64 {
2041                         elfwritedynentsym(s, DT_PLTGOT, Linklookup(Ctxt, ".plt", 0))
2042                 } else if SysArch.Family == sys.S390X {
2043                         elfwritedynentsym(s, DT_PLTGOT, Linklookup(Ctxt, ".got", 0))
2044                 } else {
2045                         elfwritedynentsym(s, DT_PLTGOT, Linklookup(Ctxt, ".got.plt", 0))
2046                 }
2047
2048                 if SysArch.Family == sys.PPC64 {
2049                         Elfwritedynent(s, DT_PPC64_OPT, 0)
2050                 }
2051
2052                 // Solaris dynamic linker can't handle an empty .rela.plt if
2053                 // DT_JMPREL is emitted so we have to defer generation of DT_PLTREL,
2054                 // DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the
2055                 // size of .rel(a).plt section.
2056                 Elfwritedynent(s, DT_DEBUG, 0)
2057         }
2058
2059         if Buildmode == BuildmodeShared {
2060                 // The go.link.abihashbytes symbol will be pointed at the appropriate
2061                 // part of the .note.go.abihash section in data.go:func address().
2062                 s := Linklookup(Ctxt, "go.link.abihashbytes", 0)
2063                 s.Attr |= AttrLocal
2064                 s.Type = obj.SRODATA
2065                 s.Attr |= AttrSpecial
2066                 s.Attr |= AttrReachable
2067                 s.Size = int64(sha1.Size)
2068
2069                 sort.Sort(byPkg(Ctxt.Library))
2070                 h := sha1.New()
2071                 for _, l := range Ctxt.Library {
2072                         h.Write(l.hash)
2073                 }
2074                 addgonote(".note.go.abihash", ELF_NOTE_GOABIHASH_TAG, h.Sum([]byte{}))
2075                 addgonote(".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, pkglistfornote)
2076                 var deplist []string
2077                 for _, shlib := range Ctxt.Shlibs {
2078                         deplist = append(deplist, filepath.Base(shlib.Path))
2079                 }
2080                 addgonote(".note.go.deps", ELF_NOTE_GODEPS_TAG, []byte(strings.Join(deplist, "\n")))
2081         }
2082
2083         if Linkmode == LinkExternal && buildid != "" {
2084                 addgonote(".note.go.buildid", ELF_NOTE_GOBUILDID_TAG, []byte(buildid))
2085         }
2086 }
2087
2088 // Do not write DT_NULL.  elfdynhash will finish it.
2089 func shsym(sh *ElfShdr, s *LSym) {
2090         addr := Symaddr(s)
2091         if sh.flags&SHF_ALLOC != 0 {
2092                 sh.addr = uint64(addr)
2093         }
2094         sh.off = uint64(datoff(addr))
2095         sh.size = uint64(s.Size)
2096 }
2097
2098 func phsh(ph *ElfPhdr, sh *ElfShdr) {
2099         ph.vaddr = sh.addr
2100         ph.paddr = ph.vaddr
2101         ph.off = sh.off
2102         ph.filesz = sh.size
2103         ph.memsz = sh.size
2104         ph.align = sh.addralign
2105 }
2106
2107 func Asmbelfsetup() {
2108         /* This null SHdr must appear before all others */
2109         elfshname("")
2110
2111         for sect := Segtext.Sect; sect != nil; sect = sect.Next {
2112                 elfshalloc(sect)
2113         }
2114         for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
2115                 elfshalloc(sect)
2116         }
2117         for sect := Segdata.Sect; sect != nil; sect = sect.Next {
2118                 elfshalloc(sect)
2119         }
2120         for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
2121                 elfshalloc(sect)
2122         }
2123 }
2124
2125 func Asmbelf(symo int64) {
2126         eh := getElfEhdr()
2127         switch SysArch.Family {
2128         default:
2129                 Exitf("unknown architecture in asmbelf: %v", SysArch.Family)
2130         case sys.MIPS64:
2131                 eh.machine = EM_MIPS
2132         case sys.ARM:
2133                 eh.machine = EM_ARM
2134         case sys.AMD64:
2135                 eh.machine = EM_X86_64
2136         case sys.ARM64:
2137                 eh.machine = EM_AARCH64
2138         case sys.I386:
2139                 eh.machine = EM_386
2140         case sys.PPC64:
2141                 eh.machine = EM_PPC64
2142         case sys.S390X:
2143                 eh.machine = EM_S390
2144         }
2145
2146         elfreserve := int64(ELFRESERVE)
2147         startva := INITTEXT - int64(HEADR)
2148         resoff := elfreserve
2149
2150         var pph *ElfPhdr
2151         var pnote *ElfPhdr
2152         if Linkmode == LinkExternal {
2153                 /* skip program headers */
2154                 eh.phoff = 0
2155
2156                 eh.phentsize = 0
2157
2158                 if Buildmode == BuildmodeShared {
2159                         sh := elfshname(".note.go.pkg-list")
2160                         sh.type_ = SHT_NOTE
2161                         sh = elfshname(".note.go.abihash")
2162                         sh.type_ = SHT_NOTE
2163                         sh.flags = SHF_ALLOC
2164                         sh = elfshname(".note.go.deps")
2165                         sh.type_ = SHT_NOTE
2166                 }
2167
2168                 if buildid != "" {
2169                         sh := elfshname(".note.go.buildid")
2170                         sh.type_ = SHT_NOTE
2171                         sh.flags = SHF_ALLOC
2172                 }
2173
2174                 goto elfobj
2175         }
2176
2177         /* program header info */
2178         pph = newElfPhdr()
2179
2180         pph.type_ = PT_PHDR
2181         pph.flags = PF_R
2182         pph.off = uint64(eh.ehsize)
2183         pph.vaddr = uint64(INITTEXT) - uint64(HEADR) + pph.off
2184         pph.paddr = uint64(INITTEXT) - uint64(HEADR) + pph.off
2185         pph.align = uint64(INITRND)
2186
2187         /*
2188          * PHDR must be in a loaded segment. Adjust the text
2189          * segment boundaries downwards to include it.
2190          * Except on NaCl where it must not be loaded.
2191          */
2192         if HEADTYPE != obj.Hnacl {
2193                 o := int64(Segtext.Vaddr - pph.vaddr)
2194                 Segtext.Vaddr -= uint64(o)
2195                 Segtext.Length += uint64(o)
2196                 o = int64(Segtext.Fileoff - pph.off)
2197                 Segtext.Fileoff -= uint64(o)
2198                 Segtext.Filelen += uint64(o)
2199         }
2200
2201         if Debug['d'] == 0 { /* -d suppresses dynamic loader format */
2202                 /* interpreter */
2203                 sh := elfshname(".interp")
2204
2205                 sh.type_ = SHT_PROGBITS
2206                 sh.flags = SHF_ALLOC
2207                 sh.addralign = 1
2208                 if interpreter == "" {
2209                         switch HEADTYPE {
2210                         case obj.Hlinux:
2211                                 interpreter = Thearch.Linuxdynld
2212
2213                         case obj.Hfreebsd:
2214                                 interpreter = Thearch.Freebsddynld
2215
2216                         case obj.Hnetbsd:
2217                                 interpreter = Thearch.Netbsddynld
2218
2219                         case obj.Hopenbsd:
2220                                 interpreter = Thearch.Openbsddynld
2221
2222                         case obj.Hdragonfly:
2223                                 interpreter = Thearch.Dragonflydynld
2224
2225                         case obj.Hsolaris:
2226                                 interpreter = Thearch.Solarisdynld
2227                         }
2228                 }
2229
2230                 resoff -= int64(elfinterp(sh, uint64(startva), uint64(resoff), interpreter))
2231
2232                 ph := newElfPhdr()
2233                 ph.type_ = PT_INTERP
2234                 ph.flags = PF_R
2235                 phsh(ph, sh)
2236         }
2237
2238         pnote = nil
2239         if HEADTYPE == obj.Hnetbsd || HEADTYPE == obj.Hopenbsd {
2240                 var sh *ElfShdr
2241                 switch HEADTYPE {
2242                 case obj.Hnetbsd:
2243                         sh = elfshname(".note.netbsd.ident")
2244                         resoff -= int64(elfnetbsdsig(sh, uint64(startva), uint64(resoff)))
2245
2246                 case obj.Hopenbsd:
2247                         sh = elfshname(".note.openbsd.ident")
2248                         resoff -= int64(elfopenbsdsig(sh, uint64(startva), uint64(resoff)))
2249                 }
2250
2251                 pnote = newElfPhdr()
2252                 pnote.type_ = PT_NOTE
2253                 pnote.flags = PF_R
2254                 phsh(pnote, sh)
2255         }
2256
2257         if len(buildinfo) > 0 {
2258                 sh := elfshname(".note.gnu.build-id")
2259                 resoff -= int64(elfbuildinfo(sh, uint64(startva), uint64(resoff)))
2260
2261                 if pnote == nil {
2262                         pnote = newElfPhdr()
2263                         pnote.type_ = PT_NOTE
2264                         pnote.flags = PF_R
2265                 }
2266
2267                 phsh(pnote, sh)
2268         }
2269
2270         if buildid != "" {
2271                 sh := elfshname(".note.go.buildid")
2272                 resoff -= int64(elfgobuildid(sh, uint64(startva), uint64(resoff)))
2273
2274                 pnote := newElfPhdr()
2275                 pnote.type_ = PT_NOTE
2276                 pnote.flags = PF_R
2277                 phsh(pnote, sh)
2278         }
2279
2280         // Additions to the reserved area must be above this line.
2281
2282         elfphload(&Segtext)
2283         if Segrodata.Sect != nil {
2284                 elfphload(&Segrodata)
2285         }
2286         elfphload(&Segdata)
2287
2288         /* Dynamic linking sections */
2289         if Debug['d'] == 0 {
2290                 sh := elfshname(".dynsym")
2291                 sh.type_ = SHT_DYNSYM
2292                 sh.flags = SHF_ALLOC
2293                 if elf64 {
2294                         sh.entsize = ELF64SYMSIZE
2295                 } else {
2296                         sh.entsize = ELF32SYMSIZE
2297                 }
2298                 sh.addralign = uint64(SysArch.RegSize)
2299                 sh.link = uint32(elfshname(".dynstr").shnum)
2300
2301                 // sh->info = index of first non-local symbol (number of local symbols)
2302                 shsym(sh, Linklookup(Ctxt, ".dynsym", 0))
2303
2304                 sh = elfshname(".dynstr")
2305                 sh.type_ = SHT_STRTAB
2306                 sh.flags = SHF_ALLOC
2307                 sh.addralign = 1
2308                 shsym(sh, Linklookup(Ctxt, ".dynstr", 0))
2309
2310                 if elfverneed != 0 {
2311                         sh := elfshname(".gnu.version")
2312                         sh.type_ = SHT_GNU_VERSYM
2313                         sh.flags = SHF_ALLOC
2314                         sh.addralign = 2
2315                         sh.link = uint32(elfshname(".dynsym").shnum)
2316                         sh.entsize = 2
2317                         shsym(sh, Linklookup(Ctxt, ".gnu.version", 0))
2318
2319                         sh = elfshname(".gnu.version_r")
2320                         sh.type_ = SHT_GNU_VERNEED
2321                         sh.flags = SHF_ALLOC
2322                         sh.addralign = uint64(SysArch.RegSize)
2323                         sh.info = uint32(elfverneed)
2324                         sh.link = uint32(elfshname(".dynstr").shnum)
2325                         shsym(sh, Linklookup(Ctxt, ".gnu.version_r", 0))
2326                 }
2327
2328                 if elfRelType == ".rela" {
2329                         sh := elfshname(".rela.plt")
2330                         sh.type_ = SHT_RELA
2331                         sh.flags = SHF_ALLOC
2332                         sh.entsize = ELF64RELASIZE
2333                         sh.addralign = uint64(SysArch.RegSize)
2334                         sh.link = uint32(elfshname(".dynsym").shnum)
2335                         sh.info = uint32(elfshname(".plt").shnum)
2336                         shsym(sh, Linklookup(Ctxt, ".rela.plt", 0))
2337
2338                         sh = elfshname(".rela")
2339                         sh.type_ = SHT_RELA
2340                         sh.flags = SHF_ALLOC
2341                         sh.entsize = ELF64RELASIZE
2342                         sh.addralign = 8
2343                         sh.link = uint32(elfshname(".dynsym").shnum)
2344                         shsym(sh, Linklookup(Ctxt, ".rela", 0))
2345                 } else {
2346                         sh := elfshname(".rel.plt")
2347                         sh.type_ = SHT_REL
2348                         sh.flags = SHF_ALLOC
2349                         sh.entsize = ELF32RELSIZE
2350                         sh.addralign = 4
2351                         sh.link = uint32(elfshname(".dynsym").shnum)
2352                         shsym(sh, Linklookup(Ctxt, ".rel.plt", 0))
2353
2354                         sh = elfshname(".rel")
2355                         sh.type_ = SHT_REL
2356                         sh.flags = SHF_ALLOC
2357                         sh.entsize = ELF32RELSIZE
2358                         sh.addralign = 4
2359                         sh.link = uint32(elfshname(".dynsym").shnum)
2360                         shsym(sh, Linklookup(Ctxt, ".rel", 0))
2361                 }
2362
2363                 if eh.machine == EM_PPC64 {
2364                         sh := elfshname(".glink")
2365                         sh.type_ = SHT_PROGBITS
2366                         sh.flags = SHF_ALLOC + SHF_EXECINSTR
2367                         sh.addralign = 4
2368                         shsym(sh, Linklookup(Ctxt, ".glink", 0))
2369                 }
2370
2371                 sh = elfshname(".plt")
2372                 sh.type_ = SHT_PROGBITS
2373                 sh.flags = SHF_ALLOC + SHF_EXECINSTR
2374                 if eh.machine == EM_X86_64 {
2375                         sh.entsize = 16
2376                 } else if eh.machine == EM_S390 {
2377                         sh.entsize = 32
2378                 } else if eh.machine == EM_PPC64 {
2379                         // On ppc64, this is just a table of addresses
2380                         // filled by the dynamic linker
2381                         sh.type_ = SHT_NOBITS
2382
2383                         sh.flags = SHF_ALLOC + SHF_WRITE
2384                         sh.entsize = 8
2385                 } else {
2386                         sh.entsize = 4
2387                 }
2388                 sh.addralign = sh.entsize
2389                 shsym(sh, Linklookup(Ctxt, ".plt", 0))
2390
2391                 // On ppc64, .got comes from the input files, so don't
2392                 // create it here, and .got.plt is not used.
2393                 if eh.machine != EM_PPC64 {
2394                         sh := elfshname(".got")
2395                         sh.type_ = SHT_PROGBITS
2396                         sh.flags = SHF_ALLOC + SHF_WRITE
2397                         sh.entsize = uint64(SysArch.RegSize)
2398                         sh.addralign = uint64(SysArch.RegSize)
2399                         shsym(sh, Linklookup(Ctxt, ".got", 0))
2400
2401                         sh = elfshname(".got.plt")
2402                         sh.type_ = SHT_PROGBITS
2403                         sh.flags = SHF_ALLOC + SHF_WRITE
2404                         sh.entsize = uint64(SysArch.RegSize)
2405                         sh.addralign = uint64(SysArch.RegSize)
2406                         shsym(sh, Linklookup(Ctxt, ".got.plt", 0))
2407                 }
2408
2409                 sh = elfshname(".hash")
2410                 sh.type_ = SHT_HASH
2411                 sh.flags = SHF_ALLOC
2412                 sh.entsize = 4
2413                 sh.addralign = uint64(SysArch.RegSize)
2414                 sh.link = uint32(elfshname(".dynsym").shnum)
2415                 shsym(sh, Linklookup(Ctxt, ".hash", 0))
2416
2417                 /* sh and PT_DYNAMIC for .dynamic section */
2418                 sh = elfshname(".dynamic")
2419
2420                 sh.type_ = SHT_DYNAMIC
2421                 sh.flags = SHF_ALLOC + SHF_WRITE
2422                 sh.entsize = 2 * uint64(SysArch.RegSize)
2423                 sh.addralign = uint64(SysArch.RegSize)
2424                 sh.link = uint32(elfshname(".dynstr").shnum)
2425                 shsym(sh, Linklookup(Ctxt, ".dynamic", 0))
2426                 ph := newElfPhdr()
2427                 ph.type_ = PT_DYNAMIC
2428                 ph.flags = PF_R + PF_W
2429                 phsh(ph, sh)
2430
2431                 /*
2432                  * Thread-local storage segment (really just size).
2433                  */
2434                 // Do not emit PT_TLS for OpenBSD since ld.so(1) does
2435                 // not currently support it. This is handled
2436                 // appropriately in runtime/cgo.
2437                 if HEADTYPE != obj.Hopenbsd {
2438                         tlssize := uint64(0)
2439                         for sect := Segdata.Sect; sect != nil; sect = sect.Next {
2440                                 if sect.Name == ".tbss" {
2441                                         tlssize = sect.Length
2442                                 }
2443                         }
2444                         if tlssize != 0 {
2445                                 ph := newElfPhdr()
2446                                 ph.type_ = PT_TLS
2447                                 ph.flags = PF_R
2448                                 ph.memsz = tlssize
2449                                 ph.align = uint64(SysArch.RegSize)
2450                         }
2451                 }
2452         }
2453
2454         if HEADTYPE == obj.Hlinux {
2455                 ph := newElfPhdr()
2456                 ph.type_ = PT_GNU_STACK
2457                 ph.flags = PF_W + PF_R
2458                 ph.align = uint64(SysArch.RegSize)
2459
2460                 ph = newElfPhdr()
2461                 ph.type_ = PT_PAX_FLAGS
2462                 ph.flags = 0x2a00 // mprotect, randexec, emutramp disabled
2463                 ph.align = uint64(SysArch.RegSize)
2464         }
2465
2466 elfobj:
2467         sh := elfshname(".shstrtab")
2468         sh.type_ = SHT_STRTAB
2469         sh.addralign = 1
2470         shsym(sh, Linklookup(Ctxt, ".shstrtab", 0))
2471         eh.shstrndx = uint16(sh.shnum)
2472
2473         // put these sections early in the list
2474         if Debug['s'] == 0 {
2475                 elfshname(".symtab")
2476                 elfshname(".strtab")
2477         }
2478
2479         for sect := Segtext.Sect; sect != nil; sect = sect.Next {
2480                 elfshbits(sect)
2481         }
2482         for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
2483                 elfshbits(sect)
2484         }
2485         for sect := Segdata.Sect; sect != nil; sect = sect.Next {
2486                 elfshbits(sect)
2487         }
2488         for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
2489                 elfshbits(sect)
2490         }
2491
2492         if Linkmode == LinkExternal {
2493                 for sect := Segtext.Sect; sect != nil; sect = sect.Next {
2494                         elfshreloc(sect)
2495                 }
2496                 for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
2497                         elfshreloc(sect)
2498                 }
2499                 for sect := Segdata.Sect; sect != nil; sect = sect.Next {
2500                         elfshreloc(sect)
2501                 }
2502                 for s := dwarfp; s != nil; s = s.Next {
2503                         if len(s.R) > 0 || s.Type == obj.SDWARFINFO {
2504                                 elfshreloc(s.Sect)
2505                         }
2506                         if s.Type == obj.SDWARFINFO {
2507                                 break
2508                         }
2509                 }
2510                 // add a .note.GNU-stack section to mark the stack as non-executable
2511                 sh := elfshname(".note.GNU-stack")
2512
2513                 sh.type_ = SHT_PROGBITS
2514                 sh.addralign = 1
2515                 sh.flags = 0
2516         }
2517
2518         if Debug['s'] == 0 {
2519                 sh := elfshname(".symtab")
2520                 sh.type_ = SHT_SYMTAB
2521                 sh.off = uint64(symo)
2522                 sh.size = uint64(Symsize)
2523                 sh.addralign = uint64(SysArch.RegSize)
2524                 sh.entsize = 8 + 2*uint64(SysArch.RegSize)
2525                 sh.link = uint32(elfshname(".strtab").shnum)
2526                 sh.info = uint32(elfglobalsymndx)
2527
2528                 sh = elfshname(".strtab")
2529                 sh.type_ = SHT_STRTAB
2530                 sh.off = uint64(symo) + uint64(Symsize)
2531                 sh.size = uint64(len(Elfstrdat))
2532                 sh.addralign = 1
2533         }
2534
2535         /* Main header */
2536         eh.ident[EI_MAG0] = '\177'
2537
2538         eh.ident[EI_MAG1] = 'E'
2539         eh.ident[EI_MAG2] = 'L'
2540         eh.ident[EI_MAG3] = 'F'
2541         if HEADTYPE == obj.Hfreebsd {
2542                 eh.ident[EI_OSABI] = ELFOSABI_FREEBSD
2543         } else if HEADTYPE == obj.Hnetbsd {
2544                 eh.ident[EI_OSABI] = ELFOSABI_NETBSD
2545         } else if HEADTYPE == obj.Hopenbsd {
2546                 eh.ident[EI_OSABI] = ELFOSABI_OPENBSD
2547         } else if HEADTYPE == obj.Hdragonfly {
2548                 eh.ident[EI_OSABI] = ELFOSABI_NONE
2549         }
2550         if elf64 {
2551                 eh.ident[EI_CLASS] = ELFCLASS64
2552         } else {
2553                 eh.ident[EI_CLASS] = ELFCLASS32
2554         }
2555         if Ctxt.Arch.ByteOrder == binary.BigEndian {
2556                 eh.ident[EI_DATA] = ELFDATA2MSB
2557         } else {
2558                 eh.ident[EI_DATA] = ELFDATA2LSB
2559         }
2560         eh.ident[EI_VERSION] = EV_CURRENT
2561
2562         if Linkmode == LinkExternal {
2563                 eh.type_ = ET_REL
2564         } else {
2565                 eh.type_ = ET_EXEC
2566         }
2567
2568         if Linkmode != LinkExternal {
2569                 eh.entry = uint64(Entryvalue())
2570         }
2571
2572         eh.version = EV_CURRENT
2573
2574         if pph != nil {
2575                 pph.filesz = uint64(eh.phnum) * uint64(eh.phentsize)
2576                 pph.memsz = pph.filesz
2577         }
2578
2579         Cseek(0)
2580         a := int64(0)
2581         a += int64(elfwritehdr())
2582         a += int64(elfwritephdrs())
2583         a += int64(elfwriteshdrs())
2584         if Debug['d'] == 0 {
2585                 a += int64(elfwriteinterp())
2586         }
2587         if Linkmode != LinkExternal {
2588                 if HEADTYPE == obj.Hnetbsd {
2589                         a += int64(elfwritenetbsdsig())
2590                 }
2591                 if HEADTYPE == obj.Hopenbsd {
2592                         a += int64(elfwriteopenbsdsig())
2593                 }
2594                 if len(buildinfo) > 0 {
2595                         a += int64(elfwritebuildinfo())
2596                 }
2597                 if buildid != "" {
2598                         a += int64(elfwritegobuildid())
2599                 }
2600         }
2601
2602         if a > elfreserve {
2603                 Diag("ELFRESERVE too small: %d > %d", a, elfreserve)
2604         }
2605 }
2606
2607 func Elfadddynsym(ctxt *Link, s *LSym) {
2608         if elf64 {
2609                 s.Dynid = int32(Nelfsym)
2610                 Nelfsym++
2611
2612                 d := Linklookup(ctxt, ".dynsym", 0)
2613
2614                 name := s.Extname
2615                 Adduint32(ctxt, d, uint32(Addstring(Linklookup(ctxt, ".dynstr", 0), name)))
2616
2617                 /* type */
2618                 t := STB_GLOBAL << 4
2619
2620                 if s.Attr.CgoExport() && s.Type&obj.SMASK == obj.STEXT {
2621                         t |= STT_FUNC
2622                 } else {
2623                         t |= STT_OBJECT
2624                 }
2625                 Adduint8(ctxt, d, uint8(t))
2626
2627                 /* reserved */
2628                 Adduint8(ctxt, d, 0)
2629
2630                 /* section where symbol is defined */
2631                 if s.Type == obj.SDYNIMPORT {
2632                         Adduint16(ctxt, d, SHN_UNDEF)
2633                 } else {
2634                         Adduint16(ctxt, d, 1)
2635                 }
2636
2637                 /* value */
2638                 if s.Type == obj.SDYNIMPORT {
2639                         Adduint64(ctxt, d, 0)
2640                 } else {
2641                         Addaddr(ctxt, d, s)
2642                 }
2643
2644                 /* size of object */
2645                 Adduint64(ctxt, d, uint64(s.Size))
2646
2647                 if SysArch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib != "" && !seenlib[s.Dynimplib] {
2648                         Elfwritedynent(Linklookup(ctxt, ".dynamic", 0), DT_NEEDED, uint64(Addstring(Linklookup(ctxt, ".dynstr", 0), s.Dynimplib)))
2649                 }
2650         } else {
2651                 s.Dynid = int32(Nelfsym)
2652                 Nelfsym++
2653
2654                 d := Linklookup(ctxt, ".dynsym", 0)
2655
2656                 /* name */
2657                 name := s.Extname
2658
2659                 Adduint32(ctxt, d, uint32(Addstring(Linklookup(ctxt, ".dynstr", 0), name)))
2660
2661                 /* value */
2662                 if s.Type == obj.SDYNIMPORT {
2663                         Adduint32(ctxt, d, 0)
2664                 } else {
2665                         Addaddr(ctxt, d, s)
2666                 }
2667
2668                 /* size */
2669                 Adduint32(ctxt, d, 0)
2670
2671                 /* type */
2672                 t := STB_GLOBAL << 4
2673
2674                 // TODO(mwhudson): presumably the behaviour should actually be the same on both arm and 386.
2675                 if SysArch.Family == sys.I386 && s.Attr.CgoExport() && s.Type&obj.SMASK == obj.STEXT {
2676                         t |= STT_FUNC
2677                 } else if SysArch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type&obj.SMASK == obj.STEXT {
2678                         t |= STT_FUNC
2679                 } else {
2680                         t |= STT_OBJECT
2681                 }
2682                 Adduint8(ctxt, d, uint8(t))
2683                 Adduint8(ctxt, d, 0)
2684
2685                 /* shndx */
2686                 if s.Type == obj.SDYNIMPORT {
2687                         Adduint16(ctxt, d, SHN_UNDEF)
2688                 } else {
2689                         Adduint16(ctxt, d, 1)
2690                 }
2691         }
2692 }
2693
2694 func ELF32_R_SYM(info uint32) uint32 {
2695         return info >> 8
2696 }
2697
2698 func ELF32_R_TYPE(info uint32) uint32 {
2699         return uint32(uint8(info))
2700 }
2701
2702 func ELF32_R_INFO(sym uint32, type_ uint32) uint32 {
2703         return sym<<8 | type_
2704 }
2705
2706 func ELF32_ST_BIND(info uint8) uint8 {
2707         return info >> 4
2708 }
2709
2710 func ELF32_ST_TYPE(info uint8) uint8 {
2711         return info & 0xf
2712 }
2713
2714 func ELF32_ST_INFO(bind uint8, type_ uint8) uint8 {
2715         return bind<<4 | type_&0xf
2716 }
2717
2718 func ELF32_ST_VISIBILITY(oth uint8) uint8 {
2719         return oth & 3
2720 }
2721
2722 func ELF64_R_SYM(info uint64) uint32 {
2723         return uint32(info >> 32)
2724 }
2725
2726 func ELF64_R_TYPE(info uint64) uint32 {
2727         return uint32(info)
2728 }
2729
2730 func ELF64_R_INFO(sym uint32, type_ uint32) uint64 {
2731         return uint64(sym)<<32 | uint64(type_)
2732 }
2733
2734 func ELF64_ST_BIND(info uint8) uint8 {
2735         return info >> 4
2736 }
2737
2738 func ELF64_ST_TYPE(info uint8) uint8 {
2739         return info & 0xf
2740 }
2741
2742 func ELF64_ST_INFO(bind uint8, type_ uint8) uint8 {
2743         return bind<<4 | type_&0xf
2744 }
2745
2746 func ELF64_ST_VISIBILITY(oth uint8) uint8 {
2747         return oth & 3
2748 }