github.com/mattn/go@v0.0.0-20171011075504-07f7db3ea99f/src/cmd/link/internal/ld/elf.go (about)

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