Black Lives Matter. Support the Equal Justice Initiative.

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

Documentation: cmd/link/internal/ld

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

View as plain text