github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/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  	"github.com/gagliardetto/golang-go/cmd/internal/objabi"
     9  	"github.com/gagliardetto/golang-go/cmd/internal/sys"
    10  	"github.com/gagliardetto/golang-go/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  	EM_RISCV             = 243
   180  	SHN_UNDEF            = 0
   181  	SHN_LORESERVE        = 0xff00
   182  	SHN_LOPROC           = 0xff00
   183  	SHN_HIPROC           = 0xff1f
   184  	SHN_LOOS             = 0xff20
   185  	SHN_HIOS             = 0xff3f
   186  	SHN_ABS              = 0xfff1
   187  	SHN_COMMON           = 0xfff2
   188  	SHN_XINDEX           = 0xffff
   189  	SHN_HIRESERVE        = 0xffff
   190  	SHT_NULL             = 0
   191  	SHT_PROGBITS         = 1
   192  	SHT_SYMTAB           = 2
   193  	SHT_STRTAB           = 3
   194  	SHT_RELA             = 4
   195  	SHT_HASH             = 5
   196  	SHT_DYNAMIC          = 6
   197  	SHT_NOTE             = 7
   198  	SHT_NOBITS           = 8
   199  	SHT_REL              = 9
   200  	SHT_SHLIB            = 10
   201  	SHT_DYNSYM           = 11
   202  	SHT_INIT_ARRAY       = 14
   203  	SHT_FINI_ARRAY       = 15
   204  	SHT_PREINIT_ARRAY    = 16
   205  	SHT_GROUP            = 17
   206  	SHT_SYMTAB_SHNDX     = 18
   207  	SHT_LOOS             = 0x60000000
   208  	SHT_HIOS             = 0x6fffffff
   209  	SHT_GNU_VERDEF       = 0x6ffffffd
   210  	SHT_GNU_VERNEED      = 0x6ffffffe
   211  	SHT_GNU_VERSYM       = 0x6fffffff
   212  	SHT_LOPROC           = 0x70000000
   213  	SHT_ARM_ATTRIBUTES   = 0x70000003
   214  	SHT_HIPROC           = 0x7fffffff
   215  	SHT_LOUSER           = 0x80000000
   216  	SHT_HIUSER           = 0xffffffff
   217  	SHF_WRITE            = 0x1
   218  	SHF_ALLOC            = 0x2
   219  	SHF_EXECINSTR        = 0x4
   220  	SHF_MERGE            = 0x10
   221  	SHF_STRINGS          = 0x20
   222  	SHF_INFO_LINK        = 0x40
   223  	SHF_LINK_ORDER       = 0x80
   224  	SHF_OS_NONCONFORMING = 0x100
   225  	SHF_GROUP            = 0x200
   226  	SHF_TLS              = 0x400
   227  	SHF_MASKOS           = 0x0ff00000
   228  	SHF_MASKPROC         = 0xf0000000
   229  	PT_NULL              = 0
   230  	PT_LOAD              = 1
   231  	PT_DYNAMIC           = 2
   232  	PT_INTERP            = 3
   233  	PT_NOTE              = 4
   234  	PT_SHLIB             = 5
   235  	PT_PHDR              = 6
   236  	PT_TLS               = 7
   237  	PT_LOOS              = 0x60000000
   238  	PT_HIOS              = 0x6fffffff
   239  	PT_LOPROC            = 0x70000000
   240  	PT_HIPROC            = 0x7fffffff
   241  	PT_GNU_STACK         = 0x6474e551
   242  	PT_GNU_RELRO         = 0x6474e552
   243  	PT_PAX_FLAGS         = 0x65041580
   244  	PT_SUNWSTACK         = 0x6ffffffb
   245  	PF_X                 = 0x1
   246  	PF_W                 = 0x2
   247  	PF_R                 = 0x4
   248  	PF_MASKOS            = 0x0ff00000
   249  	PF_MASKPROC          = 0xf0000000
   250  	DT_NULL              = 0
   251  	DT_NEEDED            = 1
   252  	DT_PLTRELSZ          = 2
   253  	DT_PLTGOT            = 3
   254  	DT_HASH              = 4
   255  	DT_STRTAB            = 5
   256  	DT_SYMTAB            = 6
   257  	DT_RELA              = 7
   258  	DT_RELASZ            = 8
   259  	DT_RELAENT           = 9
   260  	DT_STRSZ             = 10
   261  	DT_SYMENT            = 11
   262  	DT_INIT              = 12
   263  	DT_FINI              = 13
   264  	DT_SONAME            = 14
   265  	DT_RPATH             = 15
   266  	DT_SYMBOLIC          = 16
   267  	DT_REL               = 17
   268  	DT_RELSZ             = 18
   269  	DT_RELENT            = 19
   270  	DT_PLTREL            = 20
   271  	DT_DEBUG             = 21
   272  	DT_TEXTREL           = 22
   273  	DT_JMPREL            = 23
   274  	DT_BIND_NOW          = 24
   275  	DT_INIT_ARRAY        = 25
   276  	DT_FINI_ARRAY        = 26
   277  	DT_INIT_ARRAYSZ      = 27
   278  	DT_FINI_ARRAYSZ      = 28
   279  	DT_RUNPATH           = 29
   280  	DT_FLAGS             = 30
   281  	DT_ENCODING          = 32
   282  	DT_PREINIT_ARRAY     = 32
   283  	DT_PREINIT_ARRAYSZ   = 33
   284  	DT_LOOS              = 0x6000000d
   285  	DT_HIOS              = 0x6ffff000
   286  	DT_LOPROC            = 0x70000000
   287  	DT_HIPROC            = 0x7fffffff
   288  	DT_VERNEED           = 0x6ffffffe
   289  	DT_VERNEEDNUM        = 0x6fffffff
   290  	DT_VERSYM            = 0x6ffffff0
   291  	DT_PPC64_GLINK       = DT_LOPROC + 0
   292  	DT_PPC64_OPT         = DT_LOPROC + 3
   293  	DF_ORIGIN            = 0x0001
   294  	DF_SYMBOLIC          = 0x0002
   295  	DF_TEXTREL           = 0x0004
   296  	DF_BIND_NOW          = 0x0008
   297  	DF_STATIC_TLS        = 0x0010
   298  	NT_PRSTATUS          = 1
   299  	NT_FPREGSET          = 2
   300  	NT_PRPSINFO          = 3
   301  	STB_LOCAL            = 0
   302  	STB_GLOBAL           = 1
   303  	STB_WEAK             = 2
   304  	STB_LOOS             = 10
   305  	STB_HIOS             = 12
   306  	STB_LOPROC           = 13
   307  	STB_HIPROC           = 15
   308  	STT_NOTYPE           = 0
   309  	STT_OBJECT           = 1
   310  	STT_FUNC             = 2
   311  	STT_SECTION          = 3
   312  	STT_FILE             = 4
   313  	STT_COMMON           = 5
   314  	STT_TLS              = 6
   315  	STT_LOOS             = 10
   316  	STT_HIOS             = 12
   317  	STT_LOPROC           = 13
   318  	STT_HIPROC           = 15
   319  	STV_DEFAULT          = 0x0
   320  	STV_INTERNAL         = 0x1
   321  	STV_HIDDEN           = 0x2
   322  	STV_PROTECTED        = 0x3
   323  	STN_UNDEF            = 0
   324  )
   325  
   326  /* For accessing the fields of r_info. */
   327  
   328  /* For constructing r_info from field values. */
   329  
   330  /*
   331   * Relocation types.
   332   */
   333  const (
   334  	ARM_MAGIC_TRAMP_NUMBER = 0x5c000003
   335  )
   336  
   337  /*
   338   * Symbol table entries.
   339   */
   340  
   341  /* For accessing the fields of st_info. */
   342  
   343  /* For constructing st_info from field values. */
   344  
   345  /* For accessing the fields of st_other. */
   346  
   347  /*
   348   * ELF header.
   349   */
   350  type ElfEhdr struct {
   351  	ident     [EI_NIDENT]uint8
   352  	type_     uint16
   353  	machine   uint16
   354  	version   uint32
   355  	entry     uint64
   356  	phoff     uint64
   357  	shoff     uint64
   358  	flags     uint32
   359  	ehsize    uint16
   360  	phentsize uint16
   361  	phnum     uint16
   362  	shentsize uint16
   363  	shnum     uint16
   364  	shstrndx  uint16
   365  }
   366  
   367  /*
   368   * Section header.
   369   */
   370  type ElfShdr struct {
   371  	name      uint32
   372  	type_     uint32
   373  	flags     uint64
   374  	addr      uint64
   375  	off       uint64
   376  	size      uint64
   377  	link      uint32
   378  	info      uint32
   379  	addralign uint64
   380  	entsize   uint64
   381  	shnum     int
   382  }
   383  
   384  /*
   385   * Program header.
   386   */
   387  type ElfPhdr struct {
   388  	type_  uint32
   389  	flags  uint32
   390  	off    uint64
   391  	vaddr  uint64
   392  	paddr  uint64
   393  	filesz uint64
   394  	memsz  uint64
   395  	align  uint64
   396  }
   397  
   398  /* For accessing the fields of r_info. */
   399  
   400  /* For constructing r_info from field values. */
   401  
   402  /*
   403   * Symbol table entries.
   404   */
   405  
   406  /* For accessing the fields of st_info. */
   407  
   408  /* For constructing st_info from field values. */
   409  
   410  /* For accessing the fields of st_other. */
   411  
   412  /*
   413   * Go linker interface
   414   */
   415  const (
   416  	ELF64HDRSIZE  = 64
   417  	ELF64PHDRSIZE = 56
   418  	ELF64SHDRSIZE = 64
   419  	ELF64RELSIZE  = 16
   420  	ELF64RELASIZE = 24
   421  	ELF64SYMSIZE  = 24
   422  	ELF32HDRSIZE  = 52
   423  	ELF32PHDRSIZE = 32
   424  	ELF32SHDRSIZE = 40
   425  	ELF32SYMSIZE  = 16
   426  	ELF32RELSIZE  = 8
   427  )
   428  
   429  /*
   430   * The interface uses the 64-bit structures always,
   431   * to avoid code duplication.  The writers know how to
   432   * marshal a 32-bit representation from the 64-bit structure.
   433   */
   434  
   435  var Elfstrdat []byte
   436  
   437  /*
   438   * Total amount of space to reserve at the start of the file
   439   * for Header, PHeaders, SHeaders, and interp.
   440   * May waste some.
   441   * On FreeBSD, cannot be larger than a page.
   442   */
   443  const (
   444  	ELFRESERVE = 4096
   445  )
   446  
   447  /*
   448   * We use the 64-bit data structures on both 32- and 64-bit machines
   449   * in order to write the code just once.  The 64-bit data structure is
   450   * written in the 32-bit format on the 32-bit machines.
   451   */
   452  const (
   453  	NSECT = 400
   454  )
   455  
   456  var (
   457  	Nelfsym = 1
   458  
   459  	elf64 bool
   460  	// Either ".rel" or ".rela" depending on which type of relocation the
   461  	// target platform uses.
   462  	elfRelType string
   463  
   464  	ehdr ElfEhdr
   465  	phdr [NSECT]*ElfPhdr
   466  	shdr [NSECT]*ElfShdr
   467  
   468  	interp string
   469  )
   470  
   471  type Elfstring struct {
   472  	s   string
   473  	off int
   474  }
   475  
   476  var elfstr [100]Elfstring
   477  
   478  var nelfstr int
   479  
   480  var buildinfo []byte
   481  
   482  /*
   483   Initialize the global variable that describes the ELF header. It will be updated as
   484   we write section and prog headers.
   485  */
   486  func Elfinit(ctxt *Link) {
   487  	ctxt.IsELF = true
   488  
   489  	if ctxt.Arch.InFamily(sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) {
   490  		elfRelType = ".rela"
   491  	} else {
   492  		elfRelType = ".rel"
   493  	}
   494  
   495  	switch ctxt.Arch.Family {
   496  	// 64-bit architectures
   497  	case sys.PPC64, sys.S390X:
   498  		if ctxt.Arch.ByteOrder == binary.BigEndian {
   499  			ehdr.flags = 1 /* Version 1 ABI */
   500  		} else {
   501  			ehdr.flags = 2 /* Version 2 ABI */
   502  		}
   503  		fallthrough
   504  	case sys.AMD64, sys.ARM64, sys.MIPS64, sys.RISCV64:
   505  		if ctxt.Arch.Family == sys.MIPS64 {
   506  			ehdr.flags = 0x20000004 /* MIPS 3 CPIC */
   507  		}
   508  		elf64 = true
   509  
   510  		ehdr.phoff = ELF64HDRSIZE      /* Must be ELF64HDRSIZE: first PHdr must follow ELF header */
   511  		ehdr.shoff = ELF64HDRSIZE      /* Will move as we add PHeaders */
   512  		ehdr.ehsize = ELF64HDRSIZE     /* Must be ELF64HDRSIZE */
   513  		ehdr.phentsize = ELF64PHDRSIZE /* Must be ELF64PHDRSIZE */
   514  		ehdr.shentsize = ELF64SHDRSIZE /* Must be ELF64SHDRSIZE */
   515  
   516  	// 32-bit architectures
   517  	case sys.ARM, sys.MIPS:
   518  		if ctxt.Arch.Family == sys.ARM {
   519  			// we use EABI on linux/arm, freebsd/arm, netbsd/arm.
   520  			if ctxt.HeadType == objabi.Hlinux || ctxt.HeadType == objabi.Hfreebsd || ctxt.HeadType == objabi.Hnetbsd {
   521  				// We set a value here that makes no indication of which
   522  				// float ABI the object uses, because this is information
   523  				// used by the dynamic linker to compare executables and
   524  				// shared libraries -- so it only matters for cgo calls, and
   525  				// the information properly comes from the object files
   526  				// produced by the host C compiler. parseArmAttributes in
   527  				// ldelf.go reads that information and updates this field as
   528  				// appropriate.
   529  				ehdr.flags = 0x5000002 // has entry point, Version5 EABI
   530  			}
   531  		} else if ctxt.Arch.Family == sys.MIPS {
   532  			ehdr.flags = 0x50001004 /* MIPS 32 CPIC O32*/
   533  		}
   534  		fallthrough
   535  	default:
   536  		ehdr.phoff = ELF32HDRSIZE
   537  		/* Must be ELF32HDRSIZE: first PHdr must follow ELF header */
   538  		ehdr.shoff = ELF32HDRSIZE      /* Will move as we add PHeaders */
   539  		ehdr.ehsize = ELF32HDRSIZE     /* Must be ELF32HDRSIZE */
   540  		ehdr.phentsize = ELF32PHDRSIZE /* Must be ELF32PHDRSIZE */
   541  		ehdr.shentsize = ELF32SHDRSIZE /* Must be ELF32SHDRSIZE */
   542  	}
   543  }
   544  
   545  // Make sure PT_LOAD is aligned properly and
   546  // that there is no gap,
   547  // correct ELF loaders will do this implicitly,
   548  // but buggy ELF loaders like the one in some
   549  // versions of QEMU and UPX won't.
   550  func fixElfPhdr(e *ElfPhdr) {
   551  	frag := int(e.vaddr & (e.align - 1))
   552  
   553  	e.off -= uint64(frag)
   554  	e.vaddr -= uint64(frag)
   555  	e.paddr -= uint64(frag)
   556  	e.filesz += uint64(frag)
   557  	e.memsz += uint64(frag)
   558  }
   559  
   560  func elf64phdr(out *OutBuf, e *ElfPhdr) {
   561  	if e.type_ == PT_LOAD {
   562  		fixElfPhdr(e)
   563  	}
   564  
   565  	out.Write32(e.type_)
   566  	out.Write32(e.flags)
   567  	out.Write64(e.off)
   568  	out.Write64(e.vaddr)
   569  	out.Write64(e.paddr)
   570  	out.Write64(e.filesz)
   571  	out.Write64(e.memsz)
   572  	out.Write64(e.align)
   573  }
   574  
   575  func elf32phdr(out *OutBuf, e *ElfPhdr) {
   576  	if e.type_ == PT_LOAD {
   577  		fixElfPhdr(e)
   578  	}
   579  
   580  	out.Write32(e.type_)
   581  	out.Write32(uint32(e.off))
   582  	out.Write32(uint32(e.vaddr))
   583  	out.Write32(uint32(e.paddr))
   584  	out.Write32(uint32(e.filesz))
   585  	out.Write32(uint32(e.memsz))
   586  	out.Write32(e.flags)
   587  	out.Write32(uint32(e.align))
   588  }
   589  
   590  func elf64shdr(out *OutBuf, e *ElfShdr) {
   591  	out.Write32(e.name)
   592  	out.Write32(e.type_)
   593  	out.Write64(e.flags)
   594  	out.Write64(e.addr)
   595  	out.Write64(e.off)
   596  	out.Write64(e.size)
   597  	out.Write32(e.link)
   598  	out.Write32(e.info)
   599  	out.Write64(e.addralign)
   600  	out.Write64(e.entsize)
   601  }
   602  
   603  func elf32shdr(out *OutBuf, e *ElfShdr) {
   604  	out.Write32(e.name)
   605  	out.Write32(e.type_)
   606  	out.Write32(uint32(e.flags))
   607  	out.Write32(uint32(e.addr))
   608  	out.Write32(uint32(e.off))
   609  	out.Write32(uint32(e.size))
   610  	out.Write32(e.link)
   611  	out.Write32(e.info)
   612  	out.Write32(uint32(e.addralign))
   613  	out.Write32(uint32(e.entsize))
   614  }
   615  
   616  func elfwriteshdrs(out *OutBuf) uint32 {
   617  	if elf64 {
   618  		for i := 0; i < int(ehdr.shnum); i++ {
   619  			elf64shdr(out, shdr[i])
   620  		}
   621  		return uint32(ehdr.shnum) * ELF64SHDRSIZE
   622  	}
   623  
   624  	for i := 0; i < int(ehdr.shnum); i++ {
   625  		elf32shdr(out, shdr[i])
   626  	}
   627  	return uint32(ehdr.shnum) * ELF32SHDRSIZE
   628  }
   629  
   630  func elfsetstring(s *sym.Symbol, str string, off int) {
   631  	if nelfstr >= len(elfstr) {
   632  		Errorf(s, "too many elf strings")
   633  		errorexit()
   634  	}
   635  
   636  	elfstr[nelfstr].s = str
   637  	elfstr[nelfstr].off = off
   638  	nelfstr++
   639  }
   640  
   641  func elfwritephdrs(out *OutBuf) uint32 {
   642  	if elf64 {
   643  		for i := 0; i < int(ehdr.phnum); i++ {
   644  			elf64phdr(out, phdr[i])
   645  		}
   646  		return uint32(ehdr.phnum) * ELF64PHDRSIZE
   647  	}
   648  
   649  	for i := 0; i < int(ehdr.phnum); i++ {
   650  		elf32phdr(out, phdr[i])
   651  	}
   652  	return uint32(ehdr.phnum) * ELF32PHDRSIZE
   653  }
   654  
   655  func newElfPhdr() *ElfPhdr {
   656  	e := new(ElfPhdr)
   657  	if ehdr.phnum >= NSECT {
   658  		Errorf(nil, "too many phdrs")
   659  	} else {
   660  		phdr[ehdr.phnum] = e
   661  		ehdr.phnum++
   662  	}
   663  	if elf64 {
   664  		ehdr.shoff += ELF64PHDRSIZE
   665  	} else {
   666  		ehdr.shoff += ELF32PHDRSIZE
   667  	}
   668  	return e
   669  }
   670  
   671  func newElfShdr(name int64) *ElfShdr {
   672  	e := new(ElfShdr)
   673  	e.name = uint32(name)
   674  	e.shnum = int(ehdr.shnum)
   675  	if ehdr.shnum >= NSECT {
   676  		Errorf(nil, "too many shdrs")
   677  	} else {
   678  		shdr[ehdr.shnum] = e
   679  		ehdr.shnum++
   680  	}
   681  
   682  	return e
   683  }
   684  
   685  func getElfEhdr() *ElfEhdr {
   686  	return &ehdr
   687  }
   688  
   689  func elf64writehdr(out *OutBuf) uint32 {
   690  	out.Write(ehdr.ident[:])
   691  	out.Write16(ehdr.type_)
   692  	out.Write16(ehdr.machine)
   693  	out.Write32(ehdr.version)
   694  	out.Write64(ehdr.entry)
   695  	out.Write64(ehdr.phoff)
   696  	out.Write64(ehdr.shoff)
   697  	out.Write32(ehdr.flags)
   698  	out.Write16(ehdr.ehsize)
   699  	out.Write16(ehdr.phentsize)
   700  	out.Write16(ehdr.phnum)
   701  	out.Write16(ehdr.shentsize)
   702  	out.Write16(ehdr.shnum)
   703  	out.Write16(ehdr.shstrndx)
   704  	return ELF64HDRSIZE
   705  }
   706  
   707  func elf32writehdr(out *OutBuf) uint32 {
   708  	out.Write(ehdr.ident[:])
   709  	out.Write16(ehdr.type_)
   710  	out.Write16(ehdr.machine)
   711  	out.Write32(ehdr.version)
   712  	out.Write32(uint32(ehdr.entry))
   713  	out.Write32(uint32(ehdr.phoff))
   714  	out.Write32(uint32(ehdr.shoff))
   715  	out.Write32(ehdr.flags)
   716  	out.Write16(ehdr.ehsize)
   717  	out.Write16(ehdr.phentsize)
   718  	out.Write16(ehdr.phnum)
   719  	out.Write16(ehdr.shentsize)
   720  	out.Write16(ehdr.shnum)
   721  	out.Write16(ehdr.shstrndx)
   722  	return ELF32HDRSIZE
   723  }
   724  
   725  func elfwritehdr(out *OutBuf) uint32 {
   726  	if elf64 {
   727  		return elf64writehdr(out)
   728  	}
   729  	return elf32writehdr(out)
   730  }
   731  
   732  /* Taken directly from the definition document for ELF64 */
   733  func elfhash(name string) uint32 {
   734  	var h uint32
   735  	for i := 0; i < len(name); i++ {
   736  		h = (h << 4) + uint32(name[i])
   737  		if g := h & 0xf0000000; g != 0 {
   738  			h ^= g >> 24
   739  		}
   740  		h &= 0x0fffffff
   741  	}
   742  	return h
   743  }
   744  
   745  func Elfwritedynent(ctxt *Link, s *sym.Symbol, tag int, val uint64) {
   746  	if elf64 {
   747  		s.AddUint64(ctxt.Arch, uint64(tag))
   748  		s.AddUint64(ctxt.Arch, val)
   749  	} else {
   750  		s.AddUint32(ctxt.Arch, uint32(tag))
   751  		s.AddUint32(ctxt.Arch, uint32(val))
   752  	}
   753  }
   754  
   755  func elfwritedynentsym(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol) {
   756  	Elfwritedynentsymplus(ctxt, s, tag, t, 0)
   757  }
   758  
   759  func Elfwritedynentsymplus(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol, add int64) {
   760  	if elf64 {
   761  		s.AddUint64(ctxt.Arch, uint64(tag))
   762  	} else {
   763  		s.AddUint32(ctxt.Arch, uint32(tag))
   764  	}
   765  	s.AddAddrPlus(ctxt.Arch, t, add)
   766  }
   767  
   768  func elfwritedynentsymsize(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol) {
   769  	if elf64 {
   770  		s.AddUint64(ctxt.Arch, uint64(tag))
   771  	} else {
   772  		s.AddUint32(ctxt.Arch, uint32(tag))
   773  	}
   774  	s.AddSize(ctxt.Arch, t)
   775  }
   776  
   777  func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int {
   778  	interp = p
   779  	n := len(interp) + 1
   780  	sh.addr = startva + resoff - uint64(n)
   781  	sh.off = resoff - uint64(n)
   782  	sh.size = uint64(n)
   783  
   784  	return n
   785  }
   786  
   787  func elfwriteinterp(out *OutBuf) int {
   788  	sh := elfshname(".interp")
   789  	out.SeekSet(int64(sh.off))
   790  	out.WriteString(interp)
   791  	out.Write8(0)
   792  	return int(sh.size)
   793  }
   794  
   795  func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int) int {
   796  	n := 3*4 + uint64(sz) + resoff%4
   797  
   798  	sh.type_ = SHT_NOTE
   799  	sh.flags = SHF_ALLOC
   800  	sh.addralign = 4
   801  	sh.addr = startva + resoff - n
   802  	sh.off = resoff - n
   803  	sh.size = n - resoff%4
   804  
   805  	return int(n)
   806  }
   807  
   808  func elfwritenotehdr(out *OutBuf, str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr {
   809  	sh := elfshname(str)
   810  
   811  	// Write Elf_Note header.
   812  	out.SeekSet(int64(sh.off))
   813  
   814  	out.Write32(namesz)
   815  	out.Write32(descsz)
   816  	out.Write32(tag)
   817  
   818  	return sh
   819  }
   820  
   821  // NetBSD Signature (as per sys/exec_elf.h)
   822  const (
   823  	ELF_NOTE_NETBSD_NAMESZ  = 7
   824  	ELF_NOTE_NETBSD_DESCSZ  = 4
   825  	ELF_NOTE_NETBSD_TAG     = 1
   826  	ELF_NOTE_NETBSD_VERSION = 599000000 /* NetBSD 5.99 */
   827  )
   828  
   829  var ELF_NOTE_NETBSD_NAME = []byte("NetBSD\x00")
   830  
   831  func elfnetbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
   832  	n := int(Rnd(ELF_NOTE_NETBSD_NAMESZ, 4) + Rnd(ELF_NOTE_NETBSD_DESCSZ, 4))
   833  	return elfnote(sh, startva, resoff, n)
   834  }
   835  
   836  func elfwritenetbsdsig(out *OutBuf) int {
   837  	// Write Elf_Note header.
   838  	sh := elfwritenotehdr(out, ".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG)
   839  
   840  	if sh == nil {
   841  		return 0
   842  	}
   843  
   844  	// Followed by NetBSD string and version.
   845  	out.Write(ELF_NOTE_NETBSD_NAME)
   846  	out.Write8(0)
   847  	out.Write32(ELF_NOTE_NETBSD_VERSION)
   848  
   849  	return int(sh.size)
   850  }
   851  
   852  // OpenBSD Signature
   853  const (
   854  	ELF_NOTE_OPENBSD_NAMESZ  = 8
   855  	ELF_NOTE_OPENBSD_DESCSZ  = 4
   856  	ELF_NOTE_OPENBSD_TAG     = 1
   857  	ELF_NOTE_OPENBSD_VERSION = 0
   858  )
   859  
   860  var ELF_NOTE_OPENBSD_NAME = []byte("OpenBSD\x00")
   861  
   862  func elfopenbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
   863  	n := ELF_NOTE_OPENBSD_NAMESZ + ELF_NOTE_OPENBSD_DESCSZ
   864  	return elfnote(sh, startva, resoff, n)
   865  }
   866  
   867  func elfwriteopenbsdsig(out *OutBuf) int {
   868  	// Write Elf_Note header.
   869  	sh := elfwritenotehdr(out, ".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG)
   870  
   871  	if sh == nil {
   872  		return 0
   873  	}
   874  
   875  	// Followed by OpenBSD string and version.
   876  	out.Write(ELF_NOTE_OPENBSD_NAME)
   877  
   878  	out.Write32(ELF_NOTE_OPENBSD_VERSION)
   879  
   880  	return int(sh.size)
   881  }
   882  
   883  func addbuildinfo(val string) {
   884  	if !strings.HasPrefix(val, "0x") {
   885  		Exitf("-B argument must start with 0x: %s", val)
   886  	}
   887  
   888  	ov := val
   889  	val = val[2:]
   890  
   891  	const maxLen = 32
   892  	if hex.DecodedLen(len(val)) > maxLen {
   893  		Exitf("-B option too long (max %d digits): %s", maxLen, ov)
   894  	}
   895  
   896  	b, err := hex.DecodeString(val)
   897  	if err != nil {
   898  		if err == hex.ErrLength {
   899  			Exitf("-B argument must have even number of digits: %s", ov)
   900  		}
   901  		if inv, ok := err.(hex.InvalidByteError); ok {
   902  			Exitf("-B argument contains invalid hex digit %c: %s", byte(inv), ov)
   903  		}
   904  		Exitf("-B argument contains invalid hex: %s", ov)
   905  	}
   906  
   907  	buildinfo = b
   908  }
   909  
   910  // Build info note
   911  const (
   912  	ELF_NOTE_BUILDINFO_NAMESZ = 4
   913  	ELF_NOTE_BUILDINFO_TAG    = 3
   914  )
   915  
   916  var ELF_NOTE_BUILDINFO_NAME = []byte("GNU\x00")
   917  
   918  func elfbuildinfo(sh *ElfShdr, startva uint64, resoff uint64) int {
   919  	n := int(ELF_NOTE_BUILDINFO_NAMESZ + Rnd(int64(len(buildinfo)), 4))
   920  	return elfnote(sh, startva, resoff, n)
   921  }
   922  
   923  func elfgobuildid(sh *ElfShdr, startva uint64, resoff uint64) int {
   924  	n := len(ELF_NOTE_GO_NAME) + int(Rnd(int64(len(*flagBuildid)), 4))
   925  	return elfnote(sh, startva, resoff, n)
   926  }
   927  
   928  func elfwritebuildinfo(out *OutBuf) int {
   929  	sh := elfwritenotehdr(out, ".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG)
   930  	if sh == nil {
   931  		return 0
   932  	}
   933  
   934  	out.Write(ELF_NOTE_BUILDINFO_NAME)
   935  	out.Write(buildinfo)
   936  	var zero = make([]byte, 4)
   937  	out.Write(zero[:int(Rnd(int64(len(buildinfo)), 4)-int64(len(buildinfo)))])
   938  
   939  	return int(sh.size)
   940  }
   941  
   942  func elfwritegobuildid(out *OutBuf) int {
   943  	sh := elfwritenotehdr(out, ".note.go.buildid", uint32(len(ELF_NOTE_GO_NAME)), uint32(len(*flagBuildid)), ELF_NOTE_GOBUILDID_TAG)
   944  	if sh == nil {
   945  		return 0
   946  	}
   947  
   948  	out.Write(ELF_NOTE_GO_NAME)
   949  	out.Write([]byte(*flagBuildid))
   950  	var zero = make([]byte, 4)
   951  	out.Write(zero[:int(Rnd(int64(len(*flagBuildid)), 4)-int64(len(*flagBuildid)))])
   952  
   953  	return int(sh.size)
   954  }
   955  
   956  // Go specific notes
   957  const (
   958  	ELF_NOTE_GOPKGLIST_TAG = 1
   959  	ELF_NOTE_GOABIHASH_TAG = 2
   960  	ELF_NOTE_GODEPS_TAG    = 3
   961  	ELF_NOTE_GOBUILDID_TAG = 4
   962  )
   963  
   964  var ELF_NOTE_GO_NAME = []byte("Go\x00\x00")
   965  
   966  var elfverneed int
   967  
   968  type Elfaux struct {
   969  	next *Elfaux
   970  	num  int
   971  	vers string
   972  }
   973  
   974  type Elflib struct {
   975  	next *Elflib
   976  	aux  *Elfaux
   977  	file string
   978  }
   979  
   980  func addelflib(list **Elflib, file string, vers string) *Elfaux {
   981  	var lib *Elflib
   982  
   983  	for lib = *list; lib != nil; lib = lib.next {
   984  		if lib.file == file {
   985  			goto havelib
   986  		}
   987  	}
   988  	lib = new(Elflib)
   989  	lib.next = *list
   990  	lib.file = file
   991  	*list = lib
   992  
   993  havelib:
   994  	for aux := lib.aux; aux != nil; aux = aux.next {
   995  		if aux.vers == vers {
   996  			return aux
   997  		}
   998  	}
   999  	aux := new(Elfaux)
  1000  	aux.next = lib.aux
  1001  	aux.vers = vers
  1002  	lib.aux = aux
  1003  
  1004  	return aux
  1005  }
  1006  
  1007  func elfdynhash(ctxt *Link) {
  1008  	if !ctxt.IsELF {
  1009  		return
  1010  	}
  1011  
  1012  	nsym := Nelfsym
  1013  	s := ctxt.Syms.Lookup(".hash", 0)
  1014  	s.Type = sym.SELFROSECT
  1015  	s.Attr |= sym.AttrReachable
  1016  
  1017  	i := nsym
  1018  	nbucket := 1
  1019  	for i > 0 {
  1020  		nbucket++
  1021  		i >>= 1
  1022  	}
  1023  
  1024  	var needlib *Elflib
  1025  	need := make([]*Elfaux, nsym)
  1026  	chain := make([]uint32, nsym)
  1027  	buckets := make([]uint32, nbucket)
  1028  
  1029  	for _, sy := range ctxt.Syms.Allsym {
  1030  		if sy.Dynid <= 0 {
  1031  			continue
  1032  		}
  1033  
  1034  		if sy.Dynimpvers() != "" {
  1035  			need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib(), sy.Dynimpvers())
  1036  		}
  1037  
  1038  		name := sy.Extname()
  1039  		hc := elfhash(name)
  1040  
  1041  		b := hc % uint32(nbucket)
  1042  		chain[sy.Dynid] = buckets[b]
  1043  		buckets[b] = uint32(sy.Dynid)
  1044  	}
  1045  
  1046  	// s390x (ELF64) hash table entries are 8 bytes
  1047  	if ctxt.Arch.Family == sys.S390X {
  1048  		s.AddUint64(ctxt.Arch, uint64(nbucket))
  1049  		s.AddUint64(ctxt.Arch, uint64(nsym))
  1050  		for i := 0; i < nbucket; i++ {
  1051  			s.AddUint64(ctxt.Arch, uint64(buckets[i]))
  1052  		}
  1053  		for i := 0; i < nsym; i++ {
  1054  			s.AddUint64(ctxt.Arch, uint64(chain[i]))
  1055  		}
  1056  	} else {
  1057  		s.AddUint32(ctxt.Arch, uint32(nbucket))
  1058  		s.AddUint32(ctxt.Arch, uint32(nsym))
  1059  		for i := 0; i < nbucket; i++ {
  1060  			s.AddUint32(ctxt.Arch, buckets[i])
  1061  		}
  1062  		for i := 0; i < nsym; i++ {
  1063  			s.AddUint32(ctxt.Arch, chain[i])
  1064  		}
  1065  	}
  1066  
  1067  	// version symbols
  1068  	dynstr := ctxt.Syms.Lookup(".dynstr", 0)
  1069  
  1070  	s = ctxt.Syms.Lookup(".gnu.version_r", 0)
  1071  	i = 2
  1072  	nfile := 0
  1073  	for l := needlib; l != nil; l = l.next {
  1074  		nfile++
  1075  
  1076  		// header
  1077  		s.AddUint16(ctxt.Arch, 1) // table version
  1078  		j := 0
  1079  		for x := l.aux; x != nil; x = x.next {
  1080  			j++
  1081  		}
  1082  		s.AddUint16(ctxt.Arch, uint16(j))                         // aux count
  1083  		s.AddUint32(ctxt.Arch, uint32(Addstring(dynstr, l.file))) // file string offset
  1084  		s.AddUint32(ctxt.Arch, 16)                                // offset from header to first aux
  1085  		if l.next != nil {
  1086  			s.AddUint32(ctxt.Arch, 16+uint32(j)*16) // offset from this header to next
  1087  		} else {
  1088  			s.AddUint32(ctxt.Arch, 0)
  1089  		}
  1090  
  1091  		for x := l.aux; x != nil; x = x.next {
  1092  			x.num = i
  1093  			i++
  1094  
  1095  			// aux struct
  1096  			s.AddUint32(ctxt.Arch, elfhash(x.vers))                   // hash
  1097  			s.AddUint16(ctxt.Arch, 0)                                 // flags
  1098  			s.AddUint16(ctxt.Arch, uint16(x.num))                     // other - index we refer to this by
  1099  			s.AddUint32(ctxt.Arch, uint32(Addstring(dynstr, x.vers))) // version string offset
  1100  			if x.next != nil {
  1101  				s.AddUint32(ctxt.Arch, 16) // offset from this aux to next
  1102  			} else {
  1103  				s.AddUint32(ctxt.Arch, 0)
  1104  			}
  1105  		}
  1106  	}
  1107  
  1108  	// version references
  1109  	s = ctxt.Syms.Lookup(".gnu.version", 0)
  1110  
  1111  	for i := 0; i < nsym; i++ {
  1112  		if i == 0 {
  1113  			s.AddUint16(ctxt.Arch, 0) // first entry - no symbol
  1114  		} else if need[i] == nil {
  1115  			s.AddUint16(ctxt.Arch, 1) // global
  1116  		} else {
  1117  			s.AddUint16(ctxt.Arch, uint16(need[i].num))
  1118  		}
  1119  	}
  1120  
  1121  	s = ctxt.Syms.Lookup(".dynamic", 0)
  1122  	elfverneed = nfile
  1123  	if elfverneed != 0 {
  1124  		elfwritedynentsym(ctxt, s, DT_VERNEED, ctxt.Syms.Lookup(".gnu.version_r", 0))
  1125  		Elfwritedynent(ctxt, s, DT_VERNEEDNUM, uint64(nfile))
  1126  		elfwritedynentsym(ctxt, s, DT_VERSYM, ctxt.Syms.Lookup(".gnu.version", 0))
  1127  	}
  1128  
  1129  	sy := ctxt.Syms.Lookup(elfRelType+".plt", 0)
  1130  	if sy.Size > 0 {
  1131  		if elfRelType == ".rela" {
  1132  			Elfwritedynent(ctxt, s, DT_PLTREL, DT_RELA)
  1133  		} else {
  1134  			Elfwritedynent(ctxt, s, DT_PLTREL, DT_REL)
  1135  		}
  1136  		elfwritedynentsymsize(ctxt, s, DT_PLTRELSZ, sy)
  1137  		elfwritedynentsym(ctxt, s, DT_JMPREL, sy)
  1138  	}
  1139  
  1140  	Elfwritedynent(ctxt, s, DT_NULL, 0)
  1141  }
  1142  
  1143  func elfphload(seg *sym.Segment) *ElfPhdr {
  1144  	ph := newElfPhdr()
  1145  	ph.type_ = PT_LOAD
  1146  	if seg.Rwx&4 != 0 {
  1147  		ph.flags |= PF_R
  1148  	}
  1149  	if seg.Rwx&2 != 0 {
  1150  		ph.flags |= PF_W
  1151  	}
  1152  	if seg.Rwx&1 != 0 {
  1153  		ph.flags |= PF_X
  1154  	}
  1155  	ph.vaddr = seg.Vaddr
  1156  	ph.paddr = seg.Vaddr
  1157  	ph.memsz = seg.Length
  1158  	ph.off = seg.Fileoff
  1159  	ph.filesz = seg.Filelen
  1160  	ph.align = uint64(*FlagRound)
  1161  
  1162  	return ph
  1163  }
  1164  
  1165  func elfphrelro(seg *sym.Segment) {
  1166  	ph := newElfPhdr()
  1167  	ph.type_ = PT_GNU_RELRO
  1168  	ph.vaddr = seg.Vaddr
  1169  	ph.paddr = seg.Vaddr
  1170  	ph.memsz = seg.Length
  1171  	ph.off = seg.Fileoff
  1172  	ph.filesz = seg.Filelen
  1173  	ph.align = uint64(*FlagRound)
  1174  }
  1175  
  1176  func elfshname(name string) *ElfShdr {
  1177  	for i := 0; i < nelfstr; i++ {
  1178  		if name != elfstr[i].s {
  1179  			continue
  1180  		}
  1181  		off := elfstr[i].off
  1182  		for i = 0; i < int(ehdr.shnum); i++ {
  1183  			sh := shdr[i]
  1184  			if sh.name == uint32(off) {
  1185  				return sh
  1186  			}
  1187  		}
  1188  		return newElfShdr(int64(off))
  1189  	}
  1190  	Exitf("cannot find elf name %s", name)
  1191  	return nil
  1192  }
  1193  
  1194  // Create an ElfShdr for the section with name.
  1195  // Create a duplicate if one already exists with that name
  1196  func elfshnamedup(name string) *ElfShdr {
  1197  	for i := 0; i < nelfstr; i++ {
  1198  		if name == elfstr[i].s {
  1199  			off := elfstr[i].off
  1200  			return newElfShdr(int64(off))
  1201  		}
  1202  	}
  1203  
  1204  	Errorf(nil, "cannot find elf name %s", name)
  1205  	errorexit()
  1206  	return nil
  1207  }
  1208  
  1209  func elfshalloc(sect *sym.Section) *ElfShdr {
  1210  	sh := elfshname(sect.Name)
  1211  	sect.Elfsect = sh
  1212  	return sh
  1213  }
  1214  
  1215  func elfshbits(linkmode LinkMode, sect *sym.Section) *ElfShdr {
  1216  	var sh *ElfShdr
  1217  
  1218  	if sect.Name == ".text" {
  1219  		if sect.Elfsect == nil {
  1220  			sect.Elfsect = elfshnamedup(sect.Name)
  1221  		}
  1222  		sh = sect.Elfsect.(*ElfShdr)
  1223  	} else {
  1224  		sh = elfshalloc(sect)
  1225  	}
  1226  
  1227  	// If this section has already been set up as a note, we assume type_ and
  1228  	// flags are already correct, but the other fields still need filling in.
  1229  	if sh.type_ == SHT_NOTE {
  1230  		if linkmode != LinkExternal {
  1231  			// TODO(mwhudson): the approach here will work OK when
  1232  			// linking internally for notes that we want to be included
  1233  			// in a loadable segment (e.g. the abihash note) but not for
  1234  			// notes that we do not want to be mapped (e.g. the package
  1235  			// list note). The real fix is probably to define new values
  1236  			// for Symbol.Type corresponding to mapped and unmapped notes
  1237  			// and handle them in dodata().
  1238  			Errorf(nil, "sh.type_ == SHT_NOTE in elfshbits when linking internally")
  1239  		}
  1240  		sh.addralign = uint64(sect.Align)
  1241  		sh.size = sect.Length
  1242  		sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
  1243  		return sh
  1244  	}
  1245  	if sh.type_ > 0 {
  1246  		return sh
  1247  	}
  1248  
  1249  	if sect.Vaddr < sect.Seg.Vaddr+sect.Seg.Filelen {
  1250  		sh.type_ = SHT_PROGBITS
  1251  	} else {
  1252  		sh.type_ = SHT_NOBITS
  1253  	}
  1254  	sh.flags = SHF_ALLOC
  1255  	if sect.Rwx&1 != 0 {
  1256  		sh.flags |= SHF_EXECINSTR
  1257  	}
  1258  	if sect.Rwx&2 != 0 {
  1259  		sh.flags |= SHF_WRITE
  1260  	}
  1261  	if sect.Name == ".tbss" {
  1262  		sh.flags |= SHF_TLS
  1263  		sh.type_ = SHT_NOBITS
  1264  	}
  1265  	if strings.HasPrefix(sect.Name, ".debug") || strings.HasPrefix(sect.Name, ".zdebug") {
  1266  		sh.flags = 0
  1267  	}
  1268  
  1269  	if linkmode != LinkExternal {
  1270  		sh.addr = sect.Vaddr
  1271  	}
  1272  	sh.addralign = uint64(sect.Align)
  1273  	sh.size = sect.Length
  1274  	if sect.Name != ".tbss" {
  1275  		sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
  1276  	}
  1277  
  1278  	return sh
  1279  }
  1280  
  1281  func elfshreloc(arch *sys.Arch, sect *sym.Section) *ElfShdr {
  1282  	// If main section is SHT_NOBITS, nothing to relocate.
  1283  	// Also nothing to relocate in .shstrtab or notes.
  1284  	if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
  1285  		return nil
  1286  	}
  1287  	if sect.Name == ".shstrtab" || sect.Name == ".tbss" {
  1288  		return nil
  1289  	}
  1290  	if sect.Elfsect.(*ElfShdr).type_ == SHT_NOTE {
  1291  		return nil
  1292  	}
  1293  
  1294  	typ := SHT_REL
  1295  	if elfRelType == ".rela" {
  1296  		typ = SHT_RELA
  1297  	}
  1298  
  1299  	sh := elfshname(elfRelType + sect.Name)
  1300  	// There could be multiple text sections but each needs
  1301  	// its own .rela.text.
  1302  
  1303  	if sect.Name == ".text" {
  1304  		if sh.info != 0 && sh.info != uint32(sect.Elfsect.(*ElfShdr).shnum) {
  1305  			sh = elfshnamedup(elfRelType + sect.Name)
  1306  		}
  1307  	}
  1308  
  1309  	sh.type_ = uint32(typ)
  1310  	sh.entsize = uint64(arch.RegSize) * 2
  1311  	if typ == SHT_RELA {
  1312  		sh.entsize += uint64(arch.RegSize)
  1313  	}
  1314  	sh.link = uint32(elfshname(".symtab").shnum)
  1315  	sh.info = uint32(sect.Elfsect.(*ElfShdr).shnum)
  1316  	sh.off = sect.Reloff
  1317  	sh.size = sect.Rellen
  1318  	sh.addralign = uint64(arch.RegSize)
  1319  	return sh
  1320  }
  1321  
  1322  func elfrelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) {
  1323  	// If main section is SHT_NOBITS, nothing to relocate.
  1324  	// Also nothing to relocate in .shstrtab.
  1325  	if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
  1326  		return
  1327  	}
  1328  	if sect.Name == ".shstrtab" {
  1329  		return
  1330  	}
  1331  
  1332  	sect.Reloff = uint64(ctxt.Out.Offset())
  1333  	for i, s := range syms {
  1334  		if !s.Attr.Reachable() {
  1335  			continue
  1336  		}
  1337  		if uint64(s.Value) >= sect.Vaddr {
  1338  			syms = syms[i:]
  1339  			break
  1340  		}
  1341  	}
  1342  
  1343  	eaddr := int32(sect.Vaddr + sect.Length)
  1344  	for _, s := range syms {
  1345  		if !s.Attr.Reachable() {
  1346  			continue
  1347  		}
  1348  		if s.Value >= int64(eaddr) {
  1349  			break
  1350  		}
  1351  		for ri := range s.R {
  1352  			r := &s.R[ri]
  1353  			if r.Done {
  1354  				continue
  1355  			}
  1356  			if r.Xsym == nil {
  1357  				Errorf(s, "missing xsym in relocation %#v %#v", r.Sym.Name, s)
  1358  				continue
  1359  			}
  1360  			if r.Xsym.ElfsymForReloc() == 0 {
  1361  				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)
  1362  			}
  1363  			if !r.Xsym.Attr.Reachable() {
  1364  				Errorf(s, "unreachable reloc %d (%s) target %v", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Xsym.Name)
  1365  			}
  1366  			if !thearch.Elfreloc1(ctxt, r, int64(uint64(s.Value+int64(r.Off))-sect.Vaddr)) {
  1367  				Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name)
  1368  			}
  1369  		}
  1370  	}
  1371  
  1372  	sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
  1373  }
  1374  
  1375  func Elfemitreloc(ctxt *Link) {
  1376  	for ctxt.Out.Offset()&7 != 0 {
  1377  		ctxt.Out.Write8(0)
  1378  	}
  1379  
  1380  	for _, sect := range Segtext.Sections {
  1381  		if sect.Name == ".text" {
  1382  			elfrelocsect(ctxt, sect, ctxt.Textp)
  1383  		} else {
  1384  			elfrelocsect(ctxt, sect, datap)
  1385  		}
  1386  	}
  1387  
  1388  	for _, sect := range Segrodata.Sections {
  1389  		elfrelocsect(ctxt, sect, datap)
  1390  	}
  1391  	for _, sect := range Segrelrodata.Sections {
  1392  		elfrelocsect(ctxt, sect, datap)
  1393  	}
  1394  	for _, sect := range Segdata.Sections {
  1395  		elfrelocsect(ctxt, sect, datap)
  1396  	}
  1397  	for _, sect := range Segdwarf.Sections {
  1398  		elfrelocsect(ctxt, sect, dwarfp)
  1399  	}
  1400  }
  1401  
  1402  func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) {
  1403  	s := ctxt.Syms.Lookup(sectionName, 0)
  1404  	s.Attr |= sym.AttrReachable
  1405  	s.Type = sym.SELFROSECT
  1406  	// namesz
  1407  	s.AddUint32(ctxt.Arch, uint32(len(ELF_NOTE_GO_NAME)))
  1408  	// descsz
  1409  	s.AddUint32(ctxt.Arch, uint32(len(desc)))
  1410  	// tag
  1411  	s.AddUint32(ctxt.Arch, tag)
  1412  	// name + padding
  1413  	s.P = append(s.P, ELF_NOTE_GO_NAME...)
  1414  	for len(s.P)%4 != 0 {
  1415  		s.P = append(s.P, 0)
  1416  	}
  1417  	// desc + padding
  1418  	s.P = append(s.P, desc...)
  1419  	for len(s.P)%4 != 0 {
  1420  		s.P = append(s.P, 0)
  1421  	}
  1422  	s.Size = int64(len(s.P))
  1423  	s.Align = 4
  1424  }
  1425  
  1426  func (ctxt *Link) doelf() {
  1427  	if !ctxt.IsELF {
  1428  		return
  1429  	}
  1430  
  1431  	/* predefine strings we need for section headers */
  1432  	shstrtab := ctxt.Syms.Lookup(".shstrtab", 0)
  1433  
  1434  	shstrtab.Type = sym.SELFROSECT
  1435  	shstrtab.Attr |= sym.AttrReachable
  1436  
  1437  	Addstring(shstrtab, "")
  1438  	Addstring(shstrtab, ".text")
  1439  	Addstring(shstrtab, ".noptrdata")
  1440  	Addstring(shstrtab, ".data")
  1441  	Addstring(shstrtab, ".bss")
  1442  	Addstring(shstrtab, ".noptrbss")
  1443  	Addstring(shstrtab, "__libfuzzer_extra_counters")
  1444  	Addstring(shstrtab, ".go.buildinfo")
  1445  
  1446  	// generate .tbss section for dynamic internal linker or external
  1447  	// linking, so that various binutils could correctly calculate
  1448  	// PT_TLS size. See https://golang.org/issue/5200.
  1449  	if !*FlagD || ctxt.LinkMode == LinkExternal {
  1450  		Addstring(shstrtab, ".tbss")
  1451  	}
  1452  	if ctxt.HeadType == objabi.Hnetbsd {
  1453  		Addstring(shstrtab, ".note.netbsd.ident")
  1454  	}
  1455  	if ctxt.HeadType == objabi.Hopenbsd {
  1456  		Addstring(shstrtab, ".note.openbsd.ident")
  1457  	}
  1458  	if len(buildinfo) > 0 {
  1459  		Addstring(shstrtab, ".note.gnu.build-id")
  1460  	}
  1461  	if *flagBuildid != "" {
  1462  		Addstring(shstrtab, ".note.go.buildid")
  1463  	}
  1464  	Addstring(shstrtab, ".elfdata")
  1465  	Addstring(shstrtab, ".rodata")
  1466  	// See the comment about data.rel.ro.FOO section names in data.go.
  1467  	relro_prefix := ""
  1468  	if ctxt.UseRelro() {
  1469  		Addstring(shstrtab, ".data.rel.ro")
  1470  		relro_prefix = ".data.rel.ro"
  1471  	}
  1472  	Addstring(shstrtab, relro_prefix+".typelink")
  1473  	Addstring(shstrtab, relro_prefix+".itablink")
  1474  	Addstring(shstrtab, relro_prefix+".gosymtab")
  1475  	Addstring(shstrtab, relro_prefix+".gopclntab")
  1476  
  1477  	if ctxt.LinkMode == LinkExternal {
  1478  		*FlagD = true
  1479  
  1480  		Addstring(shstrtab, elfRelType+".text")
  1481  		Addstring(shstrtab, elfRelType+".rodata")
  1482  		Addstring(shstrtab, elfRelType+relro_prefix+".typelink")
  1483  		Addstring(shstrtab, elfRelType+relro_prefix+".itablink")
  1484  		Addstring(shstrtab, elfRelType+relro_prefix+".gosymtab")
  1485  		Addstring(shstrtab, elfRelType+relro_prefix+".gopclntab")
  1486  		Addstring(shstrtab, elfRelType+".noptrdata")
  1487  		Addstring(shstrtab, elfRelType+".data")
  1488  		if ctxt.UseRelro() {
  1489  			Addstring(shstrtab, elfRelType+".data.rel.ro")
  1490  		}
  1491  		Addstring(shstrtab, elfRelType+".go.buildinfo")
  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.RISCV64:
  1763  		eh.machine = EM_RISCV
  1764  	case sys.S390X:
  1765  		eh.machine = EM_S390
  1766  	}
  1767  
  1768  	elfreserve := int64(ELFRESERVE)
  1769  
  1770  	numtext := int64(0)
  1771  	for _, sect := range Segtext.Sections {
  1772  		if sect.Name == ".text" {
  1773  			numtext++
  1774  		}
  1775  	}
  1776  
  1777  	// If there are multiple text sections, extra space is needed
  1778  	// in the elfreserve for the additional .text and .rela.text
  1779  	// section headers.  It can handle 4 extra now. Headers are
  1780  	// 64 bytes.
  1781  
  1782  	if numtext > 4 {
  1783  		elfreserve += elfreserve + numtext*64*2
  1784  	}
  1785  
  1786  	startva := *FlagTextAddr - int64(HEADR)
  1787  	resoff := elfreserve
  1788  
  1789  	var pph *ElfPhdr
  1790  	var pnote *ElfPhdr
  1791  	if ctxt.LinkMode == LinkExternal {
  1792  		/* skip program headers */
  1793  		eh.phoff = 0
  1794  
  1795  		eh.phentsize = 0
  1796  
  1797  		if ctxt.BuildMode == BuildModeShared {
  1798  			sh := elfshname(".note.go.pkg-list")
  1799  			sh.type_ = SHT_NOTE
  1800  			sh = elfshname(".note.go.abihash")
  1801  			sh.type_ = SHT_NOTE
  1802  			sh.flags = SHF_ALLOC
  1803  			sh = elfshname(".note.go.deps")
  1804  			sh.type_ = SHT_NOTE
  1805  		}
  1806  
  1807  		if *flagBuildid != "" {
  1808  			sh := elfshname(".note.go.buildid")
  1809  			sh.type_ = SHT_NOTE
  1810  			sh.flags = SHF_ALLOC
  1811  		}
  1812  
  1813  		goto elfobj
  1814  	}
  1815  
  1816  	/* program header info */
  1817  	pph = newElfPhdr()
  1818  
  1819  	pph.type_ = PT_PHDR
  1820  	pph.flags = PF_R
  1821  	pph.off = uint64(eh.ehsize)
  1822  	pph.vaddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off
  1823  	pph.paddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off
  1824  	pph.align = uint64(*FlagRound)
  1825  
  1826  	/*
  1827  	 * PHDR must be in a loaded segment. Adjust the text
  1828  	 * segment boundaries downwards to include it.
  1829  	 */
  1830  	{
  1831  		o := int64(Segtext.Vaddr - pph.vaddr)
  1832  		Segtext.Vaddr -= uint64(o)
  1833  		Segtext.Length += uint64(o)
  1834  		o = int64(Segtext.Fileoff - pph.off)
  1835  		Segtext.Fileoff -= uint64(o)
  1836  		Segtext.Filelen += uint64(o)
  1837  	}
  1838  
  1839  	if !*FlagD { /* -d suppresses dynamic loader format */
  1840  		/* interpreter */
  1841  		sh := elfshname(".interp")
  1842  
  1843  		sh.type_ = SHT_PROGBITS
  1844  		sh.flags = SHF_ALLOC
  1845  		sh.addralign = 1
  1846  
  1847  		if interpreter == "" && objabi.GO_LDSO != "" {
  1848  			interpreter = objabi.GO_LDSO
  1849  		}
  1850  
  1851  		if interpreter == "" {
  1852  			switch ctxt.HeadType {
  1853  			case objabi.Hlinux:
  1854  				interpreter = thearch.Linuxdynld
  1855  
  1856  			case objabi.Hfreebsd:
  1857  				interpreter = thearch.Freebsddynld
  1858  
  1859  			case objabi.Hnetbsd:
  1860  				interpreter = thearch.Netbsddynld
  1861  
  1862  			case objabi.Hopenbsd:
  1863  				interpreter = thearch.Openbsddynld
  1864  
  1865  			case objabi.Hdragonfly:
  1866  				interpreter = thearch.Dragonflydynld
  1867  
  1868  			case objabi.Hsolaris:
  1869  				interpreter = thearch.Solarisdynld
  1870  			}
  1871  		}
  1872  
  1873  		resoff -= int64(elfinterp(sh, uint64(startva), uint64(resoff), interpreter))
  1874  
  1875  		ph := newElfPhdr()
  1876  		ph.type_ = PT_INTERP
  1877  		ph.flags = PF_R
  1878  		phsh(ph, sh)
  1879  	}
  1880  
  1881  	pnote = nil
  1882  	if ctxt.HeadType == objabi.Hnetbsd || ctxt.HeadType == objabi.Hopenbsd {
  1883  		var sh *ElfShdr
  1884  		switch ctxt.HeadType {
  1885  		case objabi.Hnetbsd:
  1886  			sh = elfshname(".note.netbsd.ident")
  1887  			resoff -= int64(elfnetbsdsig(sh, uint64(startva), uint64(resoff)))
  1888  
  1889  		case objabi.Hopenbsd:
  1890  			sh = elfshname(".note.openbsd.ident")
  1891  			resoff -= int64(elfopenbsdsig(sh, uint64(startva), uint64(resoff)))
  1892  		}
  1893  
  1894  		pnote = newElfPhdr()
  1895  		pnote.type_ = PT_NOTE
  1896  		pnote.flags = PF_R
  1897  		phsh(pnote, sh)
  1898  	}
  1899  
  1900  	if len(buildinfo) > 0 {
  1901  		sh := elfshname(".note.gnu.build-id")
  1902  		resoff -= int64(elfbuildinfo(sh, uint64(startva), uint64(resoff)))
  1903  
  1904  		if pnote == nil {
  1905  			pnote = newElfPhdr()
  1906  			pnote.type_ = PT_NOTE
  1907  			pnote.flags = PF_R
  1908  		}
  1909  
  1910  		phsh(pnote, sh)
  1911  	}
  1912  
  1913  	if *flagBuildid != "" {
  1914  		sh := elfshname(".note.go.buildid")
  1915  		resoff -= int64(elfgobuildid(sh, uint64(startva), uint64(resoff)))
  1916  
  1917  		pnote := newElfPhdr()
  1918  		pnote.type_ = PT_NOTE
  1919  		pnote.flags = PF_R
  1920  		phsh(pnote, sh)
  1921  	}
  1922  
  1923  	// Additions to the reserved area must be above this line.
  1924  
  1925  	elfphload(&Segtext)
  1926  	if len(Segrodata.Sections) > 0 {
  1927  		elfphload(&Segrodata)
  1928  	}
  1929  	if len(Segrelrodata.Sections) > 0 {
  1930  		elfphload(&Segrelrodata)
  1931  		elfphrelro(&Segrelrodata)
  1932  	}
  1933  	elfphload(&Segdata)
  1934  
  1935  	/* Dynamic linking sections */
  1936  	if !*FlagD {
  1937  		sh := elfshname(".dynsym")
  1938  		sh.type_ = SHT_DYNSYM
  1939  		sh.flags = SHF_ALLOC
  1940  		if elf64 {
  1941  			sh.entsize = ELF64SYMSIZE
  1942  		} else {
  1943  			sh.entsize = ELF32SYMSIZE
  1944  		}
  1945  		sh.addralign = uint64(ctxt.Arch.RegSize)
  1946  		sh.link = uint32(elfshname(".dynstr").shnum)
  1947  
  1948  		// sh.info is the index of first non-local symbol (number of local symbols)
  1949  		s := ctxt.Syms.Lookup(".dynsym", 0)
  1950  		i := uint32(0)
  1951  		for sub := s; sub != nil; sub = sub.Sub {
  1952  			i++
  1953  			if !sub.Attr.Local() {
  1954  				break
  1955  			}
  1956  		}
  1957  		sh.info = i
  1958  		shsym(sh, s)
  1959  
  1960  		sh = elfshname(".dynstr")
  1961  		sh.type_ = SHT_STRTAB
  1962  		sh.flags = SHF_ALLOC
  1963  		sh.addralign = 1
  1964  		shsym(sh, ctxt.Syms.Lookup(".dynstr", 0))
  1965  
  1966  		if elfverneed != 0 {
  1967  			sh := elfshname(".gnu.version")
  1968  			sh.type_ = SHT_GNU_VERSYM
  1969  			sh.flags = SHF_ALLOC
  1970  			sh.addralign = 2
  1971  			sh.link = uint32(elfshname(".dynsym").shnum)
  1972  			sh.entsize = 2
  1973  			shsym(sh, ctxt.Syms.Lookup(".gnu.version", 0))
  1974  
  1975  			sh = elfshname(".gnu.version_r")
  1976  			sh.type_ = SHT_GNU_VERNEED
  1977  			sh.flags = SHF_ALLOC
  1978  			sh.addralign = uint64(ctxt.Arch.RegSize)
  1979  			sh.info = uint32(elfverneed)
  1980  			sh.link = uint32(elfshname(".dynstr").shnum)
  1981  			shsym(sh, ctxt.Syms.Lookup(".gnu.version_r", 0))
  1982  		}
  1983  
  1984  		if elfRelType == ".rela" {
  1985  			sh := elfshname(".rela.plt")
  1986  			sh.type_ = SHT_RELA
  1987  			sh.flags = SHF_ALLOC
  1988  			sh.entsize = ELF64RELASIZE
  1989  			sh.addralign = uint64(ctxt.Arch.RegSize)
  1990  			sh.link = uint32(elfshname(".dynsym").shnum)
  1991  			sh.info = uint32(elfshname(".plt").shnum)
  1992  			shsym(sh, ctxt.Syms.Lookup(".rela.plt", 0))
  1993  
  1994  			sh = elfshname(".rela")
  1995  			sh.type_ = SHT_RELA
  1996  			sh.flags = SHF_ALLOC
  1997  			sh.entsize = ELF64RELASIZE
  1998  			sh.addralign = 8
  1999  			sh.link = uint32(elfshname(".dynsym").shnum)
  2000  			shsym(sh, ctxt.Syms.Lookup(".rela", 0))
  2001  		} else {
  2002  			sh := elfshname(".rel.plt")
  2003  			sh.type_ = SHT_REL
  2004  			sh.flags = SHF_ALLOC
  2005  			sh.entsize = ELF32RELSIZE
  2006  			sh.addralign = 4
  2007  			sh.link = uint32(elfshname(".dynsym").shnum)
  2008  			shsym(sh, ctxt.Syms.Lookup(".rel.plt", 0))
  2009  
  2010  			sh = elfshname(".rel")
  2011  			sh.type_ = SHT_REL
  2012  			sh.flags = SHF_ALLOC
  2013  			sh.entsize = ELF32RELSIZE
  2014  			sh.addralign = 4
  2015  			sh.link = uint32(elfshname(".dynsym").shnum)
  2016  			shsym(sh, ctxt.Syms.Lookup(".rel", 0))
  2017  		}
  2018  
  2019  		if eh.machine == EM_PPC64 {
  2020  			sh := elfshname(".glink")
  2021  			sh.type_ = SHT_PROGBITS
  2022  			sh.flags = SHF_ALLOC + SHF_EXECINSTR
  2023  			sh.addralign = 4
  2024  			shsym(sh, ctxt.Syms.Lookup(".glink", 0))
  2025  		}
  2026  
  2027  		sh = elfshname(".plt")
  2028  		sh.type_ = SHT_PROGBITS
  2029  		sh.flags = SHF_ALLOC + SHF_EXECINSTR
  2030  		if eh.machine == EM_X86_64 {
  2031  			sh.entsize = 16
  2032  		} else if eh.machine == EM_S390 {
  2033  			sh.entsize = 32
  2034  		} else if eh.machine == EM_PPC64 {
  2035  			// On ppc64, this is just a table of addresses
  2036  			// filled by the dynamic linker
  2037  			sh.type_ = SHT_NOBITS
  2038  
  2039  			sh.flags = SHF_ALLOC + SHF_WRITE
  2040  			sh.entsize = 8
  2041  		} else {
  2042  			sh.entsize = 4
  2043  		}
  2044  		sh.addralign = sh.entsize
  2045  		shsym(sh, ctxt.Syms.Lookup(".plt", 0))
  2046  
  2047  		// On ppc64, .got comes from the input files, so don't
  2048  		// create it here, and .got.plt is not used.
  2049  		if eh.machine != EM_PPC64 {
  2050  			sh := elfshname(".got")
  2051  			sh.type_ = SHT_PROGBITS
  2052  			sh.flags = SHF_ALLOC + SHF_WRITE
  2053  			sh.entsize = uint64(ctxt.Arch.RegSize)
  2054  			sh.addralign = uint64(ctxt.Arch.RegSize)
  2055  			shsym(sh, ctxt.Syms.Lookup(".got", 0))
  2056  
  2057  			sh = elfshname(".got.plt")
  2058  			sh.type_ = SHT_PROGBITS
  2059  			sh.flags = SHF_ALLOC + SHF_WRITE
  2060  			sh.entsize = uint64(ctxt.Arch.RegSize)
  2061  			sh.addralign = uint64(ctxt.Arch.RegSize)
  2062  			shsym(sh, ctxt.Syms.Lookup(".got.plt", 0))
  2063  		}
  2064  
  2065  		sh = elfshname(".hash")
  2066  		sh.type_ = SHT_HASH
  2067  		sh.flags = SHF_ALLOC
  2068  		sh.entsize = 4
  2069  		sh.addralign = uint64(ctxt.Arch.RegSize)
  2070  		sh.link = uint32(elfshname(".dynsym").shnum)
  2071  		shsym(sh, ctxt.Syms.Lookup(".hash", 0))
  2072  
  2073  		/* sh and PT_DYNAMIC for .dynamic section */
  2074  		sh = elfshname(".dynamic")
  2075  
  2076  		sh.type_ = SHT_DYNAMIC
  2077  		sh.flags = SHF_ALLOC + SHF_WRITE
  2078  		sh.entsize = 2 * uint64(ctxt.Arch.RegSize)
  2079  		sh.addralign = uint64(ctxt.Arch.RegSize)
  2080  		sh.link = uint32(elfshname(".dynstr").shnum)
  2081  		shsym(sh, ctxt.Syms.Lookup(".dynamic", 0))
  2082  		ph := newElfPhdr()
  2083  		ph.type_ = PT_DYNAMIC
  2084  		ph.flags = PF_R + PF_W
  2085  		phsh(ph, sh)
  2086  
  2087  		/*
  2088  		 * Thread-local storage segment (really just size).
  2089  		 */
  2090  		tlssize := uint64(0)
  2091  		for _, sect := range Segdata.Sections {
  2092  			if sect.Name == ".tbss" {
  2093  				tlssize = sect.Length
  2094  			}
  2095  		}
  2096  		if tlssize != 0 {
  2097  			ph := newElfPhdr()
  2098  			ph.type_ = PT_TLS
  2099  			ph.flags = PF_R
  2100  			ph.memsz = tlssize
  2101  			ph.align = uint64(ctxt.Arch.RegSize)
  2102  		}
  2103  	}
  2104  
  2105  	if ctxt.HeadType == objabi.Hlinux {
  2106  		ph := newElfPhdr()
  2107  		ph.type_ = PT_GNU_STACK
  2108  		ph.flags = PF_W + PF_R
  2109  		ph.align = uint64(ctxt.Arch.RegSize)
  2110  
  2111  		ph = newElfPhdr()
  2112  		ph.type_ = PT_PAX_FLAGS
  2113  		ph.flags = 0x2a00 // mprotect, randexec, emutramp disabled
  2114  		ph.align = uint64(ctxt.Arch.RegSize)
  2115  	} else if ctxt.HeadType == objabi.Hsolaris {
  2116  		ph := newElfPhdr()
  2117  		ph.type_ = PT_SUNWSTACK
  2118  		ph.flags = PF_W + PF_R
  2119  	}
  2120  
  2121  elfobj:
  2122  	sh := elfshname(".shstrtab")
  2123  	sh.type_ = SHT_STRTAB
  2124  	sh.addralign = 1
  2125  	shsym(sh, ctxt.Syms.Lookup(".shstrtab", 0))
  2126  	eh.shstrndx = uint16(sh.shnum)
  2127  
  2128  	// put these sections early in the list
  2129  	if !*FlagS {
  2130  		elfshname(".symtab")
  2131  		elfshname(".strtab")
  2132  	}
  2133  
  2134  	for _, sect := range Segtext.Sections {
  2135  		elfshbits(ctxt.LinkMode, sect)
  2136  	}
  2137  	for _, sect := range Segrodata.Sections {
  2138  		elfshbits(ctxt.LinkMode, sect)
  2139  	}
  2140  	for _, sect := range Segrelrodata.Sections {
  2141  		elfshbits(ctxt.LinkMode, sect)
  2142  	}
  2143  	for _, sect := range Segdata.Sections {
  2144  		elfshbits(ctxt.LinkMode, sect)
  2145  	}
  2146  	for _, sect := range Segdwarf.Sections {
  2147  		elfshbits(ctxt.LinkMode, sect)
  2148  	}
  2149  
  2150  	if ctxt.LinkMode == LinkExternal {
  2151  		for _, sect := range Segtext.Sections {
  2152  			elfshreloc(ctxt.Arch, sect)
  2153  		}
  2154  		for _, sect := range Segrodata.Sections {
  2155  			elfshreloc(ctxt.Arch, sect)
  2156  		}
  2157  		for _, sect := range Segrelrodata.Sections {
  2158  			elfshreloc(ctxt.Arch, sect)
  2159  		}
  2160  		for _, sect := range Segdata.Sections {
  2161  			elfshreloc(ctxt.Arch, sect)
  2162  		}
  2163  		for _, s := range dwarfp {
  2164  			if len(s.R) > 0 || s.Type == sym.SDWARFINFO || s.Type == sym.SDWARFLOC {
  2165  				elfshreloc(ctxt.Arch, s.Sect)
  2166  			}
  2167  		}
  2168  		// add a .note.GNU-stack section to mark the stack as non-executable
  2169  		sh := elfshname(".note.GNU-stack")
  2170  
  2171  		sh.type_ = SHT_PROGBITS
  2172  		sh.addralign = 1
  2173  		sh.flags = 0
  2174  	}
  2175  
  2176  	if !*FlagS {
  2177  		sh := elfshname(".symtab")
  2178  		sh.type_ = SHT_SYMTAB
  2179  		sh.off = uint64(symo)
  2180  		sh.size = uint64(Symsize)
  2181  		sh.addralign = uint64(ctxt.Arch.RegSize)
  2182  		sh.entsize = 8 + 2*uint64(ctxt.Arch.RegSize)
  2183  		sh.link = uint32(elfshname(".strtab").shnum)
  2184  		sh.info = uint32(elfglobalsymndx)
  2185  
  2186  		sh = elfshname(".strtab")
  2187  		sh.type_ = SHT_STRTAB
  2188  		sh.off = uint64(symo) + uint64(Symsize)
  2189  		sh.size = uint64(len(Elfstrdat))
  2190  		sh.addralign = 1
  2191  	}
  2192  
  2193  	/* Main header */
  2194  	eh.ident[EI_MAG0] = '\177'
  2195  
  2196  	eh.ident[EI_MAG1] = 'E'
  2197  	eh.ident[EI_MAG2] = 'L'
  2198  	eh.ident[EI_MAG3] = 'F'
  2199  	if ctxt.HeadType == objabi.Hfreebsd {
  2200  		eh.ident[EI_OSABI] = ELFOSABI_FREEBSD
  2201  	} else if ctxt.HeadType == objabi.Hnetbsd {
  2202  		eh.ident[EI_OSABI] = ELFOSABI_NETBSD
  2203  	} else if ctxt.HeadType == objabi.Hopenbsd {
  2204  		eh.ident[EI_OSABI] = ELFOSABI_OPENBSD
  2205  	} else if ctxt.HeadType == objabi.Hdragonfly {
  2206  		eh.ident[EI_OSABI] = ELFOSABI_NONE
  2207  	}
  2208  	if elf64 {
  2209  		eh.ident[EI_CLASS] = ELFCLASS64
  2210  	} else {
  2211  		eh.ident[EI_CLASS] = ELFCLASS32
  2212  	}
  2213  	if ctxt.Arch.ByteOrder == binary.BigEndian {
  2214  		eh.ident[EI_DATA] = ELFDATA2MSB
  2215  	} else {
  2216  		eh.ident[EI_DATA] = ELFDATA2LSB
  2217  	}
  2218  	eh.ident[EI_VERSION] = EV_CURRENT
  2219  
  2220  	if ctxt.LinkMode == LinkExternal {
  2221  		eh.type_ = ET_REL
  2222  	} else if ctxt.BuildMode == BuildModePIE {
  2223  		eh.type_ = ET_DYN
  2224  	} else {
  2225  		eh.type_ = ET_EXEC
  2226  	}
  2227  
  2228  	if ctxt.LinkMode != LinkExternal {
  2229  		eh.entry = uint64(Entryvalue(ctxt))
  2230  	}
  2231  
  2232  	eh.version = EV_CURRENT
  2233  
  2234  	if pph != nil {
  2235  		pph.filesz = uint64(eh.phnum) * uint64(eh.phentsize)
  2236  		pph.memsz = pph.filesz
  2237  	}
  2238  
  2239  	ctxt.Out.SeekSet(0)
  2240  	a := int64(0)
  2241  	a += int64(elfwritehdr(ctxt.Out))
  2242  	a += int64(elfwritephdrs(ctxt.Out))
  2243  	a += int64(elfwriteshdrs(ctxt.Out))
  2244  	if !*FlagD {
  2245  		a += int64(elfwriteinterp(ctxt.Out))
  2246  	}
  2247  	if ctxt.LinkMode != LinkExternal {
  2248  		if ctxt.HeadType == objabi.Hnetbsd {
  2249  			a += int64(elfwritenetbsdsig(ctxt.Out))
  2250  		}
  2251  		if ctxt.HeadType == objabi.Hopenbsd {
  2252  			a += int64(elfwriteopenbsdsig(ctxt.Out))
  2253  		}
  2254  		if len(buildinfo) > 0 {
  2255  			a += int64(elfwritebuildinfo(ctxt.Out))
  2256  		}
  2257  		if *flagBuildid != "" {
  2258  			a += int64(elfwritegobuildid(ctxt.Out))
  2259  		}
  2260  	}
  2261  
  2262  	if a > elfreserve {
  2263  		Errorf(nil, "ELFRESERVE too small: %d > %d with %d text sections", a, elfreserve, numtext)
  2264  	}
  2265  }
  2266  
  2267  func elfadddynsym(ctxt *Link, s *sym.Symbol) {
  2268  	if elf64 {
  2269  		s.Dynid = int32(Nelfsym)
  2270  		Nelfsym++
  2271  
  2272  		d := ctxt.Syms.Lookup(".dynsym", 0)
  2273  
  2274  		name := s.Extname()
  2275  		d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
  2276  
  2277  		/* type */
  2278  		t := STB_GLOBAL << 4
  2279  
  2280  		if s.Attr.CgoExport() && s.Type == sym.STEXT {
  2281  			t |= STT_FUNC
  2282  		} else {
  2283  			t |= STT_OBJECT
  2284  		}
  2285  		d.AddUint8(uint8(t))
  2286  
  2287  		/* reserved */
  2288  		d.AddUint8(0)
  2289  
  2290  		/* section where symbol is defined */
  2291  		if s.Type == sym.SDYNIMPORT {
  2292  			d.AddUint16(ctxt.Arch, SHN_UNDEF)
  2293  		} else {
  2294  			d.AddUint16(ctxt.Arch, 1)
  2295  		}
  2296  
  2297  		/* value */
  2298  		if s.Type == sym.SDYNIMPORT {
  2299  			d.AddUint64(ctxt.Arch, 0)
  2300  		} else {
  2301  			d.AddAddr(ctxt.Arch, s)
  2302  		}
  2303  
  2304  		/* size of object */
  2305  		d.AddUint64(ctxt.Arch, uint64(s.Size))
  2306  
  2307  		if ctxt.Arch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib() != "" && !seenlib[s.Dynimplib()] {
  2308  			Elfwritedynent(ctxt, ctxt.Syms.Lookup(".dynamic", 0), DT_NEEDED, uint64(Addstring(ctxt.Syms.Lookup(".dynstr", 0), s.Dynimplib())))
  2309  		}
  2310  	} else {
  2311  		s.Dynid = int32(Nelfsym)
  2312  		Nelfsym++
  2313  
  2314  		d := ctxt.Syms.Lookup(".dynsym", 0)
  2315  
  2316  		/* name */
  2317  		name := s.Extname()
  2318  
  2319  		d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
  2320  
  2321  		/* value */
  2322  		if s.Type == sym.SDYNIMPORT {
  2323  			d.AddUint32(ctxt.Arch, 0)
  2324  		} else {
  2325  			d.AddAddr(ctxt.Arch, s)
  2326  		}
  2327  
  2328  		/* size of object */
  2329  		d.AddUint32(ctxt.Arch, uint32(s.Size))
  2330  
  2331  		/* type */
  2332  		t := STB_GLOBAL << 4
  2333  
  2334  		// TODO(mwhudson): presumably the behavior should actually be the same on both arm and 386.
  2335  		if ctxt.Arch.Family == sys.I386 && s.Attr.CgoExport() && s.Type == sym.STEXT {
  2336  			t |= STT_FUNC
  2337  		} else if ctxt.Arch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type == sym.STEXT {
  2338  			t |= STT_FUNC
  2339  		} else {
  2340  			t |= STT_OBJECT
  2341  		}
  2342  		d.AddUint8(uint8(t))
  2343  		d.AddUint8(0)
  2344  
  2345  		/* shndx */
  2346  		if s.Type == sym.SDYNIMPORT {
  2347  			d.AddUint16(ctxt.Arch, SHN_UNDEF)
  2348  		} else {
  2349  			d.AddUint16(ctxt.Arch, 1)
  2350  		}
  2351  	}
  2352  }
  2353  
  2354  func ELF32_R_SYM(info uint32) uint32 {
  2355  	return info >> 8
  2356  }
  2357  
  2358  func ELF32_R_TYPE(info uint32) uint32 {
  2359  	return uint32(uint8(info))
  2360  }
  2361  
  2362  func ELF32_R_INFO(sym uint32, type_ uint32) uint32 {
  2363  	return sym<<8 | type_
  2364  }
  2365  
  2366  func ELF32_ST_BIND(info uint8) uint8 {
  2367  	return info >> 4
  2368  }
  2369  
  2370  func ELF32_ST_TYPE(info uint8) uint8 {
  2371  	return info & 0xf
  2372  }
  2373  
  2374  func ELF32_ST_INFO(bind uint8, type_ uint8) uint8 {
  2375  	return bind<<4 | type_&0xf
  2376  }
  2377  
  2378  func ELF32_ST_VISIBILITY(oth uint8) uint8 {
  2379  	return oth & 3
  2380  }
  2381  
  2382  func ELF64_R_SYM(info uint64) uint32 {
  2383  	return uint32(info >> 32)
  2384  }
  2385  
  2386  func ELF64_R_TYPE(info uint64) uint32 {
  2387  	return uint32(info)
  2388  }
  2389  
  2390  func ELF64_R_INFO(sym uint32, type_ uint32) uint64 {
  2391  	return uint64(sym)<<32 | uint64(type_)
  2392  }
  2393  
  2394  func ELF64_ST_BIND(info uint8) uint8 {
  2395  	return info >> 4
  2396  }
  2397  
  2398  func ELF64_ST_TYPE(info uint8) uint8 {
  2399  	return info & 0xf
  2400  }
  2401  
  2402  func ELF64_ST_INFO(bind uint8, type_ uint8) uint8 {
  2403  	return bind<<4 | type_&0xf
  2404  }
  2405  
  2406  func ELF64_ST_VISIBILITY(oth uint8) uint8 {
  2407  	return oth & 3
  2408  }