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