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/objabi"
      9 	"cmd/internal/sys"
     10 	"cmd/link/internal/sym"
     11 	"crypto/sha1"
     12 	"encoding/binary"
     13 	"encoding/hex"
     14 	"io"
     15 	"path/filepath"
     16 	"sort"
     17 	"strings"
     18 )
     19 
     20 /*
     21  * Derived from:
     22  * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $
     23  * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $
     24  * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $
     25  * $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $
     26  * $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $
     27  * $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $
     28  * $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $
     29  * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $
     30  * $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $
     31  *
     32  * Copyright (c) 1996-1998 John D. Polstra.  All rights reserved.
     33  * Copyright (c) 2001 David E. O'Brien
     34  * Portions Copyright 2009 The Go Authors. All rights reserved.
     35  *
     36  * Redistribution and use in source and binary forms, with or without
     37  * modification, are permitted provided that the following conditions
     38  * are met:
     39  * 1. Redistributions of source code must retain the above copyright
     40  *    notice, this list of conditions and the following disclaimer.
     41  * 2. Redistributions in binary form must reproduce the above copyright
     42  *    notice, this list of conditions and the following disclaimer in the
     43  *    documentation and/or other materials provided with the distribution.
     44  *
     45  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     46  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     47  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     48  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     49  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     50  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     51  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     52  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     53  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     54  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     55  * SUCH DAMAGE.
     56  *
     57  */
     58 
     59 /*
     60  * ELF definitions that are independent of architecture or word size.
     61  */
     62 
     63 /*
     64  * Note header.  The ".note" section contains an array of notes.  Each
     65  * begins with this header, aligned to a word boundary.  Immediately
     66  * following the note header is n_namesz bytes of name, padded to the
     67  * next word boundary.  Then comes n_descsz bytes of descriptor, again
     68  * padded to a word boundary.  The values of n_namesz and n_descsz do
     69  * not include the padding.
     70  */
     71 type elfNote struct {
     72 	nNamesz uint32
     73 	nDescsz uint32
     74 	nType   uint32
     75 }
     76 
     77 const (
     78 	EI_MAG0              = 0
     79 	EI_MAG1              = 1
     80 	EI_MAG2              = 2
     81 	EI_MAG3              = 3
     82 	EI_CLASS             = 4
     83 	EI_DATA              = 5
     84 	EI_VERSION           = 6
     85 	EI_OSABI             = 7
     86 	EI_ABIVERSION        = 8
     87 	OLD_EI_BRAND         = 8
     88 	EI_PAD               = 9
     89 	EI_NIDENT            = 16
     90 	ELFMAG0              = 0x7f
     91 	ELFMAG1              = 'E'
     92 	ELFMAG2              = 'L'
     93 	ELFMAG3              = 'F'
     94 	SELFMAG              = 4
     95 	EV_NONE              = 0
     96 	EV_CURRENT           = 1
     97 	ELFCLASSNONE         = 0
     98 	ELFCLASS32           = 1
     99 	ELFCLASS64           = 2
    100 	ELFDATANONE          = 0
    101 	ELFDATA2LSB          = 1
    102 	ELFDATA2MSB          = 2
    103 	ELFOSABI_NONE        = 0
    104 	ELFOSABI_HPUX        = 1
    105 	ELFOSABI_NETBSD      = 2
    106 	ELFOSABI_LINUX       = 3
    107 	ELFOSABI_HURD        = 4
    108 	ELFOSABI_86OPEN      = 5
    109 	ELFOSABI_SOLARIS     = 6
    110 	ELFOSABI_AIX         = 7
    111 	ELFOSABI_IRIX        = 8
    112 	ELFOSABI_FREEBSD     = 9
    113 	ELFOSABI_TRU64       = 10
    114 	ELFOSABI_MODESTO     = 11
    115 	ELFOSABI_OPENBSD     = 12
    116 	ELFOSABI_OPENVMS     = 13
    117 	ELFOSABI_NSK         = 14
    118 	ELFOSABI_ARM         = 97
    119 	ELFOSABI_STANDALONE  = 255
    120 	ELFOSABI_SYSV        = ELFOSABI_NONE
    121 	ELFOSABI_MONTEREY    = ELFOSABI_AIX
    122 	ET_NONE              = 0
    123 	ET_REL               = 1
    124 	ET_EXEC              = 2
    125 	ET_DYN               = 3
    126 	ET_CORE              = 4
    127 	ET_LOOS              = 0xfe00
    128 	ET_HIOS              = 0xfeff
    129 	ET_LOPROC            = 0xff00
    130 	ET_HIPROC            = 0xffff
    131 	EM_NONE              = 0
    132 	EM_M32               = 1
    133 	EM_SPARC             = 2
    134 	EM_386               = 3
    135 	EM_68K               = 4
    136 	EM_88K               = 5
    137 	EM_860               = 7
    138 	EM_MIPS              = 8
    139 	EM_S370              = 9
    140 	EM_MIPS_RS3_LE       = 10
    141 	EM_PARISC            = 15
    142 	EM_VPP500            = 17
    143 	EM_SPARC32PLUS       = 18
    144 	EM_960               = 19
    145 	EM_PPC               = 20
    146 	EM_PPC64             = 21
    147 	EM_S390              = 22
    148 	EM_V800              = 36
    149 	EM_FR20              = 37
    150 	EM_RH32              = 38
    151 	EM_RCE               = 39
    152 	EM_ARM               = 40
    153 	EM_SH                = 42
    154 	EM_SPARCV9           = 43
    155 	EM_TRICORE           = 44
    156 	EM_ARC               = 45
    157 	EM_H8_300            = 46
    158 	EM_H8_300H           = 47
    159 	EM_H8S               = 48
    160 	EM_H8_500            = 49
    161 	EM_IA_64             = 50
    162 	EM_MIPS_X            = 51
    163 	EM_COLDFIRE          = 52
    164 	EM_68HC12            = 53
    165 	EM_MMA               = 54
    166 	EM_PCP               = 55
    167 	EM_NCPU              = 56
    168 	EM_NDR1              = 57
    169 	EM_STARCORE          = 58
    170 	EM_ME16              = 59
    171 	EM_ST100             = 60
    172 	EM_TINYJ             = 61
    173 	EM_X86_64            = 62
    174 	EM_AARCH64           = 183
    175 	EM_486               = 6
    176 	EM_MIPS_RS4_BE       = 10
    177 	EM_ALPHA_STD         = 41
    178 	EM_ALPHA             = 0x9026
    179 	SHN_UNDEF            = 0
    180 	SHN_LORESERVE        = 0xff00
    181 	SHN_LOPROC           = 0xff00
    182 	SHN_HIPROC           = 0xff1f
    183 	SHN_LOOS             = 0xff20
    184 	SHN_HIOS             = 0xff3f
    185 	SHN_ABS              = 0xfff1
    186 	SHN_COMMON           = 0xfff2
    187 	SHN_XINDEX           = 0xffff
    188 	SHN_HIRESERVE        = 0xffff
    189 	SHT_NULL             = 0
    190 	SHT_PROGBITS         = 1
    191 	SHT_SYMTAB           = 2
    192 	SHT_STRTAB           = 3
    193 	SHT_RELA             = 4
    194 	SHT_HASH             = 5
    195 	SHT_DYNAMIC          = 6
    196 	SHT_NOTE             = 7
    197 	SHT_NOBITS           = 8
    198 	SHT_REL              = 9
    199 	SHT_SHLIB            = 10
    200 	SHT_DYNSYM           = 11
    201 	SHT_INIT_ARRAY       = 14
    202 	SHT_FINI_ARRAY       = 15
    203 	SHT_PREINIT_ARRAY    = 16
    204 	SHT_GROUP            = 17
    205 	SHT_SYMTAB_SHNDX     = 18
    206 	SHT_LOOS             = 0x60000000
    207 	SHT_HIOS             = 0x6fffffff
    208 	SHT_GNU_VERDEF       = 0x6ffffffd
    209 	SHT_GNU_VERNEED      = 0x6ffffffe
    210 	SHT_GNU_VERSYM       = 0x6fffffff
    211 	SHT_LOPROC           = 0x70000000
    212 	SHT_ARM_ATTRIBUTES   = 0x70000003
    213 	SHT_HIPROC           = 0x7fffffff
    214 	SHT_LOUSER           = 0x80000000
    215 	SHT_HIUSER           = 0xffffffff
    216 	SHF_WRITE            = 0x1
    217 	SHF_ALLOC            = 0x2
    218 	SHF_EXECINSTR        = 0x4
    219 	SHF_MERGE            = 0x10
    220 	SHF_STRINGS          = 0x20
    221 	SHF_INFO_LINK        = 0x40
    222 	SHF_LINK_ORDER       = 0x80
    223 	SHF_OS_NONCONFORMING = 0x100
    224 	SHF_GROUP            = 0x200
    225 	SHF_TLS              = 0x400
    226 	SHF_MASKOS           = 0x0ff00000
    227 	SHF_MASKPROC         = 0xf0000000
    228 	PT_NULL              = 0
    229 	PT_LOAD              = 1
    230 	PT_DYNAMIC           = 2
    231 	PT_INTERP            = 3
    232 	PT_NOTE              = 4
    233 	PT_SHLIB             = 5
    234 	PT_PHDR              = 6
    235 	PT_TLS               = 7
    236 	PT_LOOS              = 0x60000000
    237 	PT_HIOS              = 0x6fffffff
    238 	PT_LOPROC            = 0x70000000
    239 	PT_HIPROC            = 0x7fffffff
    240 	PT_GNU_STACK         = 0x6474e551
    241 	PT_GNU_RELRO         = 0x6474e552
    242 	PT_PAX_FLAGS         = 0x65041580
    243 	PT_SUNWSTACK         = 0x6ffffffb
    244 	PF_X                 = 0x1
    245 	PF_W                 = 0x2
    246 	PF_R                 = 0x4
    247 	PF_MASKOS            = 0x0ff00000
    248 	PF_MASKPROC          = 0xf0000000
    249 	DT_NULL              = 0
    250 	DT_NEEDED            = 1
    251 	DT_PLTRELSZ          = 2
    252 	DT_PLTGOT            = 3
    253 	DT_HASH              = 4
    254 	DT_STRTAB            = 5
    255 	DT_SYMTAB            = 6
    256 	DT_RELA              = 7
    257 	DT_RELASZ            = 8
    258 	DT_RELAENT           = 9
    259 	DT_STRSZ             = 10
    260 	DT_SYMENT            = 11
    261 	DT_INIT              = 12
    262 	DT_FINI              = 13
    263 	DT_SONAME            = 14
    264 	DT_RPATH             = 15
    265 	DT_SYMBOLIC          = 16
    266 	DT_REL               = 17
    267 	DT_RELSZ             = 18
    268 	DT_RELENT            = 19
    269 	DT_PLTREL            = 20
    270 	DT_DEBUG             = 21
    271 	DT_TEXTREL           = 22
    272 	DT_JMPREL            = 23
    273 	DT_BIND_NOW          = 24
    274 	DT_INIT_ARRAY        = 25
    275 	DT_FINI_ARRAY        = 26
    276 	DT_INIT_ARRAYSZ      = 27
    277 	DT_FINI_ARRAYSZ      = 28
    278 	DT_RUNPATH           = 29
    279 	DT_FLAGS             = 30
    280 	DT_ENCODING          = 32
    281 	DT_PREINIT_ARRAY     = 32
    282 	DT_PREINIT_ARRAYSZ   = 33
    283 	DT_LOOS              = 0x6000000d
    284 	DT_HIOS              = 0x6ffff000
    285 	DT_LOPROC            = 0x70000000
    286 	DT_HIPROC            = 0x7fffffff
    287 	DT_VERNEED           = 0x6ffffffe
    288 	DT_VERNEEDNUM        = 0x6fffffff
    289 	DT_VERSYM            = 0x6ffffff0
    290 	DT_PPC64_GLINK       = DT_LOPROC + 0
    291 	DT_PPC64_OPT         = DT_LOPROC + 3
    292 	DF_ORIGIN            = 0x0001
    293 	DF_SYMBOLIC          = 0x0002
    294 	DF_TEXTREL           = 0x0004
    295 	DF_BIND_NOW          = 0x0008
    296 	DF_STATIC_TLS        = 0x0010
    297 	NT_PRSTATUS          = 1
    298 	NT_FPREGSET          = 2
    299 	NT_PRPSINFO          = 3
    300 	STB_LOCAL            = 0
    301 	STB_GLOBAL           = 1
    302 	STB_WEAK             = 2
    303 	STB_LOOS             = 10
    304 	STB_HIOS             = 12
    305 	STB_LOPROC           = 13
    306 	STB_HIPROC           = 15
    307 	STT_NOTYPE           = 0
    308 	STT_OBJECT           = 1
    309 	STT_FUNC             = 2
    310 	STT_SECTION          = 3
    311 	STT_FILE             = 4
    312 	STT_COMMON           = 5
    313 	STT_TLS              = 6
    314 	STT_LOOS             = 10
    315 	STT_HIOS             = 12
    316 	STT_LOPROC           = 13
    317 	STT_HIPROC           = 15
    318 	STV_DEFAULT          = 0x0
    319 	STV_INTERNAL         = 0x1
    320 	STV_HIDDEN           = 0x2
    321 	STV_PROTECTED        = 0x3
    322 	STN_UNDEF            = 0
    323 )
    324 
    325 /* For accessing the fields of r_info. */
    326 
    327 /* For constructing r_info from field values. */
    328 
    329 /*
    330  * Relocation types.
    331  */
    332 const (
    333 	ARM_MAGIC_TRAMP_NUMBER = 0x5c000003
    334 )
    335 
    336 /*
    337  * Symbol table entries.
    338  */
    339 
    340 /* For accessing the fields of st_info. */
    341 
    342 /* For constructing st_info from field values. */
    343 
    344 /* For accessing the fields of st_other. */
    345 
    346 /*
    347  * ELF header.
    348  */
    349 type ElfEhdr struct {
    350 	ident     [EI_NIDENT]uint8
    351 	type_     uint16
    352 	machine   uint16
    353 	version   uint32
    354 	entry     uint64
    355 	phoff     uint64
    356 	shoff     uint64
    357 	flags     uint32
    358 	ehsize    uint16
    359 	phentsize uint16
    360 	phnum     uint16
    361 	shentsize uint16
    362 	shnum     uint16
    363 	shstrndx  uint16
    364 }
    365 
    366 /*
    367  * Section header.
    368  */
    369 type ElfShdr struct {
    370 	name      uint32
    371 	type_     uint32
    372 	flags     uint64
    373 	addr      uint64
    374 	off       uint64
    375 	size      uint64
    376 	link      uint32
    377 	info      uint32
    378 	addralign uint64
    379 	entsize   uint64
    380 	shnum     int
    381 }
    382 
    383 /*
    384  * Program header.
    385  */
    386 type ElfPhdr struct {
    387 	type_  uint32
    388 	flags  uint32
    389 	off    uint64
    390 	vaddr  uint64
    391 	paddr  uint64
    392 	filesz uint64
    393 	memsz  uint64
    394 	align  uint64
    395 }
    396 
    397 /* For accessing the fields of r_info. */
    398 
    399 /* For constructing r_info from field values. */
    400 
    401 /*
    402  * Symbol table entries.
    403  */
    404 
    405 /* For accessing the fields of st_info. */
    406 
    407 /* For constructing st_info from field values. */
    408 
    409 /* For accessing the fields of st_other. */
    410 
    411 /*
    412  * Go linker interface
    413  */
    414 const (
    415 	ELF64HDRSIZE  = 64
    416 	ELF64PHDRSIZE = 56
    417 	ELF64SHDRSIZE = 64
    418 	ELF64RELSIZE  = 16
    419 	ELF64RELASIZE = 24
    420 	ELF64SYMSIZE  = 24
    421 	ELF32HDRSIZE  = 52
    422 	ELF32PHDRSIZE = 32
    423 	ELF32SHDRSIZE = 40
    424 	ELF32SYMSIZE  = 16
    425 	ELF32RELSIZE  = 8
    426 )
    427 
    428 /*
    429  * The interface uses the 64-bit structures always,
    430  * to avoid code duplication.  The writers know how to
    431  * marshal a 32-bit representation from the 64-bit structure.
    432  */
    433 
    434 var Elfstrdat []byte
    435 
    436 /*
    437  * Total amount of space to reserve at the start of the file
    438  * for Header, PHeaders, SHeaders, and interp.
    439  * May waste some.
    440  * On FreeBSD, cannot be larger than a page.
    441  */
    442 const (
    443 	ELFRESERVE = 4096
    444 )
    445 
    446 /*
    447  * We use the 64-bit data structures on both 32- and 64-bit machines
    448  * in order to write the code just once.  The 64-bit data structure is
    449  * written in the 32-bit format on the 32-bit machines.
    450  */
    451 const (
    452 	NSECT = 400
    453 )
    454 
    455 var (
    456 	Nelfsym = 1
    457 
    458 	elf64 bool
    459 	// Either ".rel" or ".rela" depending on which type of relocation the
    460 	// target platform uses.
    461 	elfRelType string
    462 
    463 	ehdr ElfEhdr
    464 	phdr [NSECT]*ElfPhdr
    465 	shdr [NSECT]*ElfShdr
    466 
    467 	interp string
    468 )
    469 
    470 type Elfstring struct {
    471 	s   string
    472 	off int
    473 }
    474 
    475 var elfstr [100]Elfstring
    476 
    477 var nelfstr int
    478 
    479 var buildinfo []byte
    480 
    481 /*
    482  Initialize the global variable that describes the ELF header. It will be updated as
    483  we write section and prog headers.
    484 */
    485 func Elfinit(ctxt *Link) {
    486 	ctxt.IsELF = true
    487 
    488 	if ctxt.Arch.InFamily(sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.S390X) {
    489 		elfRelType = ".rela"
    490 	} else {
    491 		elfRelType = ".rel"
    492 	}
    493 
    494 	switch ctxt.Arch.Family {
    495 	// 64-bit architectures
    496 	case sys.PPC64, sys.S390X:
    497 		if ctxt.Arch.ByteOrder == binary.BigEndian {
    498 			ehdr.flags = 1 /* Version 1 ABI */
    499 		} else {
    500 			ehdr.flags = 2 /* Version 2 ABI */
    501 		}
    502 		fallthrough
    503 	case sys.AMD64, sys.ARM64, sys.MIPS64:
    504 		if ctxt.Arch.Family == sys.MIPS64 {
    505 			ehdr.flags = 0x20000004 /* MIPS 3 CPIC */
    506 		}
    507 		elf64 = true
    508 
    509 		ehdr.phoff = ELF64HDRSIZE      /* Must be be ELF64HDRSIZE: first PHdr must follow ELF header */
    510 		ehdr.shoff = ELF64HDRSIZE      /* Will move as we add PHeaders */
    511 		ehdr.ehsize = ELF64HDRSIZE     /* Must be ELF64HDRSIZE */
    512 		ehdr.phentsize = ELF64PHDRSIZE /* Must be ELF64PHDRSIZE */
    513 		ehdr.shentsize = ELF64SHDRSIZE /* Must be ELF64SHDRSIZE */
    514 
    515 	// 32-bit architectures
    516 	case sys.ARM, sys.MIPS:
    517 		if ctxt.Arch.Family == sys.ARM {
    518 			// we use EABI on linux/arm, freebsd/arm, netbsd/arm.
    519 			if ctxt.HeadType == objabi.Hlinux || ctxt.HeadType == objabi.Hfreebsd || ctxt.HeadType == objabi.Hnetbsd {
    520 				// We set a value here that makes no indication of which
    521 				// float ABI the object uses, because this is information
    522 				// used by the dynamic linker to compare executables and
    523 				// shared libraries -- so it only matters for cgo calls, and
    524 				// the information properly comes from the object files
    525 				// produced by the host C compiler. parseArmAttributes in
    526 				// ldelf.go reads that information and updates this field as
    527 				// appropriate.
    528 				ehdr.flags = 0x5000002 // has entry point, Version5 EABI
    529 			}
    530 		} else if ctxt.Arch.Family == sys.MIPS {
    531 			ehdr.flags = 0x50001004 /* MIPS 32 CPIC O32*/
    532 		}
    533 		fallthrough
    534 	default:
    535 		ehdr.phoff = ELF32HDRSIZE
    536 		/* Must be be ELF32HDRSIZE: first PHdr must follow ELF header */
    537 		ehdr.shoff = ELF32HDRSIZE      /* Will move as we add PHeaders */
    538 		ehdr.ehsize = ELF32HDRSIZE     /* Must be ELF32HDRSIZE */
    539 		ehdr.phentsize = ELF32PHDRSIZE /* Must be ELF32PHDRSIZE */
    540 		ehdr.shentsize = ELF32SHDRSIZE /* Must be ELF32SHDRSIZE */
    541 	}
    542 }
    543 
    544 // Make sure PT_LOAD is aligned properly and
    545 // that there is no gap,
    546 // correct ELF loaders will do this implicitly,
    547 // but buggy ELF loaders like the one in some
    548 // versions of QEMU and UPX won't.
    549 func fixElfPhdr(e *ElfPhdr) {
    550 	frag := int(e.vaddr & (e.align - 1))
    551 
    552 	e.off -= uint64(frag)
    553 	e.vaddr -= uint64(frag)
    554 	e.paddr -= uint64(frag)
    555 	e.filesz += uint64(frag)
    556 	e.memsz += uint64(frag)
    557 }
    558 
    559 func elf64phdr(out *OutBuf, e *ElfPhdr) {
    560 	if e.type_ == PT_LOAD {
    561 		fixElfPhdr(e)
    562 	}
    563 
    564 	out.Write32(e.type_)
    565 	out.Write32(e.flags)
    566 	out.Write64(e.off)
    567 	out.Write64(e.vaddr)
    568 	out.Write64(e.paddr)
    569 	out.Write64(e.filesz)
    570 	out.Write64(e.memsz)
    571 	out.Write64(e.align)
    572 }
    573 
    574 func elf32phdr(out *OutBuf, e *ElfPhdr) {
    575 	if e.type_ == PT_LOAD {
    576 		fixElfPhdr(e)
    577 	}
    578 
    579 	out.Write32(e.type_)
    580 	out.Write32(uint32(e.off))
    581 	out.Write32(uint32(e.vaddr))
    582 	out.Write32(uint32(e.paddr))
    583 	out.Write32(uint32(e.filesz))
    584 	out.Write32(uint32(e.memsz))
    585 	out.Write32(e.flags)
    586 	out.Write32(uint32(e.align))
    587 }
    588 
    589 func elf64shdr(out *OutBuf, e *ElfShdr) {
    590 	out.Write32(e.name)
    591 	out.Write32(e.type_)
    592 	out.Write64(e.flags)
    593 	out.Write64(e.addr)
    594 	out.Write64(e.off)
    595 	out.Write64(e.size)
    596 	out.Write32(e.link)
    597 	out.Write32(e.info)
    598 	out.Write64(e.addralign)
    599 	out.Write64(e.entsize)
    600 }
    601 
    602 func elf32shdr(out *OutBuf, e *ElfShdr) {
    603 	out.Write32(e.name)
    604 	out.Write32(e.type_)
    605 	out.Write32(uint32(e.flags))
    606 	out.Write32(uint32(e.addr))
    607 	out.Write32(uint32(e.off))
    608 	out.Write32(uint32(e.size))
    609 	out.Write32(e.link)
    610 	out.Write32(e.info)
    611 	out.Write32(uint32(e.addralign))
    612 	out.Write32(uint32(e.entsize))
    613 }
    614 
    615 func elfwriteshdrs(out *OutBuf) uint32 {
    616 	if elf64 {
    617 		for i := 0; i < int(ehdr.shnum); i++ {
    618 			elf64shdr(out, shdr[i])
    619 		}
    620 		return uint32(ehdr.shnum) * ELF64SHDRSIZE
    621 	}
    622 
    623 	for i := 0; i < int(ehdr.shnum); i++ {
    624 		elf32shdr(out, shdr[i])
    625 	}
    626 	return uint32(ehdr.shnum) * ELF32SHDRSIZE
    627 }
    628 
    629 func elfsetstring(s *sym.Symbol, str string, off int) {
    630 	if nelfstr >= len(elfstr) {
    631 		Errorf(s, "too many elf strings")
    632 		errorexit()
    633 	}
    634 
    635 	elfstr[nelfstr].s = str
    636 	elfstr[nelfstr].off = off
    637 	nelfstr++
    638 }
    639 
    640 func elfwritephdrs(out *OutBuf) uint32 {
    641 	if elf64 {
    642 		for i := 0; i < int(ehdr.phnum); i++ {
    643 			elf64phdr(out, phdr[i])
    644 		}
    645 		return uint32(ehdr.phnum) * ELF64PHDRSIZE
    646 	}
    647 
    648 	for i := 0; i < int(ehdr.phnum); i++ {
    649 		elf32phdr(out, phdr[i])
    650 	}
    651 	return uint32(ehdr.phnum) * ELF32PHDRSIZE
    652 }
    653 
    654 func newElfPhdr() *ElfPhdr {
    655 	e := new(ElfPhdr)
    656 	if ehdr.phnum >= NSECT {
    657 		Errorf(nil, "too many phdrs")
    658 	} else {
    659 		phdr[ehdr.phnum] = e
    660 		ehdr.phnum++
    661 	}
    662 	if elf64 {
    663 		ehdr.shoff += ELF64PHDRSIZE
    664 	} else {
    665 		ehdr.shoff += ELF32PHDRSIZE
    666 	}
    667 	return e
    668 }
    669 
    670 func newElfShdr(name int64) *ElfShdr {
    671 	e := new(ElfShdr)
    672 	e.name = uint32(name)
    673 	e.shnum = int(ehdr.shnum)
    674 	if ehdr.shnum >= NSECT {
    675 		Errorf(nil, "too many shdrs")
    676 	} else {
    677 		shdr[ehdr.shnum] = e
    678 		ehdr.shnum++
    679 	}
    680 
    681 	return e
    682 }
    683 
    684 func getElfEhdr() *ElfEhdr {
    685 	return &ehdr
    686 }
    687 
    688 func elf64writehdr(out *OutBuf) uint32 {
    689 	out.Write(ehdr.ident[:])
    690 	out.Write16(ehdr.type_)
    691 	out.Write16(ehdr.machine)
    692 	out.Write32(ehdr.version)
    693 	out.Write64(ehdr.entry)
    694 	out.Write64(ehdr.phoff)
    695 	out.Write64(ehdr.shoff)
    696 	out.Write32(ehdr.flags)
    697 	out.Write16(ehdr.ehsize)
    698 	out.Write16(ehdr.phentsize)
    699 	out.Write16(ehdr.phnum)
    700 	out.Write16(ehdr.shentsize)
    701 	out.Write16(ehdr.shnum)
    702 	out.Write16(ehdr.shstrndx)
    703 	return ELF64HDRSIZE
    704 }
    705 
    706 func elf32writehdr(out *OutBuf) uint32 {
    707 	out.Write(ehdr.ident[:])
    708 	out.Write16(ehdr.type_)
    709 	out.Write16(ehdr.machine)
    710 	out.Write32(ehdr.version)
    711 	out.Write32(uint32(ehdr.entry))
    712 	out.Write32(uint32(ehdr.phoff))
    713 	out.Write32(uint32(ehdr.shoff))
    714 	out.Write32(ehdr.flags)
    715 	out.Write16(ehdr.ehsize)
    716 	out.Write16(ehdr.phentsize)
    717 	out.Write16(ehdr.phnum)
    718 	out.Write16(ehdr.shentsize)
    719 	out.Write16(ehdr.shnum)
    720 	out.Write16(ehdr.shstrndx)
    721 	return ELF32HDRSIZE
    722 }
    723 
    724 func elfwritehdr(out *OutBuf) uint32 {
    725 	if elf64 {
    726 		return elf64writehdr(out)
    727 	}
    728 	return elf32writehdr(out)
    729 }
    730 
    731 /* Taken directly from the definition document for ELF64 */
    732 func elfhash(name string) uint32 {
    733 	var h uint32
    734 	for i := 0; i < len(name); i++ {
    735 		h = (h << 4) + uint32(name[i])
    736 		if g := h & 0xf0000000; g != 0 {
    737 			h ^= g >> 24
    738 		}
    739 		h &= 0x0fffffff
    740 	}
    741 	return h
    742 }
    743 
    744 func Elfwritedynent(ctxt *Link, s *sym.Symbol, tag int, val uint64) {
    745 	if elf64 {
    746 		s.AddUint64(ctxt.Arch, uint64(tag))
    747 		s.AddUint64(ctxt.Arch, val)
    748 	} else {
    749 		s.AddUint32(ctxt.Arch, uint32(tag))
    750 		s.AddUint32(ctxt.Arch, uint32(val))
    751 	}
    752 }
    753 
    754 func elfwritedynentsym(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol) {
    755 	Elfwritedynentsymplus(ctxt, s, tag, t, 0)
    756 }
    757 
    758 func Elfwritedynentsymplus(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol, add int64) {
    759 	if elf64 {
    760 		s.AddUint64(ctxt.Arch, uint64(tag))
    761 	} else {
    762 		s.AddUint32(ctxt.Arch, uint32(tag))
    763 	}
    764 	s.AddAddrPlus(ctxt.Arch, t, add)
    765 }
    766 
    767 func elfwritedynentsymsize(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol) {
    768 	if elf64 {
    769 		s.AddUint64(ctxt.Arch, uint64(tag))
    770 	} else {
    771 		s.AddUint32(ctxt.Arch, uint32(tag))
    772 	}
    773 	s.AddSize(ctxt.Arch, t)
    774 }
    775 
    776 func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int {
    777 	interp = p
    778 	n := len(interp) + 1
    779 	sh.addr = startva + resoff - uint64(n)
    780 	sh.off = resoff - uint64(n)
    781 	sh.size = uint64(n)
    782 
    783 	return n
    784 }
    785 
    786 func elfwriteinterp(out *OutBuf) int {
    787 	sh := elfshname(".interp")
    788 	out.SeekSet(int64(sh.off))
    789 	out.WriteString(interp)
    790 	out.Write8(0)
    791 	return int(sh.size)
    792 }
    793 
    794 func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int, alloc bool) int {
    795 	n := 3*4 + uint64(sz) + resoff%4
    796 
    797 	sh.type_ = SHT_NOTE
    798 	if alloc {
    799 		sh.flags = SHF_ALLOC
    800 	}
    801 	sh.addralign = 4
    802 	sh.addr = startva + resoff - n
    803 	sh.off = resoff - n
    804 	sh.size = n - resoff%4
    805 
    806 	return int(n)
    807 }
    808 
    809 func elfwritenotehdr(out *OutBuf, str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr {
    810 	sh := elfshname(str)
    811 
    812 	// Write Elf_Note header.
    813 	out.SeekSet(int64(sh.off))
    814 
    815 	out.Write32(namesz)
    816 	out.Write32(descsz)
    817 	out.Write32(tag)
    818 
    819 	return sh
    820 }
    821 
    822 // NetBSD Signature (as per sys/exec_elf.h)
    823 const (
    824 	ELF_NOTE_NETBSD_NAMESZ  = 7
    825 	ELF_NOTE_NETBSD_DESCSZ  = 4
    826 	ELF_NOTE_NETBSD_TAG     = 1
    827 	ELF_NOTE_NETBSD_VERSION = 599000000 /* NetBSD 5.99 */
    828 )
    829 
    830 var ELF_NOTE_NETBSD_NAME = []byte("NetBSD\x00")
    831 
    832 func elfnetbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
    833 	n := int(Rnd(ELF_NOTE_NETBSD_NAMESZ, 4) + Rnd(ELF_NOTE_NETBSD_DESCSZ, 4))
    834 	return elfnote(sh, startva, resoff, n, true)
    835 }
    836 
    837 func elfwritenetbsdsig(out *OutBuf) int {
    838 	// Write Elf_Note header.
    839 	sh := elfwritenotehdr(out, ".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG)
    840 
    841 	if sh == nil {
    842 		return 0
    843 	}
    844 
    845 	// Followed by NetBSD string and version.
    846 	out.Write(ELF_NOTE_NETBSD_NAME)
    847 	out.Write8(0)
    848 	out.Write32(ELF_NOTE_NETBSD_VERSION)
    849 
    850 	return int(sh.size)
    851 }
    852 
    853 // OpenBSD Signature
    854 const (
    855 	ELF_NOTE_OPENBSD_NAMESZ  = 8
    856 	ELF_NOTE_OPENBSD_DESCSZ  = 4
    857 	ELF_NOTE_OPENBSD_TAG     = 1
    858 	ELF_NOTE_OPENBSD_VERSION = 0
    859 )
    860 
    861 var ELF_NOTE_OPENBSD_NAME = []byte("OpenBSD\x00")
    862 
    863 func elfopenbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
    864 	n := ELF_NOTE_OPENBSD_NAMESZ + ELF_NOTE_OPENBSD_DESCSZ
    865 	return elfnote(sh, startva, resoff, n, true)
    866 }
    867 
    868 func elfwriteopenbsdsig(out *OutBuf) int {
    869 	// Write Elf_Note header.
    870 	sh := elfwritenotehdr(out, ".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG)
    871 
    872 	if sh == nil {
    873 		return 0
    874 	}
    875 
    876 	// Followed by OpenBSD string and version.
    877 	out.Write(ELF_NOTE_OPENBSD_NAME)
    878 
    879 	out.Write32(ELF_NOTE_OPENBSD_VERSION)
    880 
    881 	return int(sh.size)
    882 }
    883 
    884 func addbuildinfo(val string) {
    885 	if !strings.HasPrefix(val, "0x") {
    886 		Exitf("-B argument must start with 0x: %s", val)
    887 	}
    888 
    889 	ov := val
    890 	val = val[2:]
    891 
    892 	const maxLen = 32
    893 	if hex.DecodedLen(len(val)) > maxLen {
    894 		Exitf("-B option too long (max %d digits): %s", maxLen, ov)
    895 	}
    896 
    897 	b, err := hex.DecodeString(val)
    898 	if err != nil {
    899 		if err == hex.ErrLength {
    900 			Exitf("-B argument must have even number of digits: %s", ov)
    901 		}
    902 		if inv, ok := err.(hex.InvalidByteError); ok {
    903 			Exitf("-B argument contains invalid hex digit %c: %s", byte(inv), ov)
    904 		}
    905 		Exitf("-B argument contains invalid hex: %s", ov)
    906 	}
    907 
    908 	buildinfo = b
    909 }
    910 
    911 // Build info note
    912 const (
    913 	ELF_NOTE_BUILDINFO_NAMESZ = 4
    914 	ELF_NOTE_BUILDINFO_TAG    = 3
    915 )
    916 
    917 var ELF_NOTE_BUILDINFO_NAME = []byte("GNU\x00")
    918 
    919 func elfbuildinfo(sh *ElfShdr, startva uint64, resoff uint64) int {
    920 	n := int(ELF_NOTE_BUILDINFO_NAMESZ + Rnd(int64(len(buildinfo)), 4))
    921 	return elfnote(sh, startva, resoff, n, true)
    922 }
    923 
    924 func elfgobuildid(sh *ElfShdr, startva uint64, resoff uint64) int {
    925 	n := len(ELF_NOTE_GO_NAME) + int(Rnd(int64(len(*flagBuildid)), 4))
    926 	return elfnote(sh, startva, resoff, n, true)
    927 }
    928 
    929 func elfwritebuildinfo(out *OutBuf) int {
    930 	sh := elfwritenotehdr(out, ".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG)
    931 	if sh == nil {
    932 		return 0
    933 	}
    934 
    935 	out.Write(ELF_NOTE_BUILDINFO_NAME)
    936 	out.Write(buildinfo)
    937 	var zero = make([]byte, 4)
    938 	out.Write(zero[:int(Rnd(int64(len(buildinfo)), 4)-int64(len(buildinfo)))])
    939 
    940 	return int(sh.size)
    941 }
    942 
    943 func elfwritegobuildid(out *OutBuf) int {
    944 	sh := elfwritenotehdr(out, ".note.go.buildid", uint32(len(ELF_NOTE_GO_NAME)), uint32(len(*flagBuildid)), ELF_NOTE_GOBUILDID_TAG)
    945 	if sh == nil {
    946 		return 0
    947 	}
    948 
    949 	out.Write(ELF_NOTE_GO_NAME)
    950 	out.Write([]byte(*flagBuildid))
    951 	var zero = make([]byte, 4)
    952 	out.Write(zero[:int(Rnd(int64(len(*flagBuildid)), 4)-int64(len(*flagBuildid)))])
    953 
    954 	return int(sh.size)
    955 }
    956 
    957 // Go specific notes
    958 const (
    959 	ELF_NOTE_GOPKGLIST_TAG = 1
    960 	ELF_NOTE_GOABIHASH_TAG = 2
    961 	ELF_NOTE_GODEPS_TAG    = 3
    962 	ELF_NOTE_GOBUILDID_TAG = 4
    963 )
    964 
    965 var ELF_NOTE_GO_NAME = []byte("Go\x00\x00")
    966 
    967 var elfverneed int
    968 
    969 type Elfaux struct {
    970 	next *Elfaux
    971 	num  int
    972 	vers string
    973 }
    974 
    975 type Elflib struct {
    976 	next *Elflib
    977 	aux  *Elfaux
    978 	file string
    979 }
    980 
    981 func addelflib(list **Elflib, file string, vers string) *Elfaux {
    982 	var lib *Elflib
    983 
    984 	for lib = *list; lib != nil; lib = lib.next {
    985 		if lib.file == file {
    986 			goto havelib
    987 		}
    988 	}
    989 	lib = new(Elflib)
    990 	lib.next = *list
    991 	lib.file = file
    992 	*list = lib
    993 
    994 havelib:
    995 	for aux := lib.aux; aux != nil; aux = aux.next {
    996 		if aux.vers == vers {
    997 			return aux
    998 		}
    999 	}
   1000 	aux := new(Elfaux)
   1001 	aux.next = lib.aux
   1002 	aux.vers = vers
   1003 	lib.aux = aux
   1004 
   1005 	return aux
   1006 }
   1007 
   1008 func elfdynhash(ctxt *Link) {
   1009 	if !ctxt.IsELF {
   1010 		return
   1011 	}
   1012 
   1013 	nsym := Nelfsym
   1014 	s := ctxt.Syms.Lookup(".hash", 0)
   1015 	s.Type = sym.SELFROSECT
   1016 	s.Attr |= sym.AttrReachable
   1017 
   1018 	i := nsym
   1019 	nbucket := 1
   1020 	for i > 0 {
   1021 		nbucket++
   1022 		i >>= 1
   1023 	}
   1024 
   1025 	var needlib *Elflib
   1026 	need := make([]*Elfaux, nsym)
   1027 	chain := make([]uint32, nsym)
   1028 	buckets := make([]uint32, nbucket)
   1029 
   1030 	for _, sy := range ctxt.Syms.Allsym {
   1031 		if sy.Dynid <= 0 {
   1032 			continue
   1033 		}
   1034 
   1035 		if sy.Dynimpvers != "" {
   1036 			need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib, sy.Dynimpvers)
   1037 		}
   1038 
   1039 		name := sy.Extname
   1040 		hc := elfhash(name)
   1041 
   1042 		b := hc % uint32(nbucket)
   1043 		chain[sy.Dynid] = buckets[b]
   1044 		buckets[b] = uint32(sy.Dynid)
   1045 	}
   1046 
   1047 	// s390x (ELF64) hash table entries are 8 bytes
   1048 	if ctxt.Arch.Family == sys.S390X {
   1049 		s.AddUint64(ctxt.Arch, uint64(nbucket))
   1050 		s.AddUint64(ctxt.Arch, uint64(nsym))
   1051 		for i := 0; i < nbucket; i++ {
   1052 			s.AddUint64(ctxt.Arch, uint64(buckets[i]))
   1053 		}
   1054 		for i := 0; i < nsym; i++ {
   1055 			s.AddUint64(ctxt.Arch, uint64(chain[i]))
   1056 		}
   1057 	} else {
   1058 		s.AddUint32(ctxt.Arch, uint32(nbucket))
   1059 		s.AddUint32(ctxt.Arch, uint32(nsym))
   1060 		for i := 0; i < nbucket; i++ {
   1061 			s.AddUint32(ctxt.Arch, buckets[i])
   1062 		}
   1063 		for i := 0; i < nsym; i++ {
   1064 			s.AddUint32(ctxt.Arch, chain[i])
   1065 		}
   1066 	}
   1067 
   1068 	// version symbols
   1069 	dynstr := ctxt.Syms.Lookup(".dynstr", 0)
   1070 
   1071 	s = ctxt.Syms.Lookup(".gnu.version_r", 0)
   1072 	i = 2
   1073 	nfile := 0
   1074 	for l := needlib; l != nil; l = l.next {
   1075 		nfile++
   1076 
   1077 		// header
   1078 		s.AddUint16(ctxt.Arch, 1) // table version
   1079 		j := 0
   1080 		for x := l.aux; x != nil; x = x.next {
   1081 			j++
   1082 		}
   1083 		s.AddUint16(ctxt.Arch, uint16(j))                         // aux count
   1084 		s.AddUint32(ctxt.Arch, uint32(Addstring(dynstr, l.file))) // file string offset
   1085 		s.AddUint32(ctxt.Arch, 16)                                // offset from header to first aux
   1086 		if l.next != nil {
   1087 			s.AddUint32(ctxt.Arch, 16+uint32(j)*16) // offset from this header to next
   1088 		} else {
   1089 			s.AddUint32(ctxt.Arch, 0)
   1090 		}
   1091 
   1092 		for x := l.aux; x != nil; x = x.next {
   1093 			x.num = i
   1094 			i++
   1095 
   1096 			// aux struct
   1097 			s.AddUint32(ctxt.Arch, elfhash(x.vers))                   // hash
   1098 			s.AddUint16(ctxt.Arch, 0)                                 // flags
   1099 			s.AddUint16(ctxt.Arch, uint16(x.num))                     // other - index we refer to this by
   1100 			s.AddUint32(ctxt.Arch, uint32(Addstring(dynstr, x.vers))) // version string offset
   1101 			if x.next != nil {
   1102 				s.AddUint32(ctxt.Arch, 16) // offset from this aux to next
   1103 			} else {
   1104 				s.AddUint32(ctxt.Arch, 0)
   1105 			}
   1106 		}
   1107 	}
   1108 
   1109 	// version references
   1110 	s = ctxt.Syms.Lookup(".gnu.version", 0)
   1111 
   1112 	for i := 0; i < nsym; i++ {
   1113 		if i == 0 {
   1114 			s.AddUint16(ctxt.Arch, 0) // first entry - no symbol
   1115 		} else if need[i] == nil {
   1116 			s.AddUint16(ctxt.Arch, 1) // global
   1117 		} else {
   1118 			s.AddUint16(ctxt.Arch, uint16(need[i].num))
   1119 		}
   1120 	}
   1121 
   1122 	s = ctxt.Syms.Lookup(".dynamic", 0)
   1123 	elfverneed = nfile
   1124 	if elfverneed != 0 {
   1125 		elfwritedynentsym(ctxt, s, DT_VERNEED, ctxt.Syms.Lookup(".gnu.version_r", 0))
   1126 		Elfwritedynent(ctxt, s, DT_VERNEEDNUM, uint64(nfile))
   1127 		elfwritedynentsym(ctxt, s, DT_VERSYM, ctxt.Syms.Lookup(".gnu.version", 0))
   1128 	}
   1129 
   1130 	sy := ctxt.Syms.Lookup(elfRelType+".plt", 0)
   1131 	if sy.Size > 0 {
   1132 		if elfRelType == ".rela" {
   1133 			Elfwritedynent(ctxt, s, DT_PLTREL, DT_RELA)
   1134 		} else {
   1135 			Elfwritedynent(ctxt, s, DT_PLTREL, DT_REL)
   1136 		}
   1137 		elfwritedynentsymsize(ctxt, s, DT_PLTRELSZ, sy)
   1138 		elfwritedynentsym(ctxt, s, DT_JMPREL, sy)
   1139 	}
   1140 
   1141 	Elfwritedynent(ctxt, s, DT_NULL, 0)
   1142 }
   1143 
   1144 func elfphload(seg *sym.Segment) *ElfPhdr {
   1145 	ph := newElfPhdr()
   1146 	ph.type_ = PT_LOAD
   1147 	if seg.Rwx&4 != 0 {
   1148 		ph.flags |= PF_R
   1149 	}
   1150 	if seg.Rwx&2 != 0 {
   1151 		ph.flags |= PF_W
   1152 	}
   1153 	if seg.Rwx&1 != 0 {
   1154 		ph.flags |= PF_X
   1155 	}
   1156 	ph.vaddr = seg.Vaddr
   1157 	ph.paddr = seg.Vaddr
   1158 	ph.memsz = seg.Length
   1159 	ph.off = seg.Fileoff
   1160 	ph.filesz = seg.Filelen
   1161 	ph.align = uint64(*FlagRound)
   1162 
   1163 	return ph
   1164 }
   1165 
   1166 func elfphrelro(seg *sym.Segment) {
   1167 	ph := newElfPhdr()
   1168 	ph.type_ = PT_GNU_RELRO
   1169 	ph.vaddr = seg.Vaddr
   1170 	ph.paddr = seg.Vaddr
   1171 	ph.memsz = seg.Length
   1172 	ph.off = seg.Fileoff
   1173 	ph.filesz = seg.Filelen
   1174 	ph.align = uint64(*FlagRound)
   1175 }
   1176 
   1177 func elfshname(name string) *ElfShdr {
   1178 	for i := 0; i < nelfstr; i++ {
   1179 		if name != elfstr[i].s {
   1180 			continue
   1181 		}
   1182 		off := elfstr[i].off
   1183 		for i = 0; i < int(ehdr.shnum); i++ {
   1184 			sh := shdr[i]
   1185 			if sh.name == uint32(off) {
   1186 				return sh
   1187 			}
   1188 		}
   1189 		return newElfShdr(int64(off))
   1190 	}
   1191 	Exitf("cannot find elf name %s", name)
   1192 	return nil
   1193 }
   1194 
   1195 // Create an ElfShdr for the section with name.
   1196 // Create a duplicate if one already exists with that name
   1197 func elfshnamedup(name string) *ElfShdr {
   1198 	for i := 0; i < nelfstr; i++ {
   1199 		if name == elfstr[i].s {
   1200 			off := elfstr[i].off
   1201 			return newElfShdr(int64(off))
   1202 		}
   1203 	}
   1204 
   1205 	Errorf(nil, "cannot find elf name %s", name)
   1206 	errorexit()
   1207 	return nil
   1208 }
   1209 
   1210 func elfshalloc(sect *sym.Section) *ElfShdr {
   1211 	sh := elfshname(sect.Name)
   1212 	sect.Elfsect = sh
   1213 	return sh
   1214 }
   1215 
   1216 func elfshbits(linkmode LinkMode, sect *sym.Section) *ElfShdr {
   1217 	var sh *ElfShdr
   1218 
   1219 	if sect.Name == ".text" {
   1220 		if sect.Elfsect == nil {
   1221 			sect.Elfsect = elfshnamedup(sect.Name)
   1222 		}
   1223 		sh = sect.Elfsect.(*ElfShdr)
   1224 	} else {
   1225 		sh = elfshalloc(sect)
   1226 	}
   1227 
   1228 	// If this section has already been set up as a note, we assume type_ and
   1229 	// flags are already correct, but the other fields still need filling in.
   1230 	if sh.type_ == SHT_NOTE {
   1231 		if linkmode != LinkExternal {
   1232 			// TODO(mwhudson): the approach here will work OK when
   1233 			// linking internally for notes that we want to be included
   1234 			// in a loadable segment (e.g. the abihash note) but not for
   1235 			// notes that we do not want to be mapped (e.g. the package
   1236 			// list note). The real fix is probably to define new values
   1237 			// for Symbol.Type corresponding to mapped and unmapped notes
   1238 			// and handle them in dodata().
   1239 			Errorf(nil, "sh.type_ == SHT_NOTE in elfshbits when linking internally")
   1240 		}
   1241 		sh.addralign = uint64(sect.Align)
   1242 		sh.size = sect.Length
   1243 		sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
   1244 		return sh
   1245 	}
   1246 	if sh.type_ > 0 {
   1247 		return sh
   1248 	}
   1249 
   1250 	if sect.Vaddr < sect.Seg.Vaddr+sect.Seg.Filelen {
   1251 		sh.type_ = SHT_PROGBITS
   1252 	} else {
   1253 		sh.type_ = SHT_NOBITS
   1254 	}
   1255 	sh.flags = SHF_ALLOC
   1256 	if sect.Rwx&1 != 0 {
   1257 		sh.flags |= SHF_EXECINSTR
   1258 	}
   1259 	if sect.Rwx&2 != 0 {
   1260 		sh.flags |= SHF_WRITE
   1261 	}
   1262 	if sect.Name == ".tbss" {
   1263 		sh.flags |= SHF_TLS
   1264 		sh.type_ = SHT_NOBITS
   1265 	}
   1266 	if strings.HasPrefix(sect.Name, ".debug") {
   1267 		sh.flags = 0
   1268 	}
   1269 
   1270 	if linkmode != LinkExternal {
   1271 		sh.addr = sect.Vaddr
   1272 	}
   1273 	sh.addralign = uint64(sect.Align)
   1274 	sh.size = sect.Length
   1275 	if sect.Name != ".tbss" {
   1276 		sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
   1277 	}
   1278 
   1279 	return sh
   1280 }
   1281 
   1282 func elfshreloc(arch *sys.Arch, sect *sym.Section) *ElfShdr {
   1283 	// If main section is SHT_NOBITS, nothing to relocate.
   1284 	// Also nothing to relocate in .shstrtab or notes.
   1285 	if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
   1286 		return nil
   1287 	}
   1288 	if sect.Name == ".shstrtab" || sect.Name == ".tbss" {
   1289 		return nil
   1290 	}
   1291 	if sect.Elfsect.(*ElfShdr).type_ == SHT_NOTE {
   1292 		return nil
   1293 	}
   1294 
   1295 	var typ int
   1296 	if elfRelType == ".rela" {
   1297 		typ = SHT_RELA
   1298 	} else {
   1299 		typ = SHT_REL
   1300 	}
   1301 
   1302 	sh := elfshname(elfRelType + sect.Name)
   1303 	// There could be multiple text sections but each needs
   1304 	// its own .rela.text.
   1305 
   1306 	if sect.Name == ".text" {
   1307 		if sh.info != 0 && sh.info != uint32(sect.Elfsect.(*ElfShdr).shnum) {
   1308 			sh = elfshnamedup(elfRelType + sect.Name)
   1309 		}
   1310 	}
   1311 
   1312 	sh.type_ = uint32(typ)
   1313 	sh.entsize = uint64(arch.RegSize) * 2
   1314 	if typ == SHT_RELA {
   1315 		sh.entsize += uint64(arch.RegSize)
   1316 	}
   1317 	sh.link = uint32(elfshname(".symtab").shnum)
   1318 	sh.info = uint32(sect.Elfsect.(*ElfShdr).shnum)
   1319 	sh.off = sect.Reloff
   1320 	sh.size = sect.Rellen
   1321 	sh.addralign = uint64(arch.RegSize)
   1322 	return sh
   1323 }
   1324 
   1325 func elfrelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) {
   1326 	// If main section is SHT_NOBITS, nothing to relocate.
   1327 	// Also nothing to relocate in .shstrtab.
   1328 	if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
   1329 		return
   1330 	}
   1331 	if sect.Name == ".shstrtab" {
   1332 		return
   1333 	}
   1334 
   1335 	sect.Reloff = uint64(ctxt.Out.Offset())
   1336 	for i, s := range syms {
   1337 		if !s.Attr.Reachable() {
   1338 			continue
   1339 		}
   1340 		if uint64(s.Value) >= sect.Vaddr {
   1341 			syms = syms[i:]
   1342 			break
   1343 		}
   1344 	}
   1345 
   1346 	eaddr := int32(sect.Vaddr + sect.Length)
   1347 	for _, s := range syms {
   1348 		if !s.Attr.Reachable() {
   1349 			continue
   1350 		}
   1351 		if s.Value >= int64(eaddr) {
   1352 			break
   1353 		}
   1354 		for ri := 0; ri < len(s.R); ri++ {
   1355 			r := &s.R[ri]
   1356 			if r.Done {
   1357 				continue
   1358 			}
   1359 			if r.Xsym == nil {
   1360 				Errorf(s, "missing xsym in relocation %#v %#v", r.Sym.Name, s)
   1361 				continue
   1362 			}
   1363 			if r.Xsym.ElfsymForReloc() == 0 {
   1364 				Errorf(s, "reloc %d (%s) to non-elf symbol %s (outer=%s) %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Sym.Name, r.Xsym.Name, r.Sym.Type, r.Sym.Type)
   1365 			}
   1366 			if !r.Xsym.Attr.Reachable() {
   1367 				Errorf(s, "unreachable reloc %d (%s) target %v", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Xsym.Name)
   1368 			}
   1369 			if !Thearch.Elfreloc1(ctxt, r, int64(uint64(s.Value+int64(r.Off))-sect.Vaddr)) {
   1370 				Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name)
   1371 			}
   1372 		}
   1373 	}
   1374 
   1375 	sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
   1376 }
   1377 
   1378 func Elfemitreloc(ctxt *Link) {
   1379 	for ctxt.Out.Offset()&7 != 0 {
   1380 		ctxt.Out.Write8(0)
   1381 	}
   1382 
   1383 	for _, sect := range Segtext.Sections {
   1384 		if sect.Name == ".text" {
   1385 			elfrelocsect(ctxt, sect, ctxt.Textp)
   1386 		} else {
   1387 			elfrelocsect(ctxt, sect, datap)
   1388 		}
   1389 	}
   1390 
   1391 	for _, sect := range Segrodata.Sections {
   1392 		elfrelocsect(ctxt, sect, datap)
   1393 	}
   1394 	for _, sect := range Segrelrodata.Sections {
   1395 		elfrelocsect(ctxt, sect, datap)
   1396 	}
   1397 	for _, sect := range Segdata.Sections {
   1398 		elfrelocsect(ctxt, sect, datap)
   1399 	}
   1400 	for _, sect := range Segdwarf.Sections {
   1401 		elfrelocsect(ctxt, sect, dwarfp)
   1402 	}
   1403 }
   1404 
   1405 func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) {
   1406 	s := ctxt.Syms.Lookup(sectionName, 0)
   1407 	s.Attr |= sym.AttrReachable
   1408 	s.Type = sym.SELFROSECT
   1409 	// namesz
   1410 	s.AddUint32(ctxt.Arch, uint32(len(ELF_NOTE_GO_NAME)))
   1411 	// descsz
   1412 	s.AddUint32(ctxt.Arch, uint32(len(desc)))
   1413 	// tag
   1414 	s.AddUint32(ctxt.Arch, tag)
   1415 	// name + padding
   1416 	s.P = append(s.P, ELF_NOTE_GO_NAME...)
   1417 	for len(s.P)%4 != 0 {
   1418 		s.P = append(s.P, 0)
   1419 	}
   1420 	// desc + padding
   1421 	s.P = append(s.P, desc...)
   1422 	for len(s.P)%4 != 0 {
   1423 		s.P = append(s.P, 0)
   1424 	}
   1425 	s.Size = int64(len(s.P))
   1426 	s.Align = 4
   1427 }
   1428 
   1429 func (ctxt *Link) doelf() {
   1430 	if !ctxt.IsELF {
   1431 		return
   1432 	}
   1433 
   1434 	/* predefine strings we need for section headers */
   1435 	shstrtab := ctxt.Syms.Lookup(".shstrtab", 0)
   1436 
   1437 	shstrtab.Type = sym.SELFROSECT
   1438 	shstrtab.Attr |= sym.AttrReachable
   1439 
   1440 	Addstring(shstrtab, "")
   1441 	Addstring(shstrtab, ".text")
   1442 	Addstring(shstrtab, ".noptrdata")
   1443 	Addstring(shstrtab, ".data")
   1444 	Addstring(shstrtab, ".bss")
   1445 	Addstring(shstrtab, ".noptrbss")
   1446 
   1447 	// generate .tbss section for dynamic internal linker or external
   1448 	// linking, so that various binutils could correctly calculate
   1449 	// PT_TLS size. See https://golang.org/issue/5200.
   1450 	if !*FlagD || ctxt.LinkMode == LinkExternal {
   1451 		Addstring(shstrtab, ".tbss")
   1452 	}
   1453 	if ctxt.HeadType == objabi.Hnetbsd {
   1454 		Addstring(shstrtab, ".note.netbsd.ident")
   1455 	}
   1456 	if ctxt.HeadType == objabi.Hopenbsd {
   1457 		Addstring(shstrtab, ".note.openbsd.ident")
   1458 	}
   1459 	if len(buildinfo) > 0 {
   1460 		Addstring(shstrtab, ".note.gnu.build-id")
   1461 	}
   1462 	if *flagBuildid != "" {
   1463 		Addstring(shstrtab, ".note.go.buildid")
   1464 	}
   1465 	Addstring(shstrtab, ".elfdata")
   1466 	Addstring(shstrtab, ".rodata")
   1467 	// See the comment about data.rel.ro.FOO section names in data.go.
   1468 	relro_prefix := ""
   1469 	if ctxt.UseRelro() {
   1470 		Addstring(shstrtab, ".data.rel.ro")
   1471 		relro_prefix = ".data.rel.ro"
   1472 	}
   1473 	Addstring(shstrtab, relro_prefix+".typelink")
   1474 	Addstring(shstrtab, relro_prefix+".itablink")
   1475 	Addstring(shstrtab, relro_prefix+".gosymtab")
   1476 	Addstring(shstrtab, relro_prefix+".gopclntab")
   1477 
   1478 	if ctxt.LinkMode == LinkExternal {
   1479 		*FlagD = true
   1480 
   1481 		Addstring(shstrtab, elfRelType+".text")
   1482 		Addstring(shstrtab, elfRelType+".rodata")
   1483 		Addstring(shstrtab, elfRelType+relro_prefix+".typelink")
   1484 		Addstring(shstrtab, elfRelType+relro_prefix+".itablink")
   1485 		Addstring(shstrtab, elfRelType+relro_prefix+".gosymtab")
   1486 		Addstring(shstrtab, elfRelType+relro_prefix+".gopclntab")
   1487 		Addstring(shstrtab, elfRelType+".noptrdata")
   1488 		Addstring(shstrtab, elfRelType+".data")
   1489 		if ctxt.UseRelro() {
   1490 			Addstring(shstrtab, elfRelType+".data.rel.ro")
   1491 		}
   1492 
   1493 		// add a .note.GNU-stack section to mark the stack as non-executable
   1494 		Addstring(shstrtab, ".note.GNU-stack")
   1495 
   1496 		if ctxt.BuildMode == BuildModeShared {
   1497 			Addstring(shstrtab, ".note.go.abihash")
   1498 			Addstring(shstrtab, ".note.go.pkg-list")
   1499 			Addstring(shstrtab, ".note.go.deps")
   1500 		}
   1501 	}
   1502 
   1503 	hasinitarr := ctxt.linkShared
   1504 
   1505 	/* shared library initializer */
   1506 	switch ctxt.BuildMode {
   1507 	case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin:
   1508 		hasinitarr = true
   1509 	}
   1510 
   1511 	if hasinitarr {
   1512 		Addstring(shstrtab, ".init_array")
   1513 		Addstring(shstrtab, elfRelType+".init_array")
   1514 	}
   1515 
   1516 	if !*FlagS {
   1517 		Addstring(shstrtab, ".symtab")
   1518 		Addstring(shstrtab, ".strtab")
   1519 		dwarfaddshstrings(ctxt, shstrtab)
   1520 	}
   1521 
   1522 	Addstring(shstrtab, ".shstrtab")
   1523 
   1524 	if !*FlagD { /* -d suppresses dynamic loader format */
   1525 		Addstring(shstrtab, ".interp")
   1526 		Addstring(shstrtab, ".hash")
   1527 		Addstring(shstrtab, ".got")
   1528 		if ctxt.Arch.Family == sys.PPC64 {
   1529 			Addstring(shstrtab, ".glink")
   1530 		}
   1531 		Addstring(shstrtab, ".got.plt")
   1532 		Addstring(shstrtab, ".dynamic")
   1533 		Addstring(shstrtab, ".dynsym")
   1534 		Addstring(shstrtab, ".dynstr")
   1535 		Addstring(shstrtab, elfRelType)
   1536 		Addstring(shstrtab, elfRelType+".plt")
   1537 
   1538 		Addstring(shstrtab, ".plt")
   1539 		Addstring(shstrtab, ".gnu.version")
   1540 		Addstring(shstrtab, ".gnu.version_r")
   1541 
   1542 		/* dynamic symbol table - first entry all zeros */
   1543 		s := ctxt.Syms.Lookup(".dynsym", 0)
   1544 
   1545 		s.Type = sym.SELFROSECT
   1546 		s.Attr |= sym.AttrReachable
   1547 		if elf64 {
   1548 			s.Size += ELF64SYMSIZE
   1549 		} else {
   1550 			s.Size += ELF32SYMSIZE
   1551 		}
   1552 
   1553 		/* dynamic string table */
   1554 		s = ctxt.Syms.Lookup(".dynstr", 0)
   1555 
   1556 		s.Type = sym.SELFROSECT
   1557 		s.Attr |= sym.AttrReachable
   1558 		if s.Size == 0 {
   1559 			Addstring(s, "")
   1560 		}
   1561 		dynstr := s
   1562 
   1563 		/* relocation table */
   1564 		s = ctxt.Syms.Lookup(elfRelType, 0)
   1565 		s.Attr |= sym.AttrReachable
   1566 		s.Type = sym.SELFROSECT
   1567 
   1568 		/* global offset table */
   1569 		s = ctxt.Syms.Lookup(".got", 0)
   1570 
   1571 		s.Attr |= sym.AttrReachable
   1572 		s.Type = sym.SELFGOT // writable
   1573 
   1574 		/* ppc64 glink resolver */
   1575 		if ctxt.Arch.Family == sys.PPC64 {
   1576 			s := ctxt.Syms.Lookup(".glink", 0)
   1577 			s.Attr |= sym.AttrReachable
   1578 			s.Type = sym.SELFRXSECT
   1579 		}
   1580 
   1581 		/* hash */
   1582 		s = ctxt.Syms.Lookup(".hash", 0)
   1583 
   1584 		s.Attr |= sym.AttrReachable
   1585 		s.Type = sym.SELFROSECT
   1586 
   1587 		s = ctxt.Syms.Lookup(".got.plt", 0)
   1588 		s.Attr |= sym.AttrReachable
   1589 		s.Type = sym.SELFSECT // writable
   1590 
   1591 		s = ctxt.Syms.Lookup(".plt", 0)
   1592 
   1593 		s.Attr |= sym.AttrReachable
   1594 		if ctxt.Arch.Family == sys.PPC64 {
   1595 			// In the ppc64 ABI, .plt is a data section
   1596 			// written by the dynamic linker.
   1597 			s.Type = sym.SELFSECT
   1598 		} else {
   1599 			s.Type = sym.SELFRXSECT
   1600 		}
   1601 
   1602 		Thearch.Elfsetupplt(ctxt)
   1603 
   1604 		s = ctxt.Syms.Lookup(elfRelType+".plt", 0)
   1605 		s.Attr |= sym.AttrReachable
   1606 		s.Type = sym.SELFROSECT
   1607 
   1608 		s = ctxt.Syms.Lookup(".gnu.version", 0)
   1609 		s.Attr |= sym.AttrReachable
   1610 		s.Type = sym.SELFROSECT
   1611 
   1612 		s = ctxt.Syms.Lookup(".gnu.version_r", 0)
   1613 		s.Attr |= sym.AttrReachable
   1614 		s.Type = sym.SELFROSECT
   1615 
   1616 		/* define dynamic elf table */
   1617 		s = ctxt.Syms.Lookup(".dynamic", 0)
   1618 
   1619 		s.Attr |= sym.AttrReachable
   1620 		s.Type = sym.SELFSECT // writable
   1621 
   1622 		/*
   1623 		 * .dynamic table
   1624 		 */
   1625 		elfwritedynentsym(ctxt, s, DT_HASH, ctxt.Syms.Lookup(".hash", 0))
   1626 
   1627 		elfwritedynentsym(ctxt, s, DT_SYMTAB, ctxt.Syms.Lookup(".dynsym", 0))
   1628 		if elf64 {
   1629 			Elfwritedynent(ctxt, s, DT_SYMENT, ELF64SYMSIZE)
   1630 		} else {
   1631 			Elfwritedynent(ctxt, s, DT_SYMENT, ELF32SYMSIZE)
   1632 		}
   1633 		elfwritedynentsym(ctxt, s, DT_STRTAB, ctxt.Syms.Lookup(".dynstr", 0))
   1634 		elfwritedynentsymsize(ctxt, s, DT_STRSZ, ctxt.Syms.Lookup(".dynstr", 0))
   1635 		if elfRelType == ".rela" {
   1636 			elfwritedynentsym(ctxt, s, DT_RELA, ctxt.Syms.Lookup(".rela", 0))
   1637 			elfwritedynentsymsize(ctxt, s, DT_RELASZ, ctxt.Syms.Lookup(".rela", 0))
   1638 			Elfwritedynent(ctxt, s, DT_RELAENT, ELF64RELASIZE)
   1639 		} else {
   1640 			elfwritedynentsym(ctxt, s, DT_REL, ctxt.Syms.Lookup(".rel", 0))
   1641 			elfwritedynentsymsize(ctxt, s, DT_RELSZ, ctxt.Syms.Lookup(".rel", 0))
   1642 			Elfwritedynent(ctxt, s, DT_RELENT, ELF32RELSIZE)
   1643 		}
   1644 
   1645 		if rpath.val != "" {
   1646 			Elfwritedynent(ctxt, s, DT_RUNPATH, uint64(Addstring(dynstr, rpath.val)))
   1647 		}
   1648 
   1649 		if ctxt.Arch.Family == sys.PPC64 {
   1650 			elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".plt", 0))
   1651 		} else if ctxt.Arch.Family == sys.S390X {
   1652 			elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".got", 0))
   1653 		} else {
   1654 			elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".got.plt", 0))
   1655 		}
   1656 
   1657 		if ctxt.Arch.Family == sys.PPC64 {
   1658 			Elfwritedynent(ctxt, s, DT_PPC64_OPT, 0)
   1659 		}
   1660 
   1661 		// Solaris dynamic linker can't handle an empty .rela.plt if
   1662 		// DT_JMPREL is emitted so we have to defer generation of DT_PLTREL,
   1663 		// DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the
   1664 		// size of .rel(a).plt section.
   1665 		Elfwritedynent(ctxt, s, DT_DEBUG, 0)
   1666 	}
   1667 
   1668 	if ctxt.BuildMode == BuildModeShared {
   1669 		// The go.link.abihashbytes symbol will be pointed at the appropriate
   1670 		// part of the .note.go.abihash section in data.go:func address().
   1671 		s := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
   1672 		s.Attr |= sym.AttrLocal
   1673 		s.Type = sym.SRODATA
   1674 		s.Attr |= sym.AttrSpecial
   1675 		s.Attr |= sym.AttrReachable
   1676 		s.Size = int64(sha1.Size)
   1677 
   1678 		sort.Sort(byPkg(ctxt.Library))
   1679 		h := sha1.New()
   1680 		for _, l := range ctxt.Library {
   1681 			io.WriteString(h, l.Hash)
   1682 		}
   1683 		addgonote(ctxt, ".note.go.abihash", ELF_NOTE_GOABIHASH_TAG, h.Sum([]byte{}))
   1684 		addgonote(ctxt, ".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, pkglistfornote)
   1685 		var deplist []string
   1686 		for _, shlib := range ctxt.Shlibs {
   1687 			deplist = append(deplist, filepath.Base(shlib.Path))
   1688 		}
   1689 		addgonote(ctxt, ".note.go.deps", ELF_NOTE_GODEPS_TAG, []byte(strings.Join(deplist, "\n")))
   1690 	}
   1691 
   1692 	if ctxt.LinkMode == LinkExternal && *flagBuildid != "" {
   1693 		addgonote(ctxt, ".note.go.buildid", ELF_NOTE_GOBUILDID_TAG, []byte(*flagBuildid))
   1694 	}
   1695 }
   1696 
   1697 // Do not write DT_NULL.  elfdynhash will finish it.
   1698 func shsym(sh *ElfShdr, s *sym.Symbol) {
   1699 	addr := Symaddr(s)
   1700 	if sh.flags&SHF_ALLOC != 0 {
   1701 		sh.addr = uint64(addr)
   1702 	}
   1703 	sh.off = uint64(datoff(s, addr))
   1704 	sh.size = uint64(s.Size)
   1705 }
   1706 
   1707 func phsh(ph *ElfPhdr, sh *ElfShdr) {
   1708 	ph.vaddr = sh.addr
   1709 	ph.paddr = ph.vaddr
   1710 	ph.off = sh.off
   1711 	ph.filesz = sh.size
   1712 	ph.memsz = sh.size
   1713 	ph.align = sh.addralign
   1714 }
   1715 
   1716 func Asmbelfsetup() {
   1717 	/* This null SHdr must appear before all others */
   1718 	elfshname("")
   1719 
   1720 	for _, sect := range Segtext.Sections {
   1721 		// There could be multiple .text sections. Instead check the Elfsect
   1722 		// field to determine if already has an ElfShdr and if not, create one.
   1723 		if sect.Name == ".text" {
   1724 			if sect.Elfsect == nil {
   1725 				sect.Elfsect = elfshnamedup(sect.Name)
   1726 			}
   1727 		} else {
   1728 			elfshalloc(sect)
   1729 		}
   1730 	}
   1731 	for _, sect := range Segrodata.Sections {
   1732 		elfshalloc(sect)
   1733 	}
   1734 	for _, sect := range Segrelrodata.Sections {
   1735 		elfshalloc(sect)
   1736 	}
   1737 	for _, sect := range Segdata.Sections {
   1738 		elfshalloc(sect)
   1739 	}
   1740 	for _, sect := range Segdwarf.Sections {
   1741 		elfshalloc(sect)
   1742 	}
   1743 }
   1744 
   1745 func Asmbelf(ctxt *Link, symo int64) {
   1746 	eh := getElfEhdr()
   1747 	switch ctxt.Arch.Family {
   1748 	default:
   1749 		Exitf("unknown architecture in asmbelf: %v", ctxt.Arch.Family)
   1750 	case sys.MIPS, sys.MIPS64:
   1751 		eh.machine = EM_MIPS
   1752 	case sys.ARM:
   1753 		eh.machine = EM_ARM
   1754 	case sys.AMD64:
   1755 		eh.machine = EM_X86_64
   1756 	case sys.ARM64:
   1757 		eh.machine = EM_AARCH64
   1758 	case sys.I386:
   1759 		eh.machine = EM_386
   1760 	case sys.PPC64:
   1761 		eh.machine = EM_PPC64
   1762 	case sys.S390X:
   1763 		eh.machine = EM_S390
   1764 	}
   1765 
   1766 	elfreserve := int64(ELFRESERVE)
   1767 
   1768 	numtext := int64(0)
   1769 	for _, sect := range Segtext.Sections {
   1770 		if sect.Name == ".text" {
   1771 			numtext++
   1772 		}
   1773 	}
   1774 
   1775 	// If there are multiple text sections, extra space is needed
   1776 	// in the elfreserve for the additional .text and .rela.text
   1777 	// section headers.  It can handle 4 extra now. Headers are
   1778 	// 64 bytes.
   1779 
   1780 	if numtext > 4 {
   1781 		elfreserve += elfreserve + numtext*64*2
   1782 	}
   1783 
   1784 	startva := *FlagTextAddr - int64(HEADR)
   1785 	resoff := elfreserve
   1786 
   1787 	var pph *ElfPhdr
   1788 	var pnote *ElfPhdr
   1789 	if ctxt.LinkMode == LinkExternal {
   1790 		/* skip program headers */
   1791 		eh.phoff = 0
   1792 
   1793 		eh.phentsize = 0
   1794 
   1795 		if ctxt.BuildMode == BuildModeShared {
   1796 			sh := elfshname(".note.go.pkg-list")
   1797 			sh.type_ = SHT_NOTE
   1798 			sh = elfshname(".note.go.abihash")
   1799 			sh.type_ = SHT_NOTE
   1800 			sh.flags = SHF_ALLOC
   1801 			sh = elfshname(".note.go.deps")
   1802 			sh.type_ = SHT_NOTE
   1803 		}
   1804 
   1805 		if *flagBuildid != "" {
   1806 			sh := elfshname(".note.go.buildid")
   1807 			sh.type_ = SHT_NOTE
   1808 			sh.flags = SHF_ALLOC
   1809 		}
   1810 
   1811 		goto elfobj
   1812 	}
   1813 
   1814 	/* program header info */
   1815 	pph = newElfPhdr()
   1816 
   1817 	pph.type_ = PT_PHDR
   1818 	pph.flags = PF_R
   1819 	pph.off = uint64(eh.ehsize)
   1820 	pph.vaddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off
   1821 	pph.paddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off
   1822 	pph.align = uint64(*FlagRound)
   1823 
   1824 	/*
   1825 	 * PHDR must be in a loaded segment. Adjust the text
   1826 	 * segment boundaries downwards to include it.
   1827 	 * Except on NaCl where it must not be loaded.
   1828 	 */
   1829 	if ctxt.HeadType != objabi.Hnacl {
   1830 		o := int64(Segtext.Vaddr - pph.vaddr)
   1831 		Segtext.Vaddr -= uint64(o)
   1832 		Segtext.Length += uint64(o)
   1833 		o = int64(Segtext.Fileoff - pph.off)
   1834 		Segtext.Fileoff -= uint64(o)
   1835 		Segtext.Filelen += uint64(o)
   1836 	}
   1837 
   1838 	if !*FlagD { /* -d suppresses dynamic loader format */
   1839 		/* interpreter */
   1840 		sh := elfshname(".interp")
   1841 
   1842 		sh.type_ = SHT_PROGBITS
   1843 		sh.flags = SHF_ALLOC
   1844 		sh.addralign = 1
   1845 		if interpreter == "" {
   1846 			switch ctxt.HeadType {
   1847 			case objabi.Hlinux:
   1848 				interpreter = Thearch.Linuxdynld
   1849 
   1850 			case objabi.Hfreebsd:
   1851 				interpreter = Thearch.Freebsddynld
   1852 
   1853 			case objabi.Hnetbsd:
   1854 				interpreter = Thearch.Netbsddynld
   1855 
   1856 			case objabi.Hopenbsd:
   1857 				interpreter = Thearch.Openbsddynld
   1858 
   1859 			case objabi.Hdragonfly:
   1860 				interpreter = Thearch.Dragonflydynld
   1861 
   1862 			case objabi.Hsolaris:
   1863 				interpreter = Thearch.Solarisdynld
   1864 			}
   1865 		}
   1866 
   1867 		resoff -= int64(elfinterp(sh, uint64(startva), uint64(resoff), interpreter))
   1868 
   1869 		ph := newElfPhdr()
   1870 		ph.type_ = PT_INTERP
   1871 		ph.flags = PF_R
   1872 		phsh(ph, sh)
   1873 	}
   1874 
   1875 	pnote = nil
   1876 	if ctxt.HeadType == objabi.Hnetbsd || ctxt.HeadType == objabi.Hopenbsd {
   1877 		var sh *ElfShdr
   1878 		switch ctxt.HeadType {
   1879 		case objabi.Hnetbsd:
   1880 			sh = elfshname(".note.netbsd.ident")
   1881 			resoff -= int64(elfnetbsdsig(sh, uint64(startva), uint64(resoff)))
   1882 
   1883 		case objabi.Hopenbsd:
   1884 			sh = elfshname(".note.openbsd.ident")
   1885 			resoff -= int64(elfopenbsdsig(sh, uint64(startva), uint64(resoff)))
   1886 		}
   1887 
   1888 		pnote = newElfPhdr()
   1889 		pnote.type_ = PT_NOTE
   1890 		pnote.flags = PF_R
   1891 		phsh(pnote, sh)
   1892 	}
   1893 
   1894 	if len(buildinfo) > 0 {
   1895 		sh := elfshname(".note.gnu.build-id")
   1896 		resoff -= int64(elfbuildinfo(sh, uint64(startva), uint64(resoff)))
   1897 
   1898 		if pnote == nil {
   1899 			pnote = newElfPhdr()
   1900 			pnote.type_ = PT_NOTE
   1901 			pnote.flags = PF_R
   1902 		}
   1903 
   1904 		phsh(pnote, sh)
   1905 	}
   1906 
   1907 	if *flagBuildid != "" {
   1908 		sh := elfshname(".note.go.buildid")
   1909 		resoff -= int64(elfgobuildid(sh, uint64(startva), uint64(resoff)))
   1910 
   1911 		pnote := newElfPhdr()
   1912 		pnote.type_ = PT_NOTE
   1913 		pnote.flags = PF_R
   1914 		phsh(pnote, sh)
   1915 	}
   1916 
   1917 	// Additions to the reserved area must be above this line.
   1918 
   1919 	elfphload(&Segtext)
   1920 	if len(Segrodata.Sections) > 0 {
   1921 		elfphload(&Segrodata)
   1922 	}
   1923 	if len(Segrelrodata.Sections) > 0 {
   1924 		elfphload(&Segrelrodata)
   1925 		elfphrelro(&Segrelrodata)
   1926 	}
   1927 	elfphload(&Segdata)
   1928 
   1929 	/* Dynamic linking sections */
   1930 	if !*FlagD {
   1931 		sh := elfshname(".dynsym")
   1932 		sh.type_ = SHT_DYNSYM
   1933 		sh.flags = SHF_ALLOC
   1934 		if elf64 {
   1935 			sh.entsize = ELF64SYMSIZE
   1936 		} else {
   1937 			sh.entsize = ELF32SYMSIZE
   1938 		}
   1939 		sh.addralign = uint64(ctxt.Arch.RegSize)
   1940 		sh.link = uint32(elfshname(".dynstr").shnum)
   1941 
   1942 		// sh->info = index of first non-local symbol (number of local symbols)
   1943 		shsym(sh, ctxt.Syms.Lookup(".dynsym", 0))
   1944 
   1945 		sh = elfshname(".dynstr")
   1946 		sh.type_ = SHT_STRTAB
   1947 		sh.flags = SHF_ALLOC
   1948 		sh.addralign = 1
   1949 		shsym(sh, ctxt.Syms.Lookup(".dynstr", 0))
   1950 
   1951 		if elfverneed != 0 {
   1952 			sh := elfshname(".gnu.version")
   1953 			sh.type_ = SHT_GNU_VERSYM
   1954 			sh.flags = SHF_ALLOC
   1955 			sh.addralign = 2
   1956 			sh.link = uint32(elfshname(".dynsym").shnum)
   1957 			sh.entsize = 2
   1958 			shsym(sh, ctxt.Syms.Lookup(".gnu.version", 0))
   1959 
   1960 			sh = elfshname(".gnu.version_r")
   1961 			sh.type_ = SHT_GNU_VERNEED
   1962 			sh.flags = SHF_ALLOC
   1963 			sh.addralign = uint64(ctxt.Arch.RegSize)
   1964 			sh.info = uint32(elfverneed)
   1965 			sh.link = uint32(elfshname(".dynstr").shnum)
   1966 			shsym(sh, ctxt.Syms.Lookup(".gnu.version_r", 0))
   1967 		}
   1968 
   1969 		if elfRelType == ".rela" {
   1970 			sh := elfshname(".rela.plt")
   1971 			sh.type_ = SHT_RELA
   1972 			sh.flags = SHF_ALLOC
   1973 			sh.entsize = ELF64RELASIZE
   1974 			sh.addralign = uint64(ctxt.Arch.RegSize)
   1975 			sh.link = uint32(elfshname(".dynsym").shnum)
   1976 			sh.info = uint32(elfshname(".plt").shnum)
   1977 			shsym(sh, ctxt.Syms.Lookup(".rela.plt", 0))
   1978 
   1979 			sh = elfshname(".rela")
   1980 			sh.type_ = SHT_RELA
   1981 			sh.flags = SHF_ALLOC
   1982 			sh.entsize = ELF64RELASIZE
   1983 			sh.addralign = 8
   1984 			sh.link = uint32(elfshname(".dynsym").shnum)
   1985 			shsym(sh, ctxt.Syms.Lookup(".rela", 0))
   1986 		} else {
   1987 			sh := elfshname(".rel.plt")
   1988 			sh.type_ = SHT_REL
   1989 			sh.flags = SHF_ALLOC
   1990 			sh.entsize = ELF32RELSIZE
   1991 			sh.addralign = 4
   1992 			sh.link = uint32(elfshname(".dynsym").shnum)
   1993 			shsym(sh, ctxt.Syms.Lookup(".rel.plt", 0))
   1994 
   1995 			sh = elfshname(".rel")
   1996 			sh.type_ = SHT_REL
   1997 			sh.flags = SHF_ALLOC
   1998 			sh.entsize = ELF32RELSIZE
   1999 			sh.addralign = 4
   2000 			sh.link = uint32(elfshname(".dynsym").shnum)
   2001 			shsym(sh, ctxt.Syms.Lookup(".rel", 0))
   2002 		}
   2003 
   2004 		if eh.machine == EM_PPC64 {
   2005 			sh := elfshname(".glink")
   2006 			sh.type_ = SHT_PROGBITS
   2007 			sh.flags = SHF_ALLOC + SHF_EXECINSTR
   2008 			sh.addralign = 4
   2009 			shsym(sh, ctxt.Syms.Lookup(".glink", 0))
   2010 		}
   2011 
   2012 		sh = elfshname(".plt")
   2013 		sh.type_ = SHT_PROGBITS
   2014 		sh.flags = SHF_ALLOC + SHF_EXECINSTR
   2015 		if eh.machine == EM_X86_64 {
   2016 			sh.entsize = 16
   2017 		} else if eh.machine == EM_S390 {
   2018 			sh.entsize = 32
   2019 		} else if eh.machine == EM_PPC64 {
   2020 			// On ppc64, this is just a table of addresses
   2021 			// filled by the dynamic linker
   2022 			sh.type_ = SHT_NOBITS
   2023 
   2024 			sh.flags = SHF_ALLOC + SHF_WRITE
   2025 			sh.entsize = 8
   2026 		} else {
   2027 			sh.entsize = 4
   2028 		}
   2029 		sh.addralign = sh.entsize
   2030 		shsym(sh, ctxt.Syms.Lookup(".plt", 0))
   2031 
   2032 		// On ppc64, .got comes from the input files, so don't
   2033 		// create it here, and .got.plt is not used.
   2034 		if eh.machine != EM_PPC64 {
   2035 			sh := elfshname(".got")
   2036 			sh.type_ = SHT_PROGBITS
   2037 			sh.flags = SHF_ALLOC + SHF_WRITE
   2038 			sh.entsize = uint64(ctxt.Arch.RegSize)
   2039 			sh.addralign = uint64(ctxt.Arch.RegSize)
   2040 			shsym(sh, ctxt.Syms.Lookup(".got", 0))
   2041 
   2042 			sh = elfshname(".got.plt")
   2043 			sh.type_ = SHT_PROGBITS
   2044 			sh.flags = SHF_ALLOC + SHF_WRITE
   2045 			sh.entsize = uint64(ctxt.Arch.RegSize)
   2046 			sh.addralign = uint64(ctxt.Arch.RegSize)
   2047 			shsym(sh, ctxt.Syms.Lookup(".got.plt", 0))
   2048 		}
   2049 
   2050 		sh = elfshname(".hash")
   2051 		sh.type_ = SHT_HASH
   2052 		sh.flags = SHF_ALLOC
   2053 		sh.entsize = 4
   2054 		sh.addralign = uint64(ctxt.Arch.RegSize)
   2055 		sh.link = uint32(elfshname(".dynsym").shnum)
   2056 		shsym(sh, ctxt.Syms.Lookup(".hash", 0))
   2057 
   2058 		/* sh and PT_DYNAMIC for .dynamic section */
   2059 		sh = elfshname(".dynamic")
   2060 
   2061 		sh.type_ = SHT_DYNAMIC
   2062 		sh.flags = SHF_ALLOC + SHF_WRITE
   2063 		sh.entsize = 2 * uint64(ctxt.Arch.RegSize)
   2064 		sh.addralign = uint64(ctxt.Arch.RegSize)
   2065 		sh.link = uint32(elfshname(".dynstr").shnum)
   2066 		shsym(sh, ctxt.Syms.Lookup(".dynamic", 0))
   2067 		ph := newElfPhdr()
   2068 		ph.type_ = PT_DYNAMIC
   2069 		ph.flags = PF_R + PF_W
   2070 		phsh(ph, sh)
   2071 
   2072 		/*
   2073 		 * Thread-local storage segment (really just size).
   2074 		 */
   2075 		tlssize := uint64(0)
   2076 		for _, sect := range Segdata.Sections {
   2077 			if sect.Name == ".tbss" {
   2078 				tlssize = sect.Length
   2079 			}
   2080 		}
   2081 		if tlssize != 0 {
   2082 			ph := newElfPhdr()
   2083 			ph.type_ = PT_TLS
   2084 			ph.flags = PF_R
   2085 			ph.memsz = tlssize
   2086 			ph.align = uint64(ctxt.Arch.RegSize)
   2087 		}
   2088 	}
   2089 
   2090 	if ctxt.HeadType == objabi.Hlinux {
   2091 		ph := newElfPhdr()
   2092 		ph.type_ = PT_GNU_STACK
   2093 		ph.flags = PF_W + PF_R
   2094 		ph.align = uint64(ctxt.Arch.RegSize)
   2095 
   2096 		ph = newElfPhdr()
   2097 		ph.type_ = PT_PAX_FLAGS
   2098 		ph.flags = 0x2a00 // mprotect, randexec, emutramp disabled
   2099 		ph.align = uint64(ctxt.Arch.RegSize)
   2100 	} else if ctxt.HeadType == objabi.Hsolaris {
   2101 		ph := newElfPhdr()
   2102 		ph.type_ = PT_SUNWSTACK
   2103 		ph.flags = PF_W + PF_R
   2104 	}
   2105 
   2106 elfobj:
   2107 	sh := elfshname(".shstrtab")
   2108 	sh.type_ = SHT_STRTAB
   2109 	sh.addralign = 1
   2110 	shsym(sh, ctxt.Syms.Lookup(".shstrtab", 0))
   2111 	eh.shstrndx = uint16(sh.shnum)
   2112 
   2113 	// put these sections early in the list
   2114 	if !*FlagS {
   2115 		elfshname(".symtab")
   2116 		elfshname(".strtab")
   2117 	}
   2118 
   2119 	for _, sect := range Segtext.Sections {
   2120 		elfshbits(ctxt.LinkMode, sect)
   2121 	}
   2122 	for _, sect := range Segrodata.Sections {
   2123 		elfshbits(ctxt.LinkMode, sect)
   2124 	}
   2125 	for _, sect := range Segrelrodata.Sections {
   2126 		elfshbits(ctxt.LinkMode, sect)
   2127 	}
   2128 	for _, sect := range Segdata.Sections {
   2129 		elfshbits(ctxt.LinkMode, sect)
   2130 	}
   2131 	for _, sect := range Segdwarf.Sections {
   2132 		elfshbits(ctxt.LinkMode, sect)
   2133 	}
   2134 
   2135 	if ctxt.LinkMode == LinkExternal {
   2136 		for _, sect := range Segtext.Sections {
   2137 			elfshreloc(ctxt.Arch, sect)
   2138 		}
   2139 		for _, sect := range Segrodata.Sections {
   2140 			elfshreloc(ctxt.Arch, sect)
   2141 		}
   2142 		for _, sect := range Segrelrodata.Sections {
   2143 			elfshreloc(ctxt.Arch, sect)
   2144 		}
   2145 		for _, sect := range Segdata.Sections {
   2146 			elfshreloc(ctxt.Arch, sect)
   2147 		}
   2148 		for _, s := range dwarfp {
   2149 			if len(s.R) > 0 || s.Type == sym.SDWARFINFO || s.Type == sym.SDWARFLOC {
   2150 				elfshreloc(ctxt.Arch, s.Sect)
   2151 			}
   2152 		}
   2153 		// add a .note.GNU-stack section to mark the stack as non-executable
   2154 		sh := elfshname(".note.GNU-stack")
   2155 
   2156 		sh.type_ = SHT_PROGBITS
   2157 		sh.addralign = 1
   2158 		sh.flags = 0
   2159 	}
   2160 
   2161 	if !*FlagS {
   2162 		sh := elfshname(".symtab")
   2163 		sh.type_ = SHT_SYMTAB
   2164 		sh.off = uint64(symo)
   2165 		sh.size = uint64(Symsize)
   2166 		sh.addralign = uint64(ctxt.Arch.RegSize)
   2167 		sh.entsize = 8 + 2*uint64(ctxt.Arch.RegSize)
   2168 		sh.link = uint32(elfshname(".strtab").shnum)
   2169 		sh.info = uint32(elfglobalsymndx)
   2170 
   2171 		sh = elfshname(".strtab")
   2172 		sh.type_ = SHT_STRTAB
   2173 		sh.off = uint64(symo) + uint64(Symsize)
   2174 		sh.size = uint64(len(Elfstrdat))
   2175 		sh.addralign = 1
   2176 	}
   2177 
   2178 	/* Main header */
   2179 	eh.ident[EI_MAG0] = '\177'
   2180 
   2181 	eh.ident[EI_MAG1] = 'E'
   2182 	eh.ident[EI_MAG2] = 'L'
   2183 	eh.ident[EI_MAG3] = 'F'
   2184 	if ctxt.HeadType == objabi.Hfreebsd {
   2185 		eh.ident[EI_OSABI] = ELFOSABI_FREEBSD
   2186 	} else if ctxt.HeadType == objabi.Hnetbsd {
   2187 		eh.ident[EI_OSABI] = ELFOSABI_NETBSD
   2188 	} else if ctxt.HeadType == objabi.Hopenbsd {
   2189 		eh.ident[EI_OSABI] = ELFOSABI_OPENBSD
   2190 	} else if ctxt.HeadType == objabi.Hdragonfly {
   2191 		eh.ident[EI_OSABI] = ELFOSABI_NONE
   2192 	}
   2193 	if elf64 {
   2194 		eh.ident[EI_CLASS] = ELFCLASS64
   2195 	} else {
   2196 		eh.ident[EI_CLASS] = ELFCLASS32
   2197 	}
   2198 	if ctxt.Arch.ByteOrder == binary.BigEndian {
   2199 		eh.ident[EI_DATA] = ELFDATA2MSB
   2200 	} else {
   2201 		eh.ident[EI_DATA] = ELFDATA2LSB
   2202 	}
   2203 	eh.ident[EI_VERSION] = EV_CURRENT
   2204 
   2205 	if ctxt.LinkMode == LinkExternal {
   2206 		eh.type_ = ET_REL
   2207 	} else if ctxt.BuildMode == BuildModePIE {
   2208 		eh.type_ = ET_DYN
   2209 	} else {
   2210 		eh.type_ = ET_EXEC
   2211 	}
   2212 
   2213 	if ctxt.LinkMode != LinkExternal {
   2214 		eh.entry = uint64(Entryvalue(ctxt))
   2215 	}
   2216 
   2217 	eh.version = EV_CURRENT
   2218 
   2219 	if pph != nil {
   2220 		pph.filesz = uint64(eh.phnum) * uint64(eh.phentsize)
   2221 		pph.memsz = pph.filesz
   2222 	}
   2223 
   2224 	ctxt.Out.SeekSet(0)
   2225 	a := int64(0)
   2226 	a += int64(elfwritehdr(ctxt.Out))
   2227 	a += int64(elfwritephdrs(ctxt.Out))
   2228 	a += int64(elfwriteshdrs(ctxt.Out))
   2229 	if !*FlagD {
   2230 		a += int64(elfwriteinterp(ctxt.Out))
   2231 	}
   2232 	if ctxt.LinkMode != LinkExternal {
   2233 		if ctxt.HeadType == objabi.Hnetbsd {
   2234 			a += int64(elfwritenetbsdsig(ctxt.Out))
   2235 		}
   2236 		if ctxt.HeadType == objabi.Hopenbsd {
   2237 			a += int64(elfwriteopenbsdsig(ctxt.Out))
   2238 		}
   2239 		if len(buildinfo) > 0 {
   2240 			a += int64(elfwritebuildinfo(ctxt.Out))
   2241 		}
   2242 		if *flagBuildid != "" {
   2243 			a += int64(elfwritegobuildid(ctxt.Out))
   2244 		}
   2245 	}
   2246 
   2247 	if a > elfreserve {
   2248 		Errorf(nil, "ELFRESERVE too small: %d > %d with %d text sections", a, elfreserve, numtext)
   2249 	}
   2250 }
   2251 
   2252 func elfadddynsym(ctxt *Link, s *sym.Symbol) {
   2253 	if elf64 {
   2254 		s.Dynid = int32(Nelfsym)
   2255 		Nelfsym++
   2256 
   2257 		d := ctxt.Syms.Lookup(".dynsym", 0)
   2258 
   2259 		name := s.Extname
   2260 		d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
   2261 
   2262 		/* type */
   2263 		t := STB_GLOBAL << 4
   2264 
   2265 		if s.Attr.CgoExport() && s.Type == sym.STEXT {
   2266 			t |= STT_FUNC
   2267 		} else {
   2268 			t |= STT_OBJECT
   2269 		}
   2270 		d.AddUint8(uint8(t))
   2271 
   2272 		/* reserved */
   2273 		d.AddUint8(0)
   2274 
   2275 		/* section where symbol is defined */
   2276 		if s.Type == sym.SDYNIMPORT {
   2277 			d.AddUint16(ctxt.Arch, SHN_UNDEF)
   2278 		} else {
   2279 			d.AddUint16(ctxt.Arch, 1)
   2280 		}
   2281 
   2282 		/* value */
   2283 		if s.Type == sym.SDYNIMPORT {
   2284 			d.AddUint64(ctxt.Arch, 0)
   2285 		} else {
   2286 			d.AddAddr(ctxt.Arch, s)
   2287 		}
   2288 
   2289 		/* size of object */
   2290 		d.AddUint64(ctxt.Arch, uint64(s.Size))
   2291 
   2292 		if ctxt.Arch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib != "" && !seenlib[s.Dynimplib] {
   2293 			Elfwritedynent(ctxt, ctxt.Syms.Lookup(".dynamic", 0), DT_NEEDED, uint64(Addstring(ctxt.Syms.Lookup(".dynstr", 0), s.Dynimplib)))
   2294 		}
   2295 	} else {
   2296 		s.Dynid = int32(Nelfsym)
   2297 		Nelfsym++
   2298 
   2299 		d := ctxt.Syms.Lookup(".dynsym", 0)
   2300 
   2301 		/* name */
   2302 		name := s.Extname
   2303 
   2304 		d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
   2305 
   2306 		/* value */
   2307 		if s.Type == sym.SDYNIMPORT {
   2308 			d.AddUint32(ctxt.Arch, 0)
   2309 		} else {
   2310 			d.AddAddr(ctxt.Arch, s)
   2311 		}
   2312 
   2313 		/* size of object */
   2314 		d.AddUint32(ctxt.Arch, uint32(s.Size))
   2315 
   2316 		/* type */
   2317 		t := STB_GLOBAL << 4
   2318 
   2319 		// TODO(mwhudson): presumably the behavior should actually be the same on both arm and 386.
   2320 		if ctxt.Arch.Family == sys.I386 && s.Attr.CgoExport() && s.Type == sym.STEXT {
   2321 			t |= STT_FUNC
   2322 		} else if ctxt.Arch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type == sym.STEXT {
   2323 			t |= STT_FUNC
   2324 		} else {
   2325 			t |= STT_OBJECT
   2326 		}
   2327 		d.AddUint8(uint8(t))
   2328 		d.AddUint8(0)
   2329 
   2330 		/* shndx */
   2331 		if s.Type == sym.SDYNIMPORT {
   2332 			d.AddUint16(ctxt.Arch, SHN_UNDEF)
   2333 		} else {
   2334 			d.AddUint16(ctxt.Arch, 1)
   2335 		}
   2336 	}
   2337 }
   2338 
   2339 func ELF32_R_SYM(info uint32) uint32 {
   2340 	return info >> 8
   2341 }
   2342 
   2343 func ELF32_R_TYPE(info uint32) uint32 {
   2344 	return uint32(uint8(info))
   2345 }
   2346 
   2347 func ELF32_R_INFO(sym uint32, type_ uint32) uint32 {
   2348 	return sym<<8 | type_
   2349 }
   2350 
   2351 func ELF32_ST_BIND(info uint8) uint8 {
   2352 	return info >> 4
   2353 }
   2354 
   2355 func ELF32_ST_TYPE(info uint8) uint8 {
   2356 	return info & 0xf
   2357 }
   2358 
   2359 func ELF32_ST_INFO(bind uint8, type_ uint8) uint8 {
   2360 	return bind<<4 | type_&0xf
   2361 }
   2362 
   2363 func ELF32_ST_VISIBILITY(oth uint8) uint8 {
   2364 	return oth & 3
   2365 }
   2366 
   2367 func ELF64_R_SYM(info uint64) uint32 {
   2368 	return uint32(info >> 32)
   2369 }
   2370 
   2371 func ELF64_R_TYPE(info uint64) uint32 {
   2372 	return uint32(info)
   2373 }
   2374 
   2375 func ELF64_R_INFO(sym uint32, type_ uint32) uint64 {
   2376 	return uint64(sym)<<32 | uint64(type_)
   2377 }
   2378 
   2379 func ELF64_ST_BIND(info uint8) uint8 {
   2380 	return info >> 4
   2381 }
   2382 
   2383 func ELF64_ST_TYPE(info uint8) uint8 {
   2384 	return info & 0xf
   2385 }
   2386 
   2387 func ELF64_ST_INFO(bind uint8, type_ uint8) uint8 {
   2388 	return bind<<4 | type_&0xf
   2389 }
   2390 
   2391 func ELF64_ST_VISIBILITY(oth uint8) uint8 {
   2392 	return oth & 3
   2393 }
   2394