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