github.com/rsc/tmp@v0.0.0-20240517235954-6deaab19748b/bootstrap/internal/ld/elf.go (about)

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