...

Source file src/pkg/cmd/link/internal/ld/elf.go

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

View as plain text