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