github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/src/cmd/link/internal/ld/elf.go (about)

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