github.com/kdevb0x/go@v0.0.0-20180115030120-39687051e9e7/src/cmd/link/internal/ld/elf.go (about)

     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  }