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