github.com/riscv/riscv-go@v0.0.0-20200123204226-124ebd6fcc8e/src/cmd/link/internal/ld/elf.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ld
     6  
     7  import (
     8  	"cmd/internal/obj"
     9  	"cmd/internal/sys"
    10  	"crypto/sha1"
    11  	"encoding/binary"
    12  	"encoding/hex"
    13  	"io"
    14  	"path/filepath"
    15  	"sort"
    16  	"strings"
    17  )
    18  
    19  /*
    20   * Derived from:
    21   * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $
    22   * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $
    23   * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $
    24   * $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $
    25   * $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $
    26   * $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $
    27   * $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $
    28   * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $
    29   * $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $
    30   *
    31   * Copyright (c) 1996-1998 John D. Polstra.  All rights reserved.
    32   * Copyright (c) 2001 David E. O'Brien
    33   * Portions Copyright 2009 The Go Authors. All rights reserved.
    34   *
    35   * Redistribution and use in source and binary forms, with or without
    36   * modification, are permitted provided that the following conditions
    37   * are met:
    38   * 1. Redistributions of source code must retain the above copyright
    39   *    notice, this list of conditions and the following disclaimer.
    40   * 2. Redistributions in binary form must reproduce the above copyright
    41   *    notice, this list of conditions and the following disclaimer in the
    42   *    documentation and/or other materials provided with the distribution.
    43   *
    44   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
    45   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    46   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    47   * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
    48   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    49   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    50   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    51   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    52   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    53   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    54   * SUCH DAMAGE.
    55   *
    56   */
    57  
    58  /*
    59   * ELF definitions that are independent of architecture or word size.
    60   */
    61  
    62  /*
    63   * Note header.  The ".note" section contains an array of notes.  Each
    64   * begins with this header, aligned to a word boundary.  Immediately
    65   * following the note header is n_namesz bytes of name, padded to the
    66   * next word boundary.  Then comes n_descsz bytes of descriptor, again
    67   * padded to a word boundary.  The values of n_namesz and n_descsz do
    68   * not include the padding.
    69   */
    70  type elfNote struct {
    71  	nNamesz uint32
    72  	nDescsz uint32
    73  	nType   uint32
    74  }
    75  
    76  const (
    77  	EI_MAG0              = 0
    78  	EI_MAG1              = 1
    79  	EI_MAG2              = 2
    80  	EI_MAG3              = 3
    81  	EI_CLASS             = 4
    82  	EI_DATA              = 5
    83  	EI_VERSION           = 6
    84  	EI_OSABI             = 7
    85  	EI_ABIVERSION        = 8
    86  	OLD_EI_BRAND         = 8
    87  	EI_PAD               = 9
    88  	EI_NIDENT            = 16
    89  	ELFMAG0              = 0x7f
    90  	ELFMAG1              = 'E'
    91  	ELFMAG2              = 'L'
    92  	ELFMAG3              = 'F'
    93  	SELFMAG              = 4
    94  	EV_NONE              = 0
    95  	EV_CURRENT           = 1
    96  	ELFCLASSNONE         = 0
    97  	ELFCLASS32           = 1
    98  	ELFCLASS64           = 2
    99  	ELFDATANONE          = 0
   100  	ELFDATA2LSB          = 1
   101  	ELFDATA2MSB          = 2
   102  	ELFOSABI_NONE        = 0
   103  	ELFOSABI_HPUX        = 1
   104  	ELFOSABI_NETBSD      = 2
   105  	ELFOSABI_LINUX       = 3
   106  	ELFOSABI_HURD        = 4
   107  	ELFOSABI_86OPEN      = 5
   108  	ELFOSABI_SOLARIS     = 6
   109  	ELFOSABI_AIX         = 7
   110  	ELFOSABI_IRIX        = 8
   111  	ELFOSABI_FREEBSD     = 9
   112  	ELFOSABI_TRU64       = 10
   113  	ELFOSABI_MODESTO     = 11
   114  	ELFOSABI_OPENBSD     = 12
   115  	ELFOSABI_OPENVMS     = 13
   116  	ELFOSABI_NSK         = 14
   117  	ELFOSABI_ARM         = 97
   118  	ELFOSABI_STANDALONE  = 255
   119  	ELFOSABI_SYSV        = ELFOSABI_NONE
   120  	ELFOSABI_MONTEREY    = ELFOSABI_AIX
   121  	ET_NONE              = 0
   122  	ET_REL               = 1
   123  	ET_EXEC              = 2
   124  	ET_DYN               = 3
   125  	ET_CORE              = 4
   126  	ET_LOOS              = 0xfe00
   127  	ET_HIOS              = 0xfeff
   128  	ET_LOPROC            = 0xff00
   129  	ET_HIPROC            = 0xffff
   130  	EM_NONE              = 0
   131  	EM_M32               = 1
   132  	EM_SPARC             = 2
   133  	EM_386               = 3
   134  	EM_68K               = 4
   135  	EM_88K               = 5
   136  	EM_860               = 7
   137  	EM_MIPS              = 8
   138  	EM_S370              = 9
   139  	EM_MIPS_RS3_LE       = 10
   140  	EM_PARISC            = 15
   141  	EM_VPP500            = 17
   142  	EM_SPARC32PLUS       = 18
   143  	EM_960               = 19
   144  	EM_PPC               = 20
   145  	EM_PPC64             = 21
   146  	EM_S390              = 22
   147  	EM_V800              = 36
   148  	EM_FR20              = 37
   149  	EM_RH32              = 38
   150  	EM_RCE               = 39
   151  	EM_ARM               = 40
   152  	EM_SH                = 42
   153  	EM_SPARCV9           = 43
   154  	EM_TRICORE           = 44
   155  	EM_ARC               = 45
   156  	EM_H8_300            = 46
   157  	EM_H8_300H           = 47
   158  	EM_H8S               = 48
   159  	EM_H8_500            = 49
   160  	EM_IA_64             = 50
   161  	EM_MIPS_X            = 51
   162  	EM_COLDFIRE          = 52
   163  	EM_68HC12            = 53
   164  	EM_MMA               = 54
   165  	EM_PCP               = 55
   166  	EM_NCPU              = 56
   167  	EM_NDR1              = 57
   168  	EM_STARCORE          = 58
   169  	EM_ME16              = 59
   170  	EM_ST100             = 60
   171  	EM_TINYJ             = 61
   172  	EM_X86_64            = 62
   173  	EM_AARCH64           = 183
   174  	EM_486               = 6
   175  	EM_MIPS_RS4_BE       = 10
   176  	EM_ALPHA_STD         = 41
   177  	EM_ALPHA             = 0x9026
   178  	EM_RISCV             = 243
   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  	secsym    *Symbol
   814  }
   815  
   816  /*
   817   * Program header.
   818   */
   819  type ElfPhdr struct {
   820  	type_  uint32
   821  	flags  uint32
   822  	off    uint64
   823  	vaddr  uint64
   824  	paddr  uint64
   825  	filesz uint64
   826  	memsz  uint64
   827  	align  uint64
   828  }
   829  
   830  /* For accessing the fields of r_info. */
   831  
   832  /* For constructing r_info from field values. */
   833  
   834  /*
   835   * Symbol table entries.
   836   */
   837  
   838  /* For accessing the fields of st_info. */
   839  
   840  /* For constructing st_info from field values. */
   841  
   842  /* For accessing the fields of st_other. */
   843  
   844  /*
   845   * Go linker interface
   846   */
   847  const (
   848  	ELF64HDRSIZE  = 64
   849  	ELF64PHDRSIZE = 56
   850  	ELF64SHDRSIZE = 64
   851  	ELF64RELSIZE  = 16
   852  	ELF64RELASIZE = 24
   853  	ELF64SYMSIZE  = 24
   854  	ELF32HDRSIZE  = 52
   855  	ELF32PHDRSIZE = 32
   856  	ELF32SHDRSIZE = 40
   857  	ELF32SYMSIZE  = 16
   858  	ELF32RELSIZE  = 8
   859  )
   860  
   861  /*
   862   * The interface uses the 64-bit structures always,
   863   * to avoid code duplication.  The writers know how to
   864   * marshal a 32-bit representation from the 64-bit structure.
   865   */
   866  
   867  var Elfstrdat []byte
   868  
   869  /*
   870   * Total amount of space to reserve at the start of the file
   871   * for Header, PHeaders, SHeaders, and interp.
   872   * May waste some.
   873   * On FreeBSD, cannot be larger than a page.
   874   */
   875  const (
   876  	ELFRESERVE = 4096
   877  )
   878  
   879  /*
   880   * We use the 64-bit data structures on both 32- and 64-bit machines
   881   * in order to write the code just once.  The 64-bit data structure is
   882   * written in the 32-bit format on the 32-bit machines.
   883   */
   884  const (
   885  	NSECT = 400
   886  )
   887  
   888  var (
   889  	Iself bool
   890  
   891  	Nelfsym int = 1
   892  
   893  	elf64 bool
   894  	// Either ".rel" or ".rela" depending on which type of relocation the
   895  	// target platform uses.
   896  	elfRelType string
   897  
   898  	ehdr ElfEhdr
   899  	phdr [NSECT]*ElfPhdr
   900  	shdr [NSECT]*ElfShdr
   901  
   902  	interp string
   903  )
   904  
   905  type Elfstring struct {
   906  	s   string
   907  	off int
   908  }
   909  
   910  var elfstr [100]Elfstring
   911  
   912  var nelfstr int
   913  
   914  var buildinfo []byte
   915  
   916  /*
   917   Initialize the global variable that describes the ELF header. It will be updated as
   918   we write section and prog headers.
   919  */
   920  func Elfinit(ctxt *Link) {
   921  	Iself = true
   922  
   923  	if SysArch.InFamily(sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.RISCV, sys.S390X) {
   924  		elfRelType = ".rela"
   925  	} else {
   926  		elfRelType = ".rel"
   927  	}
   928  
   929  	switch SysArch.Family {
   930  	// 64-bit architectures
   931  	case sys.PPC64, sys.S390X:
   932  		if ctxt.Arch.ByteOrder == binary.BigEndian {
   933  			ehdr.flags = 1 /* Version 1 ABI */
   934  		} else {
   935  			ehdr.flags = 2 /* Version 2 ABI */
   936  		}
   937  		fallthrough
   938  	case sys.AMD64, sys.ARM64, sys.MIPS64, sys.RISCV:
   939  		if SysArch.Family == sys.MIPS64 {
   940  			ehdr.flags = 0x20000000 /* MIPS 3 */
   941  		}
   942  		elf64 = true
   943  
   944  		ehdr.phoff = ELF64HDRSIZE      /* Must be be ELF64HDRSIZE: first PHdr must follow ELF header */
   945  		ehdr.shoff = ELF64HDRSIZE      /* Will move as we add PHeaders */
   946  		ehdr.ehsize = ELF64HDRSIZE     /* Must be ELF64HDRSIZE */
   947  		ehdr.phentsize = ELF64PHDRSIZE /* Must be ELF64PHDRSIZE */
   948  		ehdr.shentsize = ELF64SHDRSIZE /* Must be ELF64SHDRSIZE */
   949  
   950  	// 32-bit architectures
   951  	case sys.ARM, sys.MIPS:
   952  		if SysArch.Family == sys.ARM {
   953  			// we use EABI on linux/arm, freebsd/arm, netbsd/arm.
   954  			if Headtype == obj.Hlinux || Headtype == obj.Hfreebsd || Headtype == obj.Hnetbsd {
   955  				// We set a value here that makes no indication of which
   956  				// float ABI the object uses, because this is information
   957  				// used by the dynamic linker to compare executables and
   958  				// shared libraries -- so it only matters for cgo calls, and
   959  				// the information properly comes from the object files
   960  				// produced by the host C compiler. parseArmAttributes in
   961  				// ldelf.go reads that information and updates this field as
   962  				// appropriate.
   963  				ehdr.flags = 0x5000002 // has entry point, Version5 EABI
   964  			}
   965  		} else if SysArch.Family == sys.MIPS {
   966  			ehdr.flags = 0x50001004 /* MIPS 32 CPIC O32*/
   967  		}
   968  		fallthrough
   969  	default:
   970  		ehdr.phoff = ELF32HDRSIZE
   971  		/* Must be be ELF32HDRSIZE: first PHdr must follow ELF header */
   972  		ehdr.shoff = ELF32HDRSIZE      /* Will move as we add PHeaders */
   973  		ehdr.ehsize = ELF32HDRSIZE     /* Must be ELF32HDRSIZE */
   974  		ehdr.phentsize = ELF32PHDRSIZE /* Must be ELF32PHDRSIZE */
   975  		ehdr.shentsize = ELF32SHDRSIZE /* Must be ELF32SHDRSIZE */
   976  	}
   977  }
   978  
   979  // Make sure PT_LOAD is aligned properly and
   980  // that there is no gap,
   981  // correct ELF loaders will do this implicitly,
   982  // but buggy ELF loaders like the one in some
   983  // versions of QEMU and UPX won't.
   984  func fixElfPhdr(e *ElfPhdr) {
   985  	frag := int(e.vaddr & (e.align - 1))
   986  
   987  	e.off -= uint64(frag)
   988  	e.vaddr -= uint64(frag)
   989  	e.paddr -= uint64(frag)
   990  	e.filesz += uint64(frag)
   991  	e.memsz += uint64(frag)
   992  }
   993  
   994  func elf64phdr(e *ElfPhdr) {
   995  	if e.type_ == PT_LOAD {
   996  		fixElfPhdr(e)
   997  	}
   998  
   999  	Thearch.Lput(e.type_)
  1000  	Thearch.Lput(e.flags)
  1001  	Thearch.Vput(e.off)
  1002  	Thearch.Vput(e.vaddr)
  1003  	Thearch.Vput(e.paddr)
  1004  	Thearch.Vput(e.filesz)
  1005  	Thearch.Vput(e.memsz)
  1006  	Thearch.Vput(e.align)
  1007  }
  1008  
  1009  func elf32phdr(e *ElfPhdr) {
  1010  	if e.type_ == PT_LOAD {
  1011  		fixElfPhdr(e)
  1012  	}
  1013  
  1014  	Thearch.Lput(e.type_)
  1015  	Thearch.Lput(uint32(e.off))
  1016  	Thearch.Lput(uint32(e.vaddr))
  1017  	Thearch.Lput(uint32(e.paddr))
  1018  	Thearch.Lput(uint32(e.filesz))
  1019  	Thearch.Lput(uint32(e.memsz))
  1020  	Thearch.Lput(e.flags)
  1021  	Thearch.Lput(uint32(e.align))
  1022  }
  1023  
  1024  func elf64shdr(e *ElfShdr) {
  1025  	Thearch.Lput(e.name)
  1026  	Thearch.Lput(e.type_)
  1027  	Thearch.Vput(e.flags)
  1028  	Thearch.Vput(e.addr)
  1029  	Thearch.Vput(e.off)
  1030  	Thearch.Vput(e.size)
  1031  	Thearch.Lput(e.link)
  1032  	Thearch.Lput(e.info)
  1033  	Thearch.Vput(e.addralign)
  1034  	Thearch.Vput(e.entsize)
  1035  }
  1036  
  1037  func elf32shdr(e *ElfShdr) {
  1038  	Thearch.Lput(e.name)
  1039  	Thearch.Lput(e.type_)
  1040  	Thearch.Lput(uint32(e.flags))
  1041  	Thearch.Lput(uint32(e.addr))
  1042  	Thearch.Lput(uint32(e.off))
  1043  	Thearch.Lput(uint32(e.size))
  1044  	Thearch.Lput(e.link)
  1045  	Thearch.Lput(e.info)
  1046  	Thearch.Lput(uint32(e.addralign))
  1047  	Thearch.Lput(uint32(e.entsize))
  1048  }
  1049  
  1050  func elfwriteshdrs() uint32 {
  1051  	if elf64 {
  1052  		for i := 0; i < int(ehdr.shnum); i++ {
  1053  			elf64shdr(shdr[i])
  1054  		}
  1055  		return uint32(ehdr.shnum) * ELF64SHDRSIZE
  1056  	}
  1057  
  1058  	for i := 0; i < int(ehdr.shnum); i++ {
  1059  		elf32shdr(shdr[i])
  1060  	}
  1061  	return uint32(ehdr.shnum) * ELF32SHDRSIZE
  1062  }
  1063  
  1064  func elfsetstring(s *Symbol, str string, off int) {
  1065  	if nelfstr >= len(elfstr) {
  1066  		Errorf(s, "too many elf strings")
  1067  		errorexit()
  1068  	}
  1069  
  1070  	elfstr[nelfstr].s = str
  1071  	elfstr[nelfstr].off = off
  1072  	nelfstr++
  1073  }
  1074  
  1075  func elfwritephdrs() uint32 {
  1076  	if elf64 {
  1077  		for i := 0; i < int(ehdr.phnum); i++ {
  1078  			elf64phdr(phdr[i])
  1079  		}
  1080  		return uint32(ehdr.phnum) * ELF64PHDRSIZE
  1081  	}
  1082  
  1083  	for i := 0; i < int(ehdr.phnum); i++ {
  1084  		elf32phdr(phdr[i])
  1085  	}
  1086  	return uint32(ehdr.phnum) * ELF32PHDRSIZE
  1087  }
  1088  
  1089  func newElfPhdr() *ElfPhdr {
  1090  	e := new(ElfPhdr)
  1091  	if ehdr.phnum >= NSECT {
  1092  		Errorf(nil, "too many phdrs")
  1093  	} else {
  1094  		phdr[ehdr.phnum] = e
  1095  		ehdr.phnum++
  1096  	}
  1097  	if elf64 {
  1098  		ehdr.shoff += ELF64PHDRSIZE
  1099  	} else {
  1100  		ehdr.shoff += ELF32PHDRSIZE
  1101  	}
  1102  	return e
  1103  }
  1104  
  1105  func newElfShdr(name int64) *ElfShdr {
  1106  	e := new(ElfShdr)
  1107  	e.name = uint32(name)
  1108  	e.shnum = int(ehdr.shnum)
  1109  	if ehdr.shnum >= NSECT {
  1110  		Errorf(nil, "too many shdrs")
  1111  	} else {
  1112  		shdr[ehdr.shnum] = e
  1113  		ehdr.shnum++
  1114  	}
  1115  
  1116  	return e
  1117  }
  1118  
  1119  func getElfEhdr() *ElfEhdr {
  1120  	return &ehdr
  1121  }
  1122  
  1123  func elf64writehdr() uint32 {
  1124  	for i := 0; i < EI_NIDENT; i++ {
  1125  		Cput(ehdr.ident[i])
  1126  	}
  1127  	Thearch.Wput(ehdr.type_)
  1128  	Thearch.Wput(ehdr.machine)
  1129  	Thearch.Lput(ehdr.version)
  1130  	Thearch.Vput(ehdr.entry)
  1131  	Thearch.Vput(ehdr.phoff)
  1132  	Thearch.Vput(ehdr.shoff)
  1133  	Thearch.Lput(ehdr.flags)
  1134  	Thearch.Wput(ehdr.ehsize)
  1135  	Thearch.Wput(ehdr.phentsize)
  1136  	Thearch.Wput(ehdr.phnum)
  1137  	Thearch.Wput(ehdr.shentsize)
  1138  	Thearch.Wput(ehdr.shnum)
  1139  	Thearch.Wput(ehdr.shstrndx)
  1140  	return ELF64HDRSIZE
  1141  }
  1142  
  1143  func elf32writehdr() uint32 {
  1144  	for i := 0; i < EI_NIDENT; i++ {
  1145  		Cput(ehdr.ident[i])
  1146  	}
  1147  	Thearch.Wput(ehdr.type_)
  1148  	Thearch.Wput(ehdr.machine)
  1149  	Thearch.Lput(ehdr.version)
  1150  	Thearch.Lput(uint32(ehdr.entry))
  1151  	Thearch.Lput(uint32(ehdr.phoff))
  1152  	Thearch.Lput(uint32(ehdr.shoff))
  1153  	Thearch.Lput(ehdr.flags)
  1154  	Thearch.Wput(ehdr.ehsize)
  1155  	Thearch.Wput(ehdr.phentsize)
  1156  	Thearch.Wput(ehdr.phnum)
  1157  	Thearch.Wput(ehdr.shentsize)
  1158  	Thearch.Wput(ehdr.shnum)
  1159  	Thearch.Wput(ehdr.shstrndx)
  1160  	return ELF32HDRSIZE
  1161  }
  1162  
  1163  func elfwritehdr() uint32 {
  1164  	if elf64 {
  1165  		return elf64writehdr()
  1166  	}
  1167  	return elf32writehdr()
  1168  }
  1169  
  1170  /* Taken directly from the definition document for ELF64 */
  1171  func elfhash(name string) uint32 {
  1172  	var h uint32
  1173  	for i := 0; i < len(name); i++ {
  1174  		h = (h << 4) + uint32(name[i])
  1175  		if g := h & 0xf0000000; g != 0 {
  1176  			h ^= g >> 24
  1177  		}
  1178  		h &= 0x0fffffff
  1179  	}
  1180  	return h
  1181  }
  1182  
  1183  func Elfwritedynent(ctxt *Link, s *Symbol, tag int, val uint64) {
  1184  	if elf64 {
  1185  		Adduint64(ctxt, s, uint64(tag))
  1186  		Adduint64(ctxt, s, val)
  1187  	} else {
  1188  		Adduint32(ctxt, s, uint32(tag))
  1189  		Adduint32(ctxt, s, uint32(val))
  1190  	}
  1191  }
  1192  
  1193  func elfwritedynentsym(ctxt *Link, s *Symbol, tag int, t *Symbol) {
  1194  	Elfwritedynentsymplus(ctxt, s, tag, t, 0)
  1195  }
  1196  
  1197  func Elfwritedynentsymplus(ctxt *Link, s *Symbol, tag int, t *Symbol, add int64) {
  1198  	if elf64 {
  1199  		Adduint64(ctxt, s, uint64(tag))
  1200  	} else {
  1201  		Adduint32(ctxt, s, uint32(tag))
  1202  	}
  1203  	Addaddrplus(ctxt, s, t, add)
  1204  }
  1205  
  1206  func elfwritedynentsymsize(ctxt *Link, s *Symbol, tag int, t *Symbol) {
  1207  	if elf64 {
  1208  		Adduint64(ctxt, s, uint64(tag))
  1209  	} else {
  1210  		Adduint32(ctxt, s, uint32(tag))
  1211  	}
  1212  	addsize(ctxt, s, t)
  1213  }
  1214  
  1215  func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int {
  1216  	interp = p
  1217  	n := len(interp) + 1
  1218  	sh.addr = startva + resoff - uint64(n)
  1219  	sh.off = resoff - uint64(n)
  1220  	sh.size = uint64(n)
  1221  
  1222  	return n
  1223  }
  1224  
  1225  func elfwriteinterp() int {
  1226  	sh := elfshname(".interp")
  1227  	Cseek(int64(sh.off))
  1228  	coutbuf.WriteString(interp)
  1229  	Cput(0)
  1230  	return int(sh.size)
  1231  }
  1232  
  1233  func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int, alloc bool) int {
  1234  	n := 3*4 + uint64(sz) + resoff%4
  1235  
  1236  	sh.type_ = SHT_NOTE
  1237  	if alloc {
  1238  		sh.flags = SHF_ALLOC
  1239  	}
  1240  	sh.addralign = 4
  1241  	sh.addr = startva + resoff - n
  1242  	sh.off = resoff - n
  1243  	sh.size = n - resoff%4
  1244  
  1245  	return int(n)
  1246  }
  1247  
  1248  func elfwritenotehdr(str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr {
  1249  	sh := elfshname(str)
  1250  
  1251  	// Write Elf_Note header.
  1252  	Cseek(int64(sh.off))
  1253  
  1254  	Thearch.Lput(namesz)
  1255  	Thearch.Lput(descsz)
  1256  	Thearch.Lput(tag)
  1257  
  1258  	return sh
  1259  }
  1260  
  1261  // NetBSD Signature (as per sys/exec_elf.h)
  1262  const (
  1263  	ELF_NOTE_NETBSD_NAMESZ  = 7
  1264  	ELF_NOTE_NETBSD_DESCSZ  = 4
  1265  	ELF_NOTE_NETBSD_TAG     = 1
  1266  	ELF_NOTE_NETBSD_VERSION = 599000000 /* NetBSD 5.99 */
  1267  )
  1268  
  1269  var ELF_NOTE_NETBSD_NAME = []byte("NetBSD\x00")
  1270  
  1271  func elfnetbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
  1272  	n := int(Rnd(ELF_NOTE_NETBSD_NAMESZ, 4) + Rnd(ELF_NOTE_NETBSD_DESCSZ, 4))
  1273  	return elfnote(sh, startva, resoff, n, true)
  1274  }
  1275  
  1276  func elfwritenetbsdsig() int {
  1277  	// Write Elf_Note header.
  1278  	sh := elfwritenotehdr(".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG)
  1279  
  1280  	if sh == nil {
  1281  		return 0
  1282  	}
  1283  
  1284  	// Followed by NetBSD string and version.
  1285  	Cwrite(ELF_NOTE_NETBSD_NAME)
  1286  	Cput(0)
  1287  
  1288  	Thearch.Lput(ELF_NOTE_NETBSD_VERSION)
  1289  
  1290  	return int(sh.size)
  1291  }
  1292  
  1293  // OpenBSD Signature
  1294  const (
  1295  	ELF_NOTE_OPENBSD_NAMESZ  = 8
  1296  	ELF_NOTE_OPENBSD_DESCSZ  = 4
  1297  	ELF_NOTE_OPENBSD_TAG     = 1
  1298  	ELF_NOTE_OPENBSD_VERSION = 0
  1299  )
  1300  
  1301  var ELF_NOTE_OPENBSD_NAME = []byte("OpenBSD\x00")
  1302  
  1303  func elfopenbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
  1304  	n := ELF_NOTE_OPENBSD_NAMESZ + ELF_NOTE_OPENBSD_DESCSZ
  1305  	return elfnote(sh, startva, resoff, n, true)
  1306  }
  1307  
  1308  func elfwriteopenbsdsig() int {
  1309  	// Write Elf_Note header.
  1310  	sh := elfwritenotehdr(".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG)
  1311  
  1312  	if sh == nil {
  1313  		return 0
  1314  	}
  1315  
  1316  	// Followed by OpenBSD string and version.
  1317  	Cwrite(ELF_NOTE_OPENBSD_NAME)
  1318  
  1319  	Thearch.Lput(ELF_NOTE_OPENBSD_VERSION)
  1320  
  1321  	return int(sh.size)
  1322  }
  1323  
  1324  func addbuildinfo(val string) {
  1325  	if !strings.HasPrefix(val, "0x") {
  1326  		Exitf("-B argument must start with 0x: %s", val)
  1327  	}
  1328  
  1329  	ov := val
  1330  	val = val[2:]
  1331  
  1332  	const maxLen = 32
  1333  	if hex.DecodedLen(len(val)) > maxLen {
  1334  		Exitf("-B option too long (max %d digits): %s", maxLen, ov)
  1335  	}
  1336  
  1337  	b, err := hex.DecodeString(val)
  1338  	if err != nil {
  1339  		if err == hex.ErrLength {
  1340  			Exitf("-B argument must have even number of digits: %s", ov)
  1341  		}
  1342  		if inv, ok := err.(hex.InvalidByteError); ok {
  1343  			Exitf("-B argument contains invalid hex digit %c: %s", byte(inv), ov)
  1344  		}
  1345  		Exitf("-B argument contains invalid hex: %s", ov)
  1346  	}
  1347  
  1348  	buildinfo = b
  1349  }
  1350  
  1351  // Build info note
  1352  const (
  1353  	ELF_NOTE_BUILDINFO_NAMESZ = 4
  1354  	ELF_NOTE_BUILDINFO_TAG    = 3
  1355  )
  1356  
  1357  var ELF_NOTE_BUILDINFO_NAME = []byte("GNU\x00")
  1358  
  1359  func elfbuildinfo(sh *ElfShdr, startva uint64, resoff uint64) int {
  1360  	n := int(ELF_NOTE_BUILDINFO_NAMESZ + Rnd(int64(len(buildinfo)), 4))
  1361  	return elfnote(sh, startva, resoff, n, true)
  1362  }
  1363  
  1364  func elfgobuildid(sh *ElfShdr, startva uint64, resoff uint64) int {
  1365  	n := len(ELF_NOTE_GO_NAME) + int(Rnd(int64(len(*flagBuildid)), 4))
  1366  	return elfnote(sh, startva, resoff, n, true)
  1367  }
  1368  
  1369  func elfwritebuildinfo() int {
  1370  	sh := elfwritenotehdr(".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG)
  1371  	if sh == nil {
  1372  		return 0
  1373  	}
  1374  
  1375  	Cwrite(ELF_NOTE_BUILDINFO_NAME)
  1376  	Cwrite(buildinfo)
  1377  	var zero = make([]byte, 4)
  1378  	Cwrite(zero[:int(Rnd(int64(len(buildinfo)), 4)-int64(len(buildinfo)))])
  1379  
  1380  	return int(sh.size)
  1381  }
  1382  
  1383  func elfwritegobuildid() int {
  1384  	sh := elfwritenotehdr(".note.go.buildid", uint32(len(ELF_NOTE_GO_NAME)), uint32(len(*flagBuildid)), ELF_NOTE_GOBUILDID_TAG)
  1385  	if sh == nil {
  1386  		return 0
  1387  	}
  1388  
  1389  	Cwrite(ELF_NOTE_GO_NAME)
  1390  	Cwrite([]byte(*flagBuildid))
  1391  	var zero = make([]byte, 4)
  1392  	Cwrite(zero[:int(Rnd(int64(len(*flagBuildid)), 4)-int64(len(*flagBuildid)))])
  1393  
  1394  	return int(sh.size)
  1395  }
  1396  
  1397  // Go specific notes
  1398  const (
  1399  	ELF_NOTE_GOPKGLIST_TAG = 1
  1400  	ELF_NOTE_GOABIHASH_TAG = 2
  1401  	ELF_NOTE_GODEPS_TAG    = 3
  1402  	ELF_NOTE_GOBUILDID_TAG = 4
  1403  )
  1404  
  1405  var ELF_NOTE_GO_NAME = []byte("Go\x00\x00")
  1406  
  1407  var elfverneed int
  1408  
  1409  type Elfaux struct {
  1410  	next *Elfaux
  1411  	num  int
  1412  	vers string
  1413  }
  1414  
  1415  type Elflib struct {
  1416  	next *Elflib
  1417  	aux  *Elfaux
  1418  	file string
  1419  }
  1420  
  1421  func addelflib(list **Elflib, file string, vers string) *Elfaux {
  1422  	var lib *Elflib
  1423  
  1424  	for lib = *list; lib != nil; lib = lib.next {
  1425  		if lib.file == file {
  1426  			goto havelib
  1427  		}
  1428  	}
  1429  	lib = new(Elflib)
  1430  	lib.next = *list
  1431  	lib.file = file
  1432  	*list = lib
  1433  
  1434  havelib:
  1435  	for aux := lib.aux; aux != nil; aux = aux.next {
  1436  		if aux.vers == vers {
  1437  			return aux
  1438  		}
  1439  	}
  1440  	aux := new(Elfaux)
  1441  	aux.next = lib.aux
  1442  	aux.vers = vers
  1443  	lib.aux = aux
  1444  
  1445  	return aux
  1446  }
  1447  
  1448  func elfdynhash(ctxt *Link) {
  1449  	if !Iself {
  1450  		return
  1451  	}
  1452  
  1453  	nsym := Nelfsym
  1454  	s := ctxt.Syms.Lookup(".hash", 0)
  1455  	s.Type = obj.SELFROSECT
  1456  	s.Attr |= AttrReachable
  1457  
  1458  	i := nsym
  1459  	nbucket := 1
  1460  	for i > 0 {
  1461  		nbucket++
  1462  		i >>= 1
  1463  	}
  1464  
  1465  	var needlib *Elflib
  1466  	need := make([]*Elfaux, nsym)
  1467  	chain := make([]uint32, nsym)
  1468  	buckets := make([]uint32, nbucket)
  1469  
  1470  	var b int
  1471  	for _, sy := range ctxt.Syms.Allsym {
  1472  		if sy.Dynid <= 0 {
  1473  			continue
  1474  		}
  1475  
  1476  		if sy.Dynimpvers != "" {
  1477  			need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib, sy.Dynimpvers)
  1478  		}
  1479  
  1480  		name := sy.Extname
  1481  		hc := elfhash(name)
  1482  
  1483  		b = int(hc % uint32(nbucket))
  1484  		chain[sy.Dynid] = buckets[b]
  1485  		buckets[b] = uint32(sy.Dynid)
  1486  	}
  1487  
  1488  	// s390x (ELF64) hash table entries are 8 bytes
  1489  	if SysArch.Family == sys.S390X {
  1490  		Adduint64(ctxt, s, uint64(nbucket))
  1491  		Adduint64(ctxt, s, uint64(nsym))
  1492  		for i := 0; i < nbucket; i++ {
  1493  			Adduint64(ctxt, s, uint64(buckets[i]))
  1494  		}
  1495  		for i := 0; i < nsym; i++ {
  1496  			Adduint64(ctxt, s, uint64(chain[i]))
  1497  		}
  1498  	} else {
  1499  		Adduint32(ctxt, s, uint32(nbucket))
  1500  		Adduint32(ctxt, s, uint32(nsym))
  1501  		for i := 0; i < nbucket; i++ {
  1502  			Adduint32(ctxt, s, buckets[i])
  1503  		}
  1504  		for i := 0; i < nsym; i++ {
  1505  			Adduint32(ctxt, s, chain[i])
  1506  		}
  1507  	}
  1508  
  1509  	// version symbols
  1510  	dynstr := ctxt.Syms.Lookup(".dynstr", 0)
  1511  
  1512  	s = ctxt.Syms.Lookup(".gnu.version_r", 0)
  1513  	i = 2
  1514  	nfile := 0
  1515  	var j int
  1516  	var x *Elfaux
  1517  	for l := needlib; l != nil; l = l.next {
  1518  		nfile++
  1519  
  1520  		// header
  1521  		Adduint16(ctxt, s, 1) // table version
  1522  		j = 0
  1523  		for x = l.aux; x != nil; x = x.next {
  1524  			j++
  1525  		}
  1526  		Adduint16(ctxt, s, uint16(j))                         // aux count
  1527  		Adduint32(ctxt, s, uint32(Addstring(dynstr, l.file))) // file string offset
  1528  		Adduint32(ctxt, s, 16)                                // offset from header to first aux
  1529  		if l.next != nil {
  1530  			Adduint32(ctxt, s, 16+uint32(j)*16) // offset from this header to next
  1531  		} else {
  1532  			Adduint32(ctxt, s, 0)
  1533  		}
  1534  
  1535  		for x = l.aux; x != nil; x = x.next {
  1536  			x.num = i
  1537  			i++
  1538  
  1539  			// aux struct
  1540  			Adduint32(ctxt, s, elfhash(x.vers))                   // hash
  1541  			Adduint16(ctxt, s, 0)                                 // flags
  1542  			Adduint16(ctxt, s, uint16(x.num))                     // other - index we refer to this by
  1543  			Adduint32(ctxt, s, uint32(Addstring(dynstr, x.vers))) // version string offset
  1544  			if x.next != nil {
  1545  				Adduint32(ctxt, s, 16) // offset from this aux to next
  1546  			} else {
  1547  				Adduint32(ctxt, s, 0)
  1548  			}
  1549  		}
  1550  	}
  1551  
  1552  	// version references
  1553  	s = ctxt.Syms.Lookup(".gnu.version", 0)
  1554  
  1555  	for i := 0; i < nsym; i++ {
  1556  		if i == 0 {
  1557  			Adduint16(ctxt, s, 0) // first entry - no symbol
  1558  		} else if need[i] == nil {
  1559  			Adduint16(ctxt, s, 1) // global
  1560  		} else {
  1561  			Adduint16(ctxt, s, uint16(need[i].num))
  1562  		}
  1563  	}
  1564  
  1565  	s = ctxt.Syms.Lookup(".dynamic", 0)
  1566  	elfverneed = nfile
  1567  	if elfverneed != 0 {
  1568  		elfwritedynentsym(ctxt, s, DT_VERNEED, ctxt.Syms.Lookup(".gnu.version_r", 0))
  1569  		Elfwritedynent(ctxt, s, DT_VERNEEDNUM, uint64(nfile))
  1570  		elfwritedynentsym(ctxt, s, DT_VERSYM, ctxt.Syms.Lookup(".gnu.version", 0))
  1571  	}
  1572  
  1573  	sy := ctxt.Syms.Lookup(elfRelType+".plt", 0)
  1574  	if sy.Size > 0 {
  1575  		if elfRelType == ".rela" {
  1576  			Elfwritedynent(ctxt, s, DT_PLTREL, DT_RELA)
  1577  		} else {
  1578  			Elfwritedynent(ctxt, s, DT_PLTREL, DT_REL)
  1579  		}
  1580  		elfwritedynentsymsize(ctxt, s, DT_PLTRELSZ, sy)
  1581  		elfwritedynentsym(ctxt, s, DT_JMPREL, sy)
  1582  	}
  1583  
  1584  	Elfwritedynent(ctxt, s, DT_NULL, 0)
  1585  }
  1586  
  1587  func elfphload(seg *Segment) *ElfPhdr {
  1588  	ph := newElfPhdr()
  1589  	ph.type_ = PT_LOAD
  1590  	if seg.Rwx&4 != 0 {
  1591  		ph.flags |= PF_R
  1592  	}
  1593  	if seg.Rwx&2 != 0 {
  1594  		ph.flags |= PF_W
  1595  	}
  1596  	if seg.Rwx&1 != 0 {
  1597  		ph.flags |= PF_X
  1598  	}
  1599  	ph.vaddr = seg.Vaddr
  1600  	ph.paddr = seg.Vaddr
  1601  	ph.memsz = seg.Length
  1602  	ph.off = seg.Fileoff
  1603  	ph.filesz = seg.Filelen
  1604  	ph.align = uint64(*FlagRound)
  1605  
  1606  	return ph
  1607  }
  1608  
  1609  func elfphrelro(seg *Segment) {
  1610  	ph := newElfPhdr()
  1611  	ph.type_ = PT_GNU_RELRO
  1612  	ph.vaddr = seg.Vaddr
  1613  	ph.paddr = seg.Vaddr
  1614  	ph.memsz = seg.Length
  1615  	ph.off = seg.Fileoff
  1616  	ph.filesz = seg.Filelen
  1617  	ph.align = uint64(*FlagRound)
  1618  }
  1619  
  1620  func elfshname(name string) *ElfShdr {
  1621  	var off int
  1622  	var sh *ElfShdr
  1623  
  1624  	for i := 0; i < nelfstr; i++ {
  1625  		if name == elfstr[i].s {
  1626  			off = elfstr[i].off
  1627  			for i = 0; i < int(ehdr.shnum); i++ {
  1628  				sh = shdr[i]
  1629  				if sh.name == uint32(off) {
  1630  					return sh
  1631  				}
  1632  			}
  1633  
  1634  			sh = newElfShdr(int64(off))
  1635  			return sh
  1636  		}
  1637  	}
  1638  
  1639  	Exitf("cannot find elf name %s", name)
  1640  	return nil
  1641  }
  1642  
  1643  // Create an ElfShdr for the section with name.
  1644  // Create a duplicate if one already exists with that name
  1645  func elfshnamedup(name string) *ElfShdr {
  1646  	var off int
  1647  	var sh *ElfShdr
  1648  
  1649  	for i := 0; i < nelfstr; i++ {
  1650  		if name == elfstr[i].s {
  1651  			off = elfstr[i].off
  1652  			sh = newElfShdr(int64(off))
  1653  			return sh
  1654  		}
  1655  	}
  1656  
  1657  	Errorf(nil, "cannot find elf name %s", name)
  1658  	errorexit()
  1659  	return nil
  1660  }
  1661  
  1662  func elfshalloc(sect *Section) *ElfShdr {
  1663  	sh := elfshname(sect.Name)
  1664  	sect.Elfsect = sh
  1665  	return sh
  1666  }
  1667  
  1668  func elfshbits(sect *Section) *ElfShdr {
  1669  	var sh *ElfShdr
  1670  
  1671  	if sect.Name == ".text" {
  1672  		if sect.Elfsect == nil {
  1673  			sect.Elfsect = elfshnamedup(sect.Name)
  1674  		}
  1675  		sh = sect.Elfsect
  1676  	} else {
  1677  		sh = elfshalloc(sect)
  1678  	}
  1679  
  1680  	// If this section has already been set up as a note, we assume type_ and
  1681  	// flags are already correct, but the other fields still need filling in.
  1682  	if sh.type_ == SHT_NOTE {
  1683  		if Linkmode != LinkExternal {
  1684  			// TODO(mwhudson): the approach here will work OK when
  1685  			// linking internally for notes that we want to be included
  1686  			// in a loadable segment (e.g. the abihash note) but not for
  1687  			// notes that we do not want to be mapped (e.g. the package
  1688  			// list note). The real fix is probably to define new values
  1689  			// for Symbol.Type corresponding to mapped and unmapped notes
  1690  			// and handle them in dodata().
  1691  			Errorf(nil, "sh.type_ == SHT_NOTE in elfshbits when linking internally")
  1692  		}
  1693  		sh.addralign = uint64(sect.Align)
  1694  		sh.size = sect.Length
  1695  		sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
  1696  		return sh
  1697  	}
  1698  	if sh.type_ > 0 {
  1699  		return sh
  1700  	}
  1701  
  1702  	if sect.Vaddr < sect.Seg.Vaddr+sect.Seg.Filelen {
  1703  		sh.type_ = SHT_PROGBITS
  1704  	} else {
  1705  		sh.type_ = SHT_NOBITS
  1706  	}
  1707  	sh.flags = SHF_ALLOC
  1708  	if sect.Rwx&1 != 0 {
  1709  		sh.flags |= SHF_EXECINSTR
  1710  	}
  1711  	if sect.Rwx&2 != 0 {
  1712  		sh.flags |= SHF_WRITE
  1713  	}
  1714  	if sect.Name == ".tbss" {
  1715  		sh.flags |= SHF_TLS
  1716  		sh.type_ = SHT_NOBITS
  1717  	}
  1718  	if strings.HasPrefix(sect.Name, ".debug") {
  1719  		sh.flags = 0
  1720  	}
  1721  
  1722  	if Linkmode != LinkExternal {
  1723  		sh.addr = sect.Vaddr
  1724  	}
  1725  	sh.addralign = uint64(sect.Align)
  1726  	sh.size = sect.Length
  1727  	if sect.Name != ".tbss" {
  1728  		sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
  1729  	}
  1730  
  1731  	return sh
  1732  }
  1733  
  1734  func elfshreloc(sect *Section) *ElfShdr {
  1735  	// If main section is SHT_NOBITS, nothing to relocate.
  1736  	// Also nothing to relocate in .shstrtab or notes.
  1737  	if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
  1738  		return nil
  1739  	}
  1740  	if sect.Name == ".shstrtab" || sect.Name == ".tbss" {
  1741  		return nil
  1742  	}
  1743  	if sect.Elfsect.type_ == SHT_NOTE {
  1744  		return nil
  1745  	}
  1746  
  1747  	var typ int
  1748  	if elfRelType == ".rela" {
  1749  		typ = SHT_RELA
  1750  	} else {
  1751  		typ = SHT_REL
  1752  	}
  1753  
  1754  	sh := elfshname(elfRelType + sect.Name)
  1755  	// There could be multiple text sections but each needs
  1756  	// its own .rela.text.
  1757  
  1758  	if sect.Name == ".text" {
  1759  		if sh.info != 0 && sh.info != uint32(sect.Elfsect.shnum) {
  1760  			sh = elfshnamedup(elfRelType + sect.Name)
  1761  		}
  1762  	}
  1763  
  1764  	sh.type_ = uint32(typ)
  1765  	sh.entsize = uint64(SysArch.RegSize) * 2
  1766  	if typ == SHT_RELA {
  1767  		sh.entsize += uint64(SysArch.RegSize)
  1768  	}
  1769  	sh.link = uint32(elfshname(".symtab").shnum)
  1770  	sh.info = uint32(sect.Elfsect.shnum)
  1771  	sh.off = sect.Reloff
  1772  	sh.size = sect.Rellen
  1773  	sh.addralign = uint64(SysArch.RegSize)
  1774  	return sh
  1775  }
  1776  
  1777  func elfrelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
  1778  	// If main section is SHT_NOBITS, nothing to relocate.
  1779  	// Also nothing to relocate in .shstrtab.
  1780  	if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
  1781  		return
  1782  	}
  1783  	if sect.Name == ".shstrtab" {
  1784  		return
  1785  	}
  1786  
  1787  	sect.Reloff = uint64(coutbuf.Offset())
  1788  	for i, s := range syms {
  1789  		if !s.Attr.Reachable() {
  1790  			continue
  1791  		}
  1792  		if uint64(s.Value) >= sect.Vaddr {
  1793  			syms = syms[i:]
  1794  			break
  1795  		}
  1796  	}
  1797  
  1798  	eaddr := int32(sect.Vaddr + sect.Length)
  1799  	for _, sym := range syms {
  1800  		if !sym.Attr.Reachable() {
  1801  			continue
  1802  		}
  1803  		if sym.Value >= int64(eaddr) {
  1804  			break
  1805  		}
  1806  		for ri := 0; ri < len(sym.R); ri++ {
  1807  			r := &sym.R[ri]
  1808  			if r.Done != 0 {
  1809  				continue
  1810  			}
  1811  			if r.Xsym == nil {
  1812  				Errorf(sym, "missing xsym in relocation")
  1813  				continue
  1814  			}
  1815  			if r.Xsym.ElfsymForReloc() == 0 {
  1816  				Errorf(sym, "reloc %d to non-elf symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type)
  1817  			}
  1818  			if !r.Xsym.Attr.Reachable() {
  1819  				Errorf(sym, "unreachable reloc %v target %v", r.Type, r.Xsym.Name)
  1820  			}
  1821  			if Thearch.Elfreloc1(ctxt, r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) < 0 {
  1822  				Errorf(sym, "unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
  1823  			}
  1824  		}
  1825  	}
  1826  
  1827  	sect.Rellen = uint64(coutbuf.Offset()) - sect.Reloff
  1828  }
  1829  
  1830  func Elfemitreloc(ctxt *Link) {
  1831  	for coutbuf.Offset()&7 != 0 {
  1832  		Cput(0)
  1833  	}
  1834  
  1835  	for sect := Segtext.Sect; sect != nil; sect = sect.Next {
  1836  		if sect.Name == ".text" {
  1837  			elfrelocsect(ctxt, sect, ctxt.Textp)
  1838  		} else {
  1839  			elfrelocsect(ctxt, sect, datap)
  1840  		}
  1841  	}
  1842  
  1843  	for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
  1844  		elfrelocsect(ctxt, sect, datap)
  1845  	}
  1846  	for sect := Segrelrodata.Sect; sect != nil; sect = sect.Next {
  1847  		elfrelocsect(ctxt, sect, datap)
  1848  	}
  1849  	for sect := Segdata.Sect; sect != nil; sect = sect.Next {
  1850  		elfrelocsect(ctxt, sect, datap)
  1851  	}
  1852  	for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
  1853  		elfrelocsect(ctxt, sect, dwarfp)
  1854  	}
  1855  }
  1856  
  1857  func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) {
  1858  	s := ctxt.Syms.Lookup(sectionName, 0)
  1859  	s.Attr |= AttrReachable
  1860  	s.Type = obj.SELFROSECT
  1861  	// namesz
  1862  	Adduint32(ctxt, s, uint32(len(ELF_NOTE_GO_NAME)))
  1863  	// descsz
  1864  	Adduint32(ctxt, s, uint32(len(desc)))
  1865  	// tag
  1866  	Adduint32(ctxt, s, tag)
  1867  	// name + padding
  1868  	s.P = append(s.P, ELF_NOTE_GO_NAME...)
  1869  	for len(s.P)%4 != 0 {
  1870  		s.P = append(s.P, 0)
  1871  	}
  1872  	// desc + padding
  1873  	s.P = append(s.P, desc...)
  1874  	for len(s.P)%4 != 0 {
  1875  		s.P = append(s.P, 0)
  1876  	}
  1877  	s.Size = int64(len(s.P))
  1878  }
  1879  
  1880  func (ctxt *Link) doelf() {
  1881  	if !Iself {
  1882  		return
  1883  	}
  1884  
  1885  	/* predefine strings we need for section headers */
  1886  	shstrtab := ctxt.Syms.Lookup(".shstrtab", 0)
  1887  
  1888  	shstrtab.Type = obj.SELFROSECT
  1889  	shstrtab.Attr |= AttrReachable
  1890  
  1891  	Addstring(shstrtab, "")
  1892  	Addstring(shstrtab, ".text")
  1893  	Addstring(shstrtab, ".noptrdata")
  1894  	Addstring(shstrtab, ".data")
  1895  	Addstring(shstrtab, ".bss")
  1896  	Addstring(shstrtab, ".noptrbss")
  1897  
  1898  	// generate .tbss section (except for OpenBSD where it's not supported)
  1899  	// for dynamic internal linker or external linking, so that various
  1900  	// binutils could correctly calculate PT_TLS size.
  1901  	// see https://golang.org/issue/5200.
  1902  	if Headtype != obj.Hopenbsd {
  1903  		if !*FlagD || Linkmode == LinkExternal {
  1904  			Addstring(shstrtab, ".tbss")
  1905  		}
  1906  	}
  1907  	if Headtype == obj.Hnetbsd {
  1908  		Addstring(shstrtab, ".note.netbsd.ident")
  1909  	}
  1910  	if Headtype == obj.Hopenbsd {
  1911  		Addstring(shstrtab, ".note.openbsd.ident")
  1912  	}
  1913  	if len(buildinfo) > 0 {
  1914  		Addstring(shstrtab, ".note.gnu.build-id")
  1915  	}
  1916  	if *flagBuildid != "" {
  1917  		Addstring(shstrtab, ".note.go.buildid")
  1918  	}
  1919  	Addstring(shstrtab, ".elfdata")
  1920  	Addstring(shstrtab, ".rodata")
  1921  	// See the comment about data.rel.ro.FOO section names in data.go.
  1922  	relro_prefix := ""
  1923  	if UseRelro() {
  1924  		Addstring(shstrtab, ".data.rel.ro")
  1925  		relro_prefix = ".data.rel.ro"
  1926  	}
  1927  	Addstring(shstrtab, relro_prefix+".typelink")
  1928  	Addstring(shstrtab, relro_prefix+".itablink")
  1929  	Addstring(shstrtab, relro_prefix+".gosymtab")
  1930  	Addstring(shstrtab, relro_prefix+".gopclntab")
  1931  
  1932  	if Linkmode == LinkExternal {
  1933  		*FlagD = true
  1934  
  1935  		Addstring(shstrtab, elfRelType+".text")
  1936  		Addstring(shstrtab, elfRelType+".rodata")
  1937  		Addstring(shstrtab, elfRelType+relro_prefix+".typelink")
  1938  		Addstring(shstrtab, elfRelType+relro_prefix+".itablink")
  1939  		Addstring(shstrtab, elfRelType+relro_prefix+".gosymtab")
  1940  		Addstring(shstrtab, elfRelType+relro_prefix+".gopclntab")
  1941  		Addstring(shstrtab, elfRelType+".noptrdata")
  1942  		Addstring(shstrtab, elfRelType+".data")
  1943  		if UseRelro() {
  1944  			Addstring(shstrtab, elfRelType+".data.rel.ro")
  1945  		}
  1946  
  1947  		// add a .note.GNU-stack section to mark the stack as non-executable
  1948  		Addstring(shstrtab, ".note.GNU-stack")
  1949  
  1950  		if Buildmode == BuildmodeShared {
  1951  			Addstring(shstrtab, ".note.go.abihash")
  1952  			Addstring(shstrtab, ".note.go.pkg-list")
  1953  			Addstring(shstrtab, ".note.go.deps")
  1954  		}
  1955  	}
  1956  
  1957  	hasinitarr := *FlagLinkshared
  1958  
  1959  	/* shared library initializer */
  1960  	switch Buildmode {
  1961  	case BuildmodeCArchive, BuildmodeCShared, BuildmodeShared, BuildmodePlugin:
  1962  		hasinitarr = true
  1963  	}
  1964  
  1965  	if hasinitarr {
  1966  		Addstring(shstrtab, ".init_array")
  1967  		Addstring(shstrtab, elfRelType+".init_array")
  1968  	}
  1969  
  1970  	if !*FlagS {
  1971  		Addstring(shstrtab, ".symtab")
  1972  		Addstring(shstrtab, ".strtab")
  1973  		dwarfaddshstrings(ctxt, shstrtab)
  1974  	}
  1975  
  1976  	Addstring(shstrtab, ".shstrtab")
  1977  
  1978  	if !*FlagD { /* -d suppresses dynamic loader format */
  1979  		Addstring(shstrtab, ".interp")
  1980  		Addstring(shstrtab, ".hash")
  1981  		Addstring(shstrtab, ".got")
  1982  		if SysArch.Family == sys.PPC64 {
  1983  			Addstring(shstrtab, ".glink")
  1984  		}
  1985  		Addstring(shstrtab, ".got.plt")
  1986  		Addstring(shstrtab, ".dynamic")
  1987  		Addstring(shstrtab, ".dynsym")
  1988  		Addstring(shstrtab, ".dynstr")
  1989  		Addstring(shstrtab, elfRelType)
  1990  		Addstring(shstrtab, elfRelType+".plt")
  1991  
  1992  		Addstring(shstrtab, ".plt")
  1993  		Addstring(shstrtab, ".gnu.version")
  1994  		Addstring(shstrtab, ".gnu.version_r")
  1995  
  1996  		/* dynamic symbol table - first entry all zeros */
  1997  		s := ctxt.Syms.Lookup(".dynsym", 0)
  1998  
  1999  		s.Type = obj.SELFROSECT
  2000  		s.Attr |= AttrReachable
  2001  		if elf64 {
  2002  			s.Size += ELF64SYMSIZE
  2003  		} else {
  2004  			s.Size += ELF32SYMSIZE
  2005  		}
  2006  
  2007  		/* dynamic string table */
  2008  		s = ctxt.Syms.Lookup(".dynstr", 0)
  2009  
  2010  		s.Type = obj.SELFROSECT
  2011  		s.Attr |= AttrReachable
  2012  		if s.Size == 0 {
  2013  			Addstring(s, "")
  2014  		}
  2015  		dynstr := s
  2016  
  2017  		/* relocation table */
  2018  		s = ctxt.Syms.Lookup(elfRelType, 0)
  2019  		s.Attr |= AttrReachable
  2020  		s.Type = obj.SELFROSECT
  2021  
  2022  		/* global offset table */
  2023  		s = ctxt.Syms.Lookup(".got", 0)
  2024  
  2025  		s.Attr |= AttrReachable
  2026  		s.Type = obj.SELFGOT // writable
  2027  
  2028  		/* ppc64 glink resolver */
  2029  		if SysArch.Family == sys.PPC64 {
  2030  			s := ctxt.Syms.Lookup(".glink", 0)
  2031  			s.Attr |= AttrReachable
  2032  			s.Type = obj.SELFRXSECT
  2033  		}
  2034  
  2035  		/* hash */
  2036  		s = ctxt.Syms.Lookup(".hash", 0)
  2037  
  2038  		s.Attr |= AttrReachable
  2039  		s.Type = obj.SELFROSECT
  2040  
  2041  		s = ctxt.Syms.Lookup(".got.plt", 0)
  2042  		s.Attr |= AttrReachable
  2043  		s.Type = obj.SELFSECT // writable
  2044  
  2045  		s = ctxt.Syms.Lookup(".plt", 0)
  2046  
  2047  		s.Attr |= AttrReachable
  2048  		if SysArch.Family == sys.PPC64 {
  2049  			// In the ppc64 ABI, .plt is a data section
  2050  			// written by the dynamic linker.
  2051  			s.Type = obj.SELFSECT
  2052  		} else {
  2053  			s.Type = obj.SELFRXSECT
  2054  		}
  2055  
  2056  		Thearch.Elfsetupplt(ctxt)
  2057  
  2058  		s = ctxt.Syms.Lookup(elfRelType+".plt", 0)
  2059  		s.Attr |= AttrReachable
  2060  		s.Type = obj.SELFROSECT
  2061  
  2062  		s = ctxt.Syms.Lookup(".gnu.version", 0)
  2063  		s.Attr |= AttrReachable
  2064  		s.Type = obj.SELFROSECT
  2065  
  2066  		s = ctxt.Syms.Lookup(".gnu.version_r", 0)
  2067  		s.Attr |= AttrReachable
  2068  		s.Type = obj.SELFROSECT
  2069  
  2070  		/* define dynamic elf table */
  2071  		s = ctxt.Syms.Lookup(".dynamic", 0)
  2072  
  2073  		s.Attr |= AttrReachable
  2074  		s.Type = obj.SELFSECT // writable
  2075  
  2076  		/*
  2077  		 * .dynamic table
  2078  		 */
  2079  		elfwritedynentsym(ctxt, s, DT_HASH, ctxt.Syms.Lookup(".hash", 0))
  2080  
  2081  		elfwritedynentsym(ctxt, s, DT_SYMTAB, ctxt.Syms.Lookup(".dynsym", 0))
  2082  		if elf64 {
  2083  			Elfwritedynent(ctxt, s, DT_SYMENT, ELF64SYMSIZE)
  2084  		} else {
  2085  			Elfwritedynent(ctxt, s, DT_SYMENT, ELF32SYMSIZE)
  2086  		}
  2087  		elfwritedynentsym(ctxt, s, DT_STRTAB, ctxt.Syms.Lookup(".dynstr", 0))
  2088  		elfwritedynentsymsize(ctxt, s, DT_STRSZ, ctxt.Syms.Lookup(".dynstr", 0))
  2089  		if elfRelType == ".rela" {
  2090  			elfwritedynentsym(ctxt, s, DT_RELA, ctxt.Syms.Lookup(".rela", 0))
  2091  			elfwritedynentsymsize(ctxt, s, DT_RELASZ, ctxt.Syms.Lookup(".rela", 0))
  2092  			Elfwritedynent(ctxt, s, DT_RELAENT, ELF64RELASIZE)
  2093  		} else {
  2094  			elfwritedynentsym(ctxt, s, DT_REL, ctxt.Syms.Lookup(".rel", 0))
  2095  			elfwritedynentsymsize(ctxt, s, DT_RELSZ, ctxt.Syms.Lookup(".rel", 0))
  2096  			Elfwritedynent(ctxt, s, DT_RELENT, ELF32RELSIZE)
  2097  		}
  2098  
  2099  		if rpath.val != "" {
  2100  			Elfwritedynent(ctxt, s, DT_RUNPATH, uint64(Addstring(dynstr, rpath.val)))
  2101  		}
  2102  
  2103  		if SysArch.Family == sys.PPC64 {
  2104  			elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".plt", 0))
  2105  		} else if SysArch.Family == sys.S390X {
  2106  			elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".got", 0))
  2107  		} else {
  2108  			elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".got.plt", 0))
  2109  		}
  2110  
  2111  		if SysArch.Family == sys.PPC64 {
  2112  			Elfwritedynent(ctxt, s, DT_PPC64_OPT, 0)
  2113  		}
  2114  
  2115  		// Solaris dynamic linker can't handle an empty .rela.plt if
  2116  		// DT_JMPREL is emitted so we have to defer generation of DT_PLTREL,
  2117  		// DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the
  2118  		// size of .rel(a).plt section.
  2119  		Elfwritedynent(ctxt, s, DT_DEBUG, 0)
  2120  	}
  2121  
  2122  	if Buildmode == BuildmodeShared {
  2123  		// The go.link.abihashbytes symbol will be pointed at the appropriate
  2124  		// part of the .note.go.abihash section in data.go:func address().
  2125  		s := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
  2126  		s.Attr |= AttrLocal
  2127  		s.Type = obj.SRODATA
  2128  		s.Attr |= AttrSpecial
  2129  		s.Attr |= AttrReachable
  2130  		s.Size = int64(sha1.Size)
  2131  
  2132  		sort.Sort(byPkg(ctxt.Library))
  2133  		h := sha1.New()
  2134  		for _, l := range ctxt.Library {
  2135  			io.WriteString(h, l.hash)
  2136  		}
  2137  		addgonote(ctxt, ".note.go.abihash", ELF_NOTE_GOABIHASH_TAG, h.Sum([]byte{}))
  2138  		addgonote(ctxt, ".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, pkglistfornote)
  2139  		var deplist []string
  2140  		for _, shlib := range ctxt.Shlibs {
  2141  			deplist = append(deplist, filepath.Base(shlib.Path))
  2142  		}
  2143  		addgonote(ctxt, ".note.go.deps", ELF_NOTE_GODEPS_TAG, []byte(strings.Join(deplist, "\n")))
  2144  	}
  2145  
  2146  	if Linkmode == LinkExternal && *flagBuildid != "" {
  2147  		addgonote(ctxt, ".note.go.buildid", ELF_NOTE_GOBUILDID_TAG, []byte(*flagBuildid))
  2148  	}
  2149  }
  2150  
  2151  // Do not write DT_NULL.  elfdynhash will finish it.
  2152  func shsym(sh *ElfShdr, s *Symbol) {
  2153  	addr := Symaddr(s)
  2154  	if sh.flags&SHF_ALLOC != 0 {
  2155  		sh.addr = uint64(addr)
  2156  	}
  2157  	sh.off = uint64(datoff(s, addr))
  2158  	sh.size = uint64(s.Size)
  2159  }
  2160  
  2161  func phsh(ph *ElfPhdr, sh *ElfShdr) {
  2162  	ph.vaddr = sh.addr
  2163  	ph.paddr = ph.vaddr
  2164  	ph.off = sh.off
  2165  	ph.filesz = sh.size
  2166  	ph.memsz = sh.size
  2167  	ph.align = sh.addralign
  2168  }
  2169  
  2170  func Asmbelfsetup() {
  2171  	/* This null SHdr must appear before all others */
  2172  	elfshname("")
  2173  
  2174  	for sect := Segtext.Sect; sect != nil; sect = sect.Next {
  2175  		// There could be multiple .text sections. Instead check the Elfsect
  2176  		// field to determine if already has an ElfShdr and if not, create one.
  2177  		if sect.Name == ".text" {
  2178  			if sect.Elfsect == nil {
  2179  				sect.Elfsect = elfshnamedup(sect.Name)
  2180  			}
  2181  		} else {
  2182  			elfshalloc(sect)
  2183  		}
  2184  	}
  2185  	for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
  2186  		elfshalloc(sect)
  2187  	}
  2188  	for sect := Segrelrodata.Sect; sect != nil; sect = sect.Next {
  2189  		elfshalloc(sect)
  2190  	}
  2191  	for sect := Segdata.Sect; sect != nil; sect = sect.Next {
  2192  		elfshalloc(sect)
  2193  	}
  2194  	for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
  2195  		elfshalloc(sect)
  2196  	}
  2197  }
  2198  
  2199  func Asmbelf(ctxt *Link, symo int64) {
  2200  	eh := getElfEhdr()
  2201  	switch SysArch.Family {
  2202  	default:
  2203  		Exitf("unknown architecture in asmbelf: %v", SysArch.Family)
  2204  	case sys.MIPS, sys.MIPS64:
  2205  		eh.machine = EM_MIPS
  2206  	case sys.ARM:
  2207  		eh.machine = EM_ARM
  2208  	case sys.AMD64:
  2209  		eh.machine = EM_X86_64
  2210  	case sys.ARM64:
  2211  		eh.machine = EM_AARCH64
  2212  	case sys.I386:
  2213  		eh.machine = EM_386
  2214  	case sys.PPC64:
  2215  		eh.machine = EM_PPC64
  2216  	case sys.RISCV:
  2217  		eh.machine = EM_RISCV
  2218  	case sys.S390X:
  2219  		eh.machine = EM_S390
  2220  	}
  2221  
  2222  	elfreserve := int64(ELFRESERVE)
  2223  
  2224  	numtext := int64(0)
  2225  	for sect := Segtext.Sect; sect != nil; sect = sect.Next {
  2226  		if sect.Name == ".text" {
  2227  			numtext++
  2228  		}
  2229  	}
  2230  
  2231  	// If there are multiple text sections, extra space is needed
  2232  	// in the elfreserve for the additional .text and .rela.text
  2233  	// section headers.  It can handle 4 extra now. Headers are
  2234  	// 64 bytes.
  2235  
  2236  	if numtext > 4 {
  2237  		elfreserve += elfreserve + numtext*64*2
  2238  	}
  2239  
  2240  	startva := *FlagTextAddr - int64(HEADR)
  2241  	resoff := elfreserve
  2242  
  2243  	var pph *ElfPhdr
  2244  	var pnote *ElfPhdr
  2245  	if Linkmode == LinkExternal {
  2246  		/* skip program headers */
  2247  		eh.phoff = 0
  2248  
  2249  		eh.phentsize = 0
  2250  
  2251  		if Buildmode == BuildmodeShared {
  2252  			sh := elfshname(".note.go.pkg-list")
  2253  			sh.type_ = SHT_NOTE
  2254  			sh = elfshname(".note.go.abihash")
  2255  			sh.type_ = SHT_NOTE
  2256  			sh.flags = SHF_ALLOC
  2257  			sh = elfshname(".note.go.deps")
  2258  			sh.type_ = SHT_NOTE
  2259  		}
  2260  
  2261  		if *flagBuildid != "" {
  2262  			sh := elfshname(".note.go.buildid")
  2263  			sh.type_ = SHT_NOTE
  2264  			sh.flags = SHF_ALLOC
  2265  		}
  2266  
  2267  		goto elfobj
  2268  	}
  2269  
  2270  	/* program header info */
  2271  	pph = newElfPhdr()
  2272  
  2273  	pph.type_ = PT_PHDR
  2274  	pph.flags = PF_R
  2275  	pph.off = uint64(eh.ehsize)
  2276  	pph.vaddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off
  2277  	pph.paddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off
  2278  	pph.align = uint64(*FlagRound)
  2279  
  2280  	/*
  2281  	 * PHDR must be in a loaded segment. Adjust the text
  2282  	 * segment boundaries downwards to include it.
  2283  	 * Except on NaCl where it must not be loaded.
  2284  	 */
  2285  	if Headtype != obj.Hnacl {
  2286  		o := int64(Segtext.Vaddr - pph.vaddr)
  2287  		Segtext.Vaddr -= uint64(o)
  2288  		Segtext.Length += uint64(o)
  2289  		o = int64(Segtext.Fileoff - pph.off)
  2290  		Segtext.Fileoff -= uint64(o)
  2291  		Segtext.Filelen += uint64(o)
  2292  	}
  2293  
  2294  	if !*FlagD { /* -d suppresses dynamic loader format */
  2295  		/* interpreter */
  2296  		sh := elfshname(".interp")
  2297  
  2298  		sh.type_ = SHT_PROGBITS
  2299  		sh.flags = SHF_ALLOC
  2300  		sh.addralign = 1
  2301  		if interpreter == "" {
  2302  			switch Headtype {
  2303  			case obj.Hlinux:
  2304  				interpreter = Thearch.Linuxdynld
  2305  
  2306  			case obj.Hfreebsd:
  2307  				interpreter = Thearch.Freebsddynld
  2308  
  2309  			case obj.Hnetbsd:
  2310  				interpreter = Thearch.Netbsddynld
  2311  
  2312  			case obj.Hopenbsd:
  2313  				interpreter = Thearch.Openbsddynld
  2314  
  2315  			case obj.Hdragonfly:
  2316  				interpreter = Thearch.Dragonflydynld
  2317  
  2318  			case obj.Hsolaris:
  2319  				interpreter = Thearch.Solarisdynld
  2320  			}
  2321  		}
  2322  
  2323  		resoff -= int64(elfinterp(sh, uint64(startva), uint64(resoff), interpreter))
  2324  
  2325  		ph := newElfPhdr()
  2326  		ph.type_ = PT_INTERP
  2327  		ph.flags = PF_R
  2328  		phsh(ph, sh)
  2329  	}
  2330  
  2331  	pnote = nil
  2332  	if Headtype == obj.Hnetbsd || Headtype == obj.Hopenbsd {
  2333  		var sh *ElfShdr
  2334  		switch Headtype {
  2335  		case obj.Hnetbsd:
  2336  			sh = elfshname(".note.netbsd.ident")
  2337  			resoff -= int64(elfnetbsdsig(sh, uint64(startva), uint64(resoff)))
  2338  
  2339  		case obj.Hopenbsd:
  2340  			sh = elfshname(".note.openbsd.ident")
  2341  			resoff -= int64(elfopenbsdsig(sh, uint64(startva), uint64(resoff)))
  2342  		}
  2343  
  2344  		pnote = newElfPhdr()
  2345  		pnote.type_ = PT_NOTE
  2346  		pnote.flags = PF_R
  2347  		phsh(pnote, sh)
  2348  	}
  2349  
  2350  	if len(buildinfo) > 0 {
  2351  		sh := elfshname(".note.gnu.build-id")
  2352  		resoff -= int64(elfbuildinfo(sh, uint64(startva), uint64(resoff)))
  2353  
  2354  		if pnote == nil {
  2355  			pnote = newElfPhdr()
  2356  			pnote.type_ = PT_NOTE
  2357  			pnote.flags = PF_R
  2358  		}
  2359  
  2360  		phsh(pnote, sh)
  2361  	}
  2362  
  2363  	if *flagBuildid != "" {
  2364  		sh := elfshname(".note.go.buildid")
  2365  		resoff -= int64(elfgobuildid(sh, uint64(startva), uint64(resoff)))
  2366  
  2367  		pnote := newElfPhdr()
  2368  		pnote.type_ = PT_NOTE
  2369  		pnote.flags = PF_R
  2370  		phsh(pnote, sh)
  2371  	}
  2372  
  2373  	// Additions to the reserved area must be above this line.
  2374  
  2375  	elfphload(&Segtext)
  2376  	if Segrodata.Sect != nil {
  2377  		elfphload(&Segrodata)
  2378  	}
  2379  	if Segrelrodata.Sect != nil {
  2380  		elfphload(&Segrelrodata)
  2381  		elfphrelro(&Segrelrodata)
  2382  	}
  2383  	elfphload(&Segdata)
  2384  
  2385  	/* Dynamic linking sections */
  2386  	if !*FlagD {
  2387  		sh := elfshname(".dynsym")
  2388  		sh.type_ = SHT_DYNSYM
  2389  		sh.flags = SHF_ALLOC
  2390  		if elf64 {
  2391  			sh.entsize = ELF64SYMSIZE
  2392  		} else {
  2393  			sh.entsize = ELF32SYMSIZE
  2394  		}
  2395  		sh.addralign = uint64(SysArch.RegSize)
  2396  		sh.link = uint32(elfshname(".dynstr").shnum)
  2397  
  2398  		// sh->info = index of first non-local symbol (number of local symbols)
  2399  		shsym(sh, ctxt.Syms.Lookup(".dynsym", 0))
  2400  
  2401  		sh = elfshname(".dynstr")
  2402  		sh.type_ = SHT_STRTAB
  2403  		sh.flags = SHF_ALLOC
  2404  		sh.addralign = 1
  2405  		shsym(sh, ctxt.Syms.Lookup(".dynstr", 0))
  2406  
  2407  		if elfverneed != 0 {
  2408  			sh := elfshname(".gnu.version")
  2409  			sh.type_ = SHT_GNU_VERSYM
  2410  			sh.flags = SHF_ALLOC
  2411  			sh.addralign = 2
  2412  			sh.link = uint32(elfshname(".dynsym").shnum)
  2413  			sh.entsize = 2
  2414  			shsym(sh, ctxt.Syms.Lookup(".gnu.version", 0))
  2415  
  2416  			sh = elfshname(".gnu.version_r")
  2417  			sh.type_ = SHT_GNU_VERNEED
  2418  			sh.flags = SHF_ALLOC
  2419  			sh.addralign = uint64(SysArch.RegSize)
  2420  			sh.info = uint32(elfverneed)
  2421  			sh.link = uint32(elfshname(".dynstr").shnum)
  2422  			shsym(sh, ctxt.Syms.Lookup(".gnu.version_r", 0))
  2423  		}
  2424  
  2425  		if elfRelType == ".rela" {
  2426  			sh := elfshname(".rela.plt")
  2427  			sh.type_ = SHT_RELA
  2428  			sh.flags = SHF_ALLOC
  2429  			sh.entsize = ELF64RELASIZE
  2430  			sh.addralign = uint64(SysArch.RegSize)
  2431  			sh.link = uint32(elfshname(".dynsym").shnum)
  2432  			sh.info = uint32(elfshname(".plt").shnum)
  2433  			shsym(sh, ctxt.Syms.Lookup(".rela.plt", 0))
  2434  
  2435  			sh = elfshname(".rela")
  2436  			sh.type_ = SHT_RELA
  2437  			sh.flags = SHF_ALLOC
  2438  			sh.entsize = ELF64RELASIZE
  2439  			sh.addralign = 8
  2440  			sh.link = uint32(elfshname(".dynsym").shnum)
  2441  			shsym(sh, ctxt.Syms.Lookup(".rela", 0))
  2442  		} else {
  2443  			sh := elfshname(".rel.plt")
  2444  			sh.type_ = SHT_REL
  2445  			sh.flags = SHF_ALLOC
  2446  			sh.entsize = ELF32RELSIZE
  2447  			sh.addralign = 4
  2448  			sh.link = uint32(elfshname(".dynsym").shnum)
  2449  			shsym(sh, ctxt.Syms.Lookup(".rel.plt", 0))
  2450  
  2451  			sh = elfshname(".rel")
  2452  			sh.type_ = SHT_REL
  2453  			sh.flags = SHF_ALLOC
  2454  			sh.entsize = ELF32RELSIZE
  2455  			sh.addralign = 4
  2456  			sh.link = uint32(elfshname(".dynsym").shnum)
  2457  			shsym(sh, ctxt.Syms.Lookup(".rel", 0))
  2458  		}
  2459  
  2460  		if eh.machine == EM_PPC64 {
  2461  			sh := elfshname(".glink")
  2462  			sh.type_ = SHT_PROGBITS
  2463  			sh.flags = SHF_ALLOC + SHF_EXECINSTR
  2464  			sh.addralign = 4
  2465  			shsym(sh, ctxt.Syms.Lookup(".glink", 0))
  2466  		}
  2467  
  2468  		sh = elfshname(".plt")
  2469  		sh.type_ = SHT_PROGBITS
  2470  		sh.flags = SHF_ALLOC + SHF_EXECINSTR
  2471  		if eh.machine == EM_X86_64 {
  2472  			sh.entsize = 16
  2473  		} else if eh.machine == EM_S390 {
  2474  			sh.entsize = 32
  2475  		} else if eh.machine == EM_PPC64 {
  2476  			// On ppc64, this is just a table of addresses
  2477  			// filled by the dynamic linker
  2478  			sh.type_ = SHT_NOBITS
  2479  
  2480  			sh.flags = SHF_ALLOC + SHF_WRITE
  2481  			sh.entsize = 8
  2482  		} else {
  2483  			sh.entsize = 4
  2484  		}
  2485  		sh.addralign = sh.entsize
  2486  		shsym(sh, ctxt.Syms.Lookup(".plt", 0))
  2487  
  2488  		// On ppc64, .got comes from the input files, so don't
  2489  		// create it here, and .got.plt is not used.
  2490  		if eh.machine != EM_PPC64 {
  2491  			sh := elfshname(".got")
  2492  			sh.type_ = SHT_PROGBITS
  2493  			sh.flags = SHF_ALLOC + SHF_WRITE
  2494  			sh.entsize = uint64(SysArch.RegSize)
  2495  			sh.addralign = uint64(SysArch.RegSize)
  2496  			shsym(sh, ctxt.Syms.Lookup(".got", 0))
  2497  
  2498  			sh = elfshname(".got.plt")
  2499  			sh.type_ = SHT_PROGBITS
  2500  			sh.flags = SHF_ALLOC + SHF_WRITE
  2501  			sh.entsize = uint64(SysArch.RegSize)
  2502  			sh.addralign = uint64(SysArch.RegSize)
  2503  			shsym(sh, ctxt.Syms.Lookup(".got.plt", 0))
  2504  		}
  2505  
  2506  		sh = elfshname(".hash")
  2507  		sh.type_ = SHT_HASH
  2508  		sh.flags = SHF_ALLOC
  2509  		sh.entsize = 4
  2510  		sh.addralign = uint64(SysArch.RegSize)
  2511  		sh.link = uint32(elfshname(".dynsym").shnum)
  2512  		shsym(sh, ctxt.Syms.Lookup(".hash", 0))
  2513  
  2514  		/* sh and PT_DYNAMIC for .dynamic section */
  2515  		sh = elfshname(".dynamic")
  2516  
  2517  		sh.type_ = SHT_DYNAMIC
  2518  		sh.flags = SHF_ALLOC + SHF_WRITE
  2519  		sh.entsize = 2 * uint64(SysArch.RegSize)
  2520  		sh.addralign = uint64(SysArch.RegSize)
  2521  		sh.link = uint32(elfshname(".dynstr").shnum)
  2522  		shsym(sh, ctxt.Syms.Lookup(".dynamic", 0))
  2523  		ph := newElfPhdr()
  2524  		ph.type_ = PT_DYNAMIC
  2525  		ph.flags = PF_R + PF_W
  2526  		phsh(ph, sh)
  2527  
  2528  		/*
  2529  		 * Thread-local storage segment (really just size).
  2530  		 */
  2531  		// Do not emit PT_TLS for OpenBSD since ld.so(1) does
  2532  		// not currently support it. This is handled
  2533  		// appropriately in runtime/cgo.
  2534  		if Headtype != obj.Hopenbsd {
  2535  			tlssize := uint64(0)
  2536  			for sect := Segdata.Sect; sect != nil; sect = sect.Next {
  2537  				if sect.Name == ".tbss" {
  2538  					tlssize = sect.Length
  2539  				}
  2540  			}
  2541  			if tlssize != 0 {
  2542  				ph := newElfPhdr()
  2543  				ph.type_ = PT_TLS
  2544  				ph.flags = PF_R
  2545  				ph.memsz = tlssize
  2546  				ph.align = uint64(SysArch.RegSize)
  2547  			}
  2548  		}
  2549  	}
  2550  
  2551  	if Headtype == obj.Hlinux {
  2552  		ph := newElfPhdr()
  2553  		ph.type_ = PT_GNU_STACK
  2554  		ph.flags = PF_W + PF_R
  2555  		ph.align = uint64(SysArch.RegSize)
  2556  
  2557  		ph = newElfPhdr()
  2558  		ph.type_ = PT_PAX_FLAGS
  2559  		ph.flags = 0x2a00 // mprotect, randexec, emutramp disabled
  2560  		ph.align = uint64(SysArch.RegSize)
  2561  	} else if Headtype == obj.Hsolaris {
  2562  		ph := newElfPhdr()
  2563  		ph.type_ = PT_SUNWSTACK
  2564  		ph.flags = PF_W + PF_R
  2565  	}
  2566  
  2567  elfobj:
  2568  	sh := elfshname(".shstrtab")
  2569  	sh.type_ = SHT_STRTAB
  2570  	sh.addralign = 1
  2571  	shsym(sh, ctxt.Syms.Lookup(".shstrtab", 0))
  2572  	eh.shstrndx = uint16(sh.shnum)
  2573  
  2574  	// put these sections early in the list
  2575  	if !*FlagS {
  2576  		elfshname(".symtab")
  2577  		elfshname(".strtab")
  2578  	}
  2579  
  2580  	for sect := Segtext.Sect; sect != nil; sect = sect.Next {
  2581  		elfshbits(sect)
  2582  	}
  2583  	for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
  2584  		elfshbits(sect)
  2585  	}
  2586  	for sect := Segrelrodata.Sect; sect != nil; sect = sect.Next {
  2587  		elfshbits(sect)
  2588  	}
  2589  	for sect := Segdata.Sect; sect != nil; sect = sect.Next {
  2590  		elfshbits(sect)
  2591  	}
  2592  	for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
  2593  		elfshbits(sect)
  2594  	}
  2595  
  2596  	if Linkmode == LinkExternal {
  2597  		for sect := Segtext.Sect; sect != nil; sect = sect.Next {
  2598  			elfshreloc(sect)
  2599  		}
  2600  		for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
  2601  			elfshreloc(sect)
  2602  		}
  2603  		for sect := Segrelrodata.Sect; sect != nil; sect = sect.Next {
  2604  			elfshreloc(sect)
  2605  		}
  2606  		for sect := Segdata.Sect; sect != nil; sect = sect.Next {
  2607  			elfshreloc(sect)
  2608  		}
  2609  		for _, s := range dwarfp {
  2610  			if len(s.R) > 0 || s.Type == obj.SDWARFINFO {
  2611  				elfshreloc(s.Sect)
  2612  			}
  2613  			if s.Type == obj.SDWARFINFO {
  2614  				break
  2615  			}
  2616  		}
  2617  		// add a .note.GNU-stack section to mark the stack as non-executable
  2618  		sh := elfshname(".note.GNU-stack")
  2619  
  2620  		sh.type_ = SHT_PROGBITS
  2621  		sh.addralign = 1
  2622  		sh.flags = 0
  2623  	}
  2624  
  2625  	if !*FlagS {
  2626  		sh := elfshname(".symtab")
  2627  		sh.type_ = SHT_SYMTAB
  2628  		sh.off = uint64(symo)
  2629  		sh.size = uint64(Symsize)
  2630  		sh.addralign = uint64(SysArch.RegSize)
  2631  		sh.entsize = 8 + 2*uint64(SysArch.RegSize)
  2632  		sh.link = uint32(elfshname(".strtab").shnum)
  2633  		sh.info = uint32(elfglobalsymndx)
  2634  
  2635  		sh = elfshname(".strtab")
  2636  		sh.type_ = SHT_STRTAB
  2637  		sh.off = uint64(symo) + uint64(Symsize)
  2638  		sh.size = uint64(len(Elfstrdat))
  2639  		sh.addralign = 1
  2640  	}
  2641  
  2642  	/* Main header */
  2643  	eh.ident[EI_MAG0] = '\177'
  2644  
  2645  	eh.ident[EI_MAG1] = 'E'
  2646  	eh.ident[EI_MAG2] = 'L'
  2647  	eh.ident[EI_MAG3] = 'F'
  2648  	if Headtype == obj.Hfreebsd {
  2649  		eh.ident[EI_OSABI] = ELFOSABI_FREEBSD
  2650  	} else if Headtype == obj.Hnetbsd {
  2651  		eh.ident[EI_OSABI] = ELFOSABI_NETBSD
  2652  	} else if Headtype == obj.Hopenbsd {
  2653  		eh.ident[EI_OSABI] = ELFOSABI_OPENBSD
  2654  	} else if Headtype == obj.Hdragonfly {
  2655  		eh.ident[EI_OSABI] = ELFOSABI_NONE
  2656  	}
  2657  	if elf64 {
  2658  		eh.ident[EI_CLASS] = ELFCLASS64
  2659  	} else {
  2660  		eh.ident[EI_CLASS] = ELFCLASS32
  2661  	}
  2662  	if ctxt.Arch.ByteOrder == binary.BigEndian {
  2663  		eh.ident[EI_DATA] = ELFDATA2MSB
  2664  	} else {
  2665  		eh.ident[EI_DATA] = ELFDATA2LSB
  2666  	}
  2667  	eh.ident[EI_VERSION] = EV_CURRENT
  2668  
  2669  	if Linkmode == LinkExternal {
  2670  		eh.type_ = ET_REL
  2671  	} else if Buildmode == BuildmodePIE {
  2672  		eh.type_ = ET_DYN
  2673  	} else {
  2674  		eh.type_ = ET_EXEC
  2675  	}
  2676  
  2677  	if Linkmode != LinkExternal {
  2678  		eh.entry = uint64(Entryvalue(ctxt))
  2679  	}
  2680  
  2681  	eh.version = EV_CURRENT
  2682  
  2683  	if pph != nil {
  2684  		pph.filesz = uint64(eh.phnum) * uint64(eh.phentsize)
  2685  		pph.memsz = pph.filesz
  2686  	}
  2687  
  2688  	Cseek(0)
  2689  	a := int64(0)
  2690  	a += int64(elfwritehdr())
  2691  	a += int64(elfwritephdrs())
  2692  	a += int64(elfwriteshdrs())
  2693  	if !*FlagD {
  2694  		a += int64(elfwriteinterp())
  2695  	}
  2696  	if Linkmode != LinkExternal {
  2697  		if Headtype == obj.Hnetbsd {
  2698  			a += int64(elfwritenetbsdsig())
  2699  		}
  2700  		if Headtype == obj.Hopenbsd {
  2701  			a += int64(elfwriteopenbsdsig())
  2702  		}
  2703  		if len(buildinfo) > 0 {
  2704  			a += int64(elfwritebuildinfo())
  2705  		}
  2706  		if *flagBuildid != "" {
  2707  			a += int64(elfwritegobuildid())
  2708  		}
  2709  	}
  2710  
  2711  	if a > elfreserve {
  2712  		Errorf(nil, "ELFRESERVE too small: %d > %d with %d text sections", a, elfreserve, numtext)
  2713  	}
  2714  }
  2715  
  2716  func Elfadddynsym(ctxt *Link, s *Symbol) {
  2717  	if elf64 {
  2718  		s.Dynid = int32(Nelfsym)
  2719  		Nelfsym++
  2720  
  2721  		d := ctxt.Syms.Lookup(".dynsym", 0)
  2722  
  2723  		name := s.Extname
  2724  		Adduint32(ctxt, d, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
  2725  
  2726  		/* type */
  2727  		t := STB_GLOBAL << 4
  2728  
  2729  		if s.Attr.CgoExport() && s.Type&obj.SMASK == obj.STEXT {
  2730  			t |= STT_FUNC
  2731  		} else {
  2732  			t |= STT_OBJECT
  2733  		}
  2734  		Adduint8(ctxt, d, uint8(t))
  2735  
  2736  		/* reserved */
  2737  		Adduint8(ctxt, d, 0)
  2738  
  2739  		/* section where symbol is defined */
  2740  		if s.Type == obj.SDYNIMPORT {
  2741  			Adduint16(ctxt, d, SHN_UNDEF)
  2742  		} else {
  2743  			Adduint16(ctxt, d, 1)
  2744  		}
  2745  
  2746  		/* value */
  2747  		if s.Type == obj.SDYNIMPORT {
  2748  			Adduint64(ctxt, d, 0)
  2749  		} else {
  2750  			Addaddr(ctxt, d, s)
  2751  		}
  2752  
  2753  		/* size of object */
  2754  		Adduint64(ctxt, d, uint64(s.Size))
  2755  
  2756  		if SysArch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib != "" && !seenlib[s.Dynimplib] {
  2757  			Elfwritedynent(ctxt, ctxt.Syms.Lookup(".dynamic", 0), DT_NEEDED, uint64(Addstring(ctxt.Syms.Lookup(".dynstr", 0), s.Dynimplib)))
  2758  		}
  2759  	} else {
  2760  		s.Dynid = int32(Nelfsym)
  2761  		Nelfsym++
  2762  
  2763  		d := ctxt.Syms.Lookup(".dynsym", 0)
  2764  
  2765  		/* name */
  2766  		name := s.Extname
  2767  
  2768  		Adduint32(ctxt, d, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
  2769  
  2770  		/* value */
  2771  		if s.Type == obj.SDYNIMPORT {
  2772  			Adduint32(ctxt, d, 0)
  2773  		} else {
  2774  			Addaddr(ctxt, d, s)
  2775  		}
  2776  
  2777  		/* size of object */
  2778  		Adduint32(ctxt, d, uint32(s.Size))
  2779  
  2780  		/* type */
  2781  		t := STB_GLOBAL << 4
  2782  
  2783  		// TODO(mwhudson): presumably the behavior should actually be the same on both arm and 386.
  2784  		if SysArch.Family == sys.I386 && s.Attr.CgoExport() && s.Type&obj.SMASK == obj.STEXT {
  2785  			t |= STT_FUNC
  2786  		} else if SysArch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type&obj.SMASK == obj.STEXT {
  2787  			t |= STT_FUNC
  2788  		} else {
  2789  			t |= STT_OBJECT
  2790  		}
  2791  		Adduint8(ctxt, d, uint8(t))
  2792  		Adduint8(ctxt, d, 0)
  2793  
  2794  		/* shndx */
  2795  		if s.Type == obj.SDYNIMPORT {
  2796  			Adduint16(ctxt, d, SHN_UNDEF)
  2797  		} else {
  2798  			Adduint16(ctxt, d, 1)
  2799  		}
  2800  	}
  2801  }
  2802  
  2803  func ELF32_R_SYM(info uint32) uint32 {
  2804  	return info >> 8
  2805  }
  2806  
  2807  func ELF32_R_TYPE(info uint32) uint32 {
  2808  	return uint32(uint8(info))
  2809  }
  2810  
  2811  func ELF32_R_INFO(sym uint32, type_ uint32) uint32 {
  2812  	return sym<<8 | type_
  2813  }
  2814  
  2815  func ELF32_ST_BIND(info uint8) uint8 {
  2816  	return info >> 4
  2817  }
  2818  
  2819  func ELF32_ST_TYPE(info uint8) uint8 {
  2820  	return info & 0xf
  2821  }
  2822  
  2823  func ELF32_ST_INFO(bind uint8, type_ uint8) uint8 {
  2824  	return bind<<4 | type_&0xf
  2825  }
  2826  
  2827  func ELF32_ST_VISIBILITY(oth uint8) uint8 {
  2828  	return oth & 3
  2829  }
  2830  
  2831  func ELF64_R_SYM(info uint64) uint32 {
  2832  	return uint32(info >> 32)
  2833  }
  2834  
  2835  func ELF64_R_TYPE(info uint64) uint32 {
  2836  	return uint32(info)
  2837  }
  2838  
  2839  func ELF64_R_INFO(sym uint32, type_ uint32) uint64 {
  2840  	return uint64(sym)<<32 | uint64(type_)
  2841  }
  2842  
  2843  func ELF64_ST_BIND(info uint8) uint8 {
  2844  	return info >> 4
  2845  }
  2846  
  2847  func ELF64_ST_TYPE(info uint8) uint8 {
  2848  	return info & 0xf
  2849  }
  2850  
  2851  func ELF64_ST_INFO(bind uint8, type_ uint8) uint8 {
  2852  	return bind<<4 | type_&0xf
  2853  }
  2854  
  2855  func ELF64_ST_VISIBILITY(oth uint8) uint8 {
  2856  	return oth & 3
  2857  }