github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/src/cmd/link/internal/ld/ldelf.go (about)

     1  package ld
     2  
     3  import (
     4  	"bytes"
     5  	"cmd/internal/bio"
     6  	"cmd/internal/obj"
     7  	"cmd/internal/sys"
     8  	"encoding/binary"
     9  	"fmt"
    10  	"io"
    11  	"log"
    12  	"sort"
    13  	"strings"
    14  )
    15  
    16  /*
    17  Derived from Plan 9 from User Space's src/libmach/elf.h, elf.c
    18  http://code.swtch.com/plan9port/src/tip/src/libmach/
    19  
    20  	Copyright © 2004 Russ Cox.
    21  	Portions Copyright © 2008-2010 Google Inc.
    22  	Portions Copyright © 2010 The Go Authors.
    23  
    24  Permission is hereby granted, free of charge, to any person obtaining a copy
    25  of this software and associated documentation files (the "Software"), to deal
    26  in the Software without restriction, including without limitation the rights
    27  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    28  copies of the Software, and to permit persons to whom the Software is
    29  furnished to do so, subject to the following conditions:
    30  
    31  The above copyright notice and this permission notice shall be included in
    32  all copies or substantial portions of the Software.
    33  
    34  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    35  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    36  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    37  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    38  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    39  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    40  THE SOFTWARE.
    41  */
    42  const (
    43  	ElfClassNone = 0
    44  	ElfClass32   = 1
    45  	ElfClass64   = 2
    46  )
    47  
    48  const (
    49  	ElfDataNone = 0
    50  	ElfDataLsb  = 1
    51  	ElfDataMsb  = 2
    52  )
    53  
    54  const (
    55  	ElfTypeNone         = 0
    56  	ElfTypeRelocatable  = 1
    57  	ElfTypeExecutable   = 2
    58  	ElfTypeSharedObject = 3
    59  	ElfTypeCore         = 4
    60  )
    61  
    62  const (
    63  	ElfMachNone        = 0
    64  	ElfMach32100       = 1
    65  	ElfMachSparc       = 2
    66  	ElfMach386         = 3
    67  	ElfMach68000       = 4
    68  	ElfMach88000       = 5
    69  	ElfMach486         = 6
    70  	ElfMach860         = 7
    71  	ElfMachMips        = 8
    72  	ElfMachS370        = 9
    73  	ElfMachMipsLe      = 10
    74  	ElfMachParisc      = 15
    75  	ElfMachVpp500      = 17
    76  	ElfMachSparc32Plus = 18
    77  	ElfMach960         = 19
    78  	ElfMachPower       = 20
    79  	ElfMachPower64     = 21
    80  	ElfMachS390        = 22
    81  	ElfMachV800        = 36
    82  	ElfMachFr20        = 37
    83  	ElfMachRh32        = 38
    84  	ElfMachRce         = 39
    85  	ElfMachArm         = 40
    86  	ElfMachAlpha       = 41
    87  	ElfMachSH          = 42
    88  	ElfMachSparc9      = 43
    89  	ElfMachAmd64       = 62
    90  	ElfMachArm64       = 183
    91  )
    92  
    93  const (
    94  	ElfAbiNone     = 0
    95  	ElfAbiSystemV  = 0
    96  	ElfAbiHPUX     = 1
    97  	ElfAbiNetBSD   = 2
    98  	ElfAbiLinux    = 3
    99  	ElfAbiSolaris  = 6
   100  	ElfAbiAix      = 7
   101  	ElfAbiIrix     = 8
   102  	ElfAbiFreeBSD  = 9
   103  	ElfAbiTru64    = 10
   104  	ElfAbiModesto  = 11
   105  	ElfAbiOpenBSD  = 12
   106  	ElfAbiARM      = 97
   107  	ElfAbiEmbedded = 255
   108  )
   109  
   110  const (
   111  	ElfSectNone      = 0
   112  	ElfSectProgbits  = 1
   113  	ElfSectSymtab    = 2
   114  	ElfSectStrtab    = 3
   115  	ElfSectRela      = 4
   116  	ElfSectHash      = 5
   117  	ElfSectDynamic   = 6
   118  	ElfSectNote      = 7
   119  	ElfSectNobits    = 8
   120  	ElfSectRel       = 9
   121  	ElfSectShlib     = 10
   122  	ElfSectDynsym    = 11
   123  	ElfSectFlagWrite = 0x1
   124  	ElfSectFlagAlloc = 0x2
   125  	ElfSectFlagExec  = 0x4
   126  )
   127  
   128  const (
   129  	ElfSymBindLocal  = 0
   130  	ElfSymBindGlobal = 1
   131  	ElfSymBindWeak   = 2
   132  )
   133  
   134  const (
   135  	ElfSymTypeNone    = 0
   136  	ElfSymTypeObject  = 1
   137  	ElfSymTypeFunc    = 2
   138  	ElfSymTypeSection = 3
   139  	ElfSymTypeFile    = 4
   140  	ElfSymTypeCommon  = 5
   141  	ElfSymTypeTLS     = 6
   142  )
   143  
   144  const (
   145  	ElfSymShnNone   = 0
   146  	ElfSymShnAbs    = 0xFFF1
   147  	ElfSymShnCommon = 0xFFF2
   148  )
   149  
   150  const (
   151  	ElfProgNone      = 0
   152  	ElfProgLoad      = 1
   153  	ElfProgDynamic   = 2
   154  	ElfProgInterp    = 3
   155  	ElfProgNote      = 4
   156  	ElfProgShlib     = 5
   157  	ElfProgPhdr      = 6
   158  	ElfProgFlagExec  = 0x1
   159  	ElfProgFlagWrite = 0x2
   160  	ElfProgFlagRead  = 0x4
   161  )
   162  
   163  const (
   164  	ElfNotePrStatus     = 1
   165  	ElfNotePrFpreg      = 2
   166  	ElfNotePrPsinfo     = 3
   167  	ElfNotePrTaskstruct = 4
   168  	ElfNotePrAuxv       = 6
   169  	ElfNotePrXfpreg     = 0x46e62b7f
   170  )
   171  
   172  type ElfHdrBytes struct {
   173  	Ident     [16]uint8
   174  	Type      [2]uint8
   175  	Machine   [2]uint8
   176  	Version   [4]uint8
   177  	Entry     [4]uint8
   178  	Phoff     [4]uint8
   179  	Shoff     [4]uint8
   180  	Flags     [4]uint8
   181  	Ehsize    [2]uint8
   182  	Phentsize [2]uint8
   183  	Phnum     [2]uint8
   184  	Shentsize [2]uint8
   185  	Shnum     [2]uint8
   186  	Shstrndx  [2]uint8
   187  }
   188  
   189  type ElfSectBytes struct {
   190  	Name    [4]uint8
   191  	Type    [4]uint8
   192  	Flags   [4]uint8
   193  	Addr    [4]uint8
   194  	Off     [4]uint8
   195  	Size    [4]uint8
   196  	Link    [4]uint8
   197  	Info    [4]uint8
   198  	Align   [4]uint8
   199  	Entsize [4]uint8
   200  }
   201  
   202  type ElfProgBytes struct {
   203  }
   204  
   205  type ElfSymBytes struct {
   206  	Name  [4]uint8
   207  	Value [4]uint8
   208  	Size  [4]uint8
   209  	Info  uint8
   210  	Other uint8
   211  	Shndx [2]uint8
   212  }
   213  
   214  type ElfHdrBytes64 struct {
   215  	Ident     [16]uint8
   216  	Type      [2]uint8
   217  	Machine   [2]uint8
   218  	Version   [4]uint8
   219  	Entry     [8]uint8
   220  	Phoff     [8]uint8
   221  	Shoff     [8]uint8
   222  	Flags     [4]uint8
   223  	Ehsize    [2]uint8
   224  	Phentsize [2]uint8
   225  	Phnum     [2]uint8
   226  	Shentsize [2]uint8
   227  	Shnum     [2]uint8
   228  	Shstrndx  [2]uint8
   229  }
   230  
   231  type ElfSectBytes64 struct {
   232  	Name    [4]uint8
   233  	Type    [4]uint8
   234  	Flags   [8]uint8
   235  	Addr    [8]uint8
   236  	Off     [8]uint8
   237  	Size    [8]uint8
   238  	Link    [4]uint8
   239  	Info    [4]uint8
   240  	Align   [8]uint8
   241  	Entsize [8]uint8
   242  }
   243  
   244  type ElfProgBytes64 struct {
   245  }
   246  
   247  type ElfSymBytes64 struct {
   248  	Name  [4]uint8
   249  	Info  uint8
   250  	Other uint8
   251  	Shndx [2]uint8
   252  	Value [8]uint8
   253  	Size  [8]uint8
   254  }
   255  
   256  type ElfSect struct {
   257  	name    string
   258  	nameoff uint32
   259  	type_   uint32
   260  	flags   uint64
   261  	addr    uint64
   262  	off     uint64
   263  	size    uint64
   264  	link    uint32
   265  	info    uint32
   266  	align   uint64
   267  	entsize uint64
   268  	base    []byte
   269  	sym     *Symbol
   270  }
   271  
   272  type ElfObj struct {
   273  	f         *bio.Reader
   274  	base      int64 // offset in f where ELF begins
   275  	length    int64 // length of ELF
   276  	is64      int
   277  	name      string
   278  	e         binary.ByteOrder
   279  	sect      []ElfSect
   280  	nsect     uint
   281  	shstrtab  string
   282  	nsymtab   int
   283  	symtab    *ElfSect
   284  	symstr    *ElfSect
   285  	type_     uint32
   286  	machine   uint32
   287  	version   uint32
   288  	entry     uint64
   289  	phoff     uint64
   290  	shoff     uint64
   291  	flags     uint32
   292  	ehsize    uint32
   293  	phentsize uint32
   294  	phnum     uint32
   295  	shentsize uint32
   296  	shnum     uint32
   297  	shstrndx  uint32
   298  }
   299  
   300  type ElfSym struct {
   301  	name  string
   302  	value uint64
   303  	size  uint64
   304  	bind  uint8
   305  	type_ uint8
   306  	other uint8
   307  	shndx uint16
   308  	sym   *Symbol
   309  }
   310  
   311  var ElfMagic = [4]uint8{0x7F, 'E', 'L', 'F'}
   312  
   313  const (
   314  	TagFile               = 1
   315  	TagCPUName            = 4
   316  	TagCPURawName         = 5
   317  	TagCompatibility      = 32
   318  	TagNoDefaults         = 64
   319  	TagAlsoCompatibleWith = 65
   320  	TagABIVFPArgs         = 28
   321  )
   322  
   323  type elfAttribute struct {
   324  	tag  uint64
   325  	sval string
   326  	ival uint64
   327  }
   328  
   329  type elfAttributeList struct {
   330  	data []byte
   331  	err  error
   332  }
   333  
   334  func (a *elfAttributeList) string() string {
   335  	if a.err != nil {
   336  		return ""
   337  	}
   338  	nul := bytes.IndexByte(a.data, 0)
   339  	if nul < 0 {
   340  		a.err = io.EOF
   341  		return ""
   342  	}
   343  	s := string(a.data[:nul])
   344  	a.data = a.data[nul+1:]
   345  	return s
   346  }
   347  
   348  func (a *elfAttributeList) uleb128() uint64 {
   349  	if a.err != nil {
   350  		return 0
   351  	}
   352  	v, size := binary.Uvarint(a.data)
   353  	a.data = a.data[size:]
   354  	return v
   355  }
   356  
   357  // Read an elfAttribute from the list following the rules used on ARM systems.
   358  func (a *elfAttributeList) armAttr() elfAttribute {
   359  	attr := elfAttribute{tag: a.uleb128()}
   360  	switch {
   361  	case attr.tag == TagCompatibility:
   362  		attr.ival = a.uleb128()
   363  		attr.sval = a.string()
   364  
   365  	case attr.tag == 64: // Tag_nodefaults has no argument
   366  
   367  	case attr.tag == 65: // Tag_also_compatible_with
   368  		// Not really, but we don't actually care about this tag.
   369  		attr.sval = a.string()
   370  
   371  	// Tag with string argument
   372  	case attr.tag == TagCPUName || attr.tag == TagCPURawName || (attr.tag >= 32 && attr.tag&1 != 0):
   373  		attr.sval = a.string()
   374  
   375  	default: // Tag with integer argument
   376  		attr.ival = a.uleb128()
   377  	}
   378  	return attr
   379  }
   380  
   381  func (a *elfAttributeList) done() bool {
   382  	if a.err != nil || len(a.data) == 0 {
   383  		return true
   384  	}
   385  	return false
   386  }
   387  
   388  // Look for the attribute that indicates the object uses the hard-float ABI (a
   389  // file-level attribute with tag Tag_VFP_arch and value 1). Unfortunately the
   390  // format used means that we have to parse all of the file-level attributes to
   391  // find the one we are looking for. This format is slightly documented in "ELF
   392  // for the ARM Architecture" but mostly this is derived from reading the source
   393  // to gold and readelf.
   394  func parseArmAttributes(ctxt *Link, e binary.ByteOrder, data []byte) {
   395  	// We assume the soft-float ABI unless we see a tag indicating otherwise.
   396  	if ehdr.flags == 0x5000002 {
   397  		ehdr.flags = 0x5000202
   398  	}
   399  	if data[0] != 'A' {
   400  		// TODO(dfc) should this be ctxt.Diag ?
   401  		ctxt.Logf(".ARM.attributes has unexpected format %c\n", data[0])
   402  		return
   403  	}
   404  	data = data[1:]
   405  	for len(data) != 0 {
   406  		sectionlength := e.Uint32(data)
   407  		sectiondata := data[4:sectionlength]
   408  		data = data[sectionlength:]
   409  
   410  		nulIndex := bytes.IndexByte(sectiondata, 0)
   411  		if nulIndex < 0 {
   412  			// TODO(dfc) should this be ctxt.Diag ?
   413  			ctxt.Logf("corrupt .ARM.attributes (section name not NUL-terminated)\n")
   414  			return
   415  		}
   416  		name := string(sectiondata[:nulIndex])
   417  		sectiondata = sectiondata[nulIndex+1:]
   418  
   419  		if name != "aeabi" {
   420  			continue
   421  		}
   422  		for len(sectiondata) != 0 {
   423  			subsectiontag, sz := binary.Uvarint(sectiondata)
   424  			subsectionsize := e.Uint32(sectiondata[sz:])
   425  			subsectiondata := sectiondata[sz+4 : subsectionsize]
   426  			sectiondata = sectiondata[subsectionsize:]
   427  
   428  			if subsectiontag == TagFile {
   429  				attrList := elfAttributeList{data: subsectiondata}
   430  				for !attrList.done() {
   431  					attr := attrList.armAttr()
   432  					if attr.tag == TagABIVFPArgs && attr.ival == 1 {
   433  						ehdr.flags = 0x5000402 // has entry point, Version5 EABI, hard-float ABI
   434  					}
   435  				}
   436  				if attrList.err != nil {
   437  					// TODO(dfc) should this be ctxt.Diag ?
   438  					ctxt.Logf("could not parse .ARM.attributes\n")
   439  				}
   440  			}
   441  		}
   442  	}
   443  }
   444  
   445  func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
   446  	if ctxt.Debugvlog != 0 {
   447  		ctxt.Logf("%5.2f ldelf %s\n", obj.Cputime(), pn)
   448  	}
   449  
   450  	localSymVersion := ctxt.Syms.IncVersion()
   451  	base := f.Offset()
   452  
   453  	var add uint64
   454  	var e binary.ByteOrder
   455  	var elfobj *ElfObj
   456  	var err error
   457  	var flag int
   458  	var hdr *ElfHdrBytes
   459  	var hdrbuf [64]uint8
   460  	var info uint64
   461  	var is64 int
   462  	var j int
   463  	var n int
   464  	var name string
   465  	var p []byte
   466  	var r []Reloc
   467  	var rela int
   468  	var rp *Reloc
   469  	var rsect *ElfSect
   470  	var s *Symbol
   471  	var sect *ElfSect
   472  	var sym ElfSym
   473  	var symbols []*Symbol
   474  	if _, err := io.ReadFull(f, hdrbuf[:]); err != nil {
   475  		goto bad
   476  	}
   477  	hdr = new(ElfHdrBytes)
   478  	binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter
   479  	if string(hdr.Ident[:4]) != "\x7FELF" {
   480  		goto bad
   481  	}
   482  	switch hdr.Ident[5] {
   483  	case ElfDataLsb:
   484  		e = binary.LittleEndian
   485  
   486  	case ElfDataMsb:
   487  		e = binary.BigEndian
   488  
   489  	default:
   490  		goto bad
   491  	}
   492  
   493  	// read header
   494  	elfobj = new(ElfObj)
   495  
   496  	elfobj.e = e
   497  	elfobj.f = f
   498  	elfobj.base = base
   499  	elfobj.length = length
   500  	elfobj.name = pn
   501  
   502  	is64 = 0
   503  	if hdr.Ident[4] == ElfClass64 {
   504  		is64 = 1
   505  		hdr := new(ElfHdrBytes64)
   506  		binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter
   507  		elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
   508  		elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
   509  		elfobj.version = e.Uint32(hdr.Version[:])
   510  		elfobj.phoff = e.Uint64(hdr.Phoff[:])
   511  		elfobj.shoff = e.Uint64(hdr.Shoff[:])
   512  		elfobj.flags = e.Uint32(hdr.Flags[:])
   513  		elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:]))
   514  		elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:]))
   515  		elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:]))
   516  		elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:]))
   517  		elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:]))
   518  		elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:]))
   519  	} else {
   520  		elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
   521  		elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
   522  		elfobj.version = e.Uint32(hdr.Version[:])
   523  		elfobj.entry = uint64(e.Uint32(hdr.Entry[:]))
   524  		elfobj.phoff = uint64(e.Uint32(hdr.Phoff[:]))
   525  		elfobj.shoff = uint64(e.Uint32(hdr.Shoff[:]))
   526  		elfobj.flags = e.Uint32(hdr.Flags[:])
   527  		elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:]))
   528  		elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:]))
   529  		elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:]))
   530  		elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:]))
   531  		elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:]))
   532  		elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:]))
   533  	}
   534  
   535  	elfobj.is64 = is64
   536  
   537  	if uint32(hdr.Ident[6]) != elfobj.version {
   538  		goto bad
   539  	}
   540  
   541  	if e.Uint16(hdr.Type[:]) != ElfTypeRelocatable {
   542  		Errorf(nil, "%s: elf but not elf relocatable object", pn)
   543  		return
   544  	}
   545  
   546  	switch SysArch.Family {
   547  	default:
   548  		Errorf(nil, "%s: elf %s unimplemented", pn, SysArch.Name)
   549  		return
   550  
   551  	case sys.MIPS:
   552  		if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass32 {
   553  			Errorf(nil, "%s: elf object but not mips", pn)
   554  			return
   555  		}
   556  
   557  	case sys.MIPS64:
   558  		if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass64 {
   559  			Errorf(nil, "%s: elf object but not mips64", pn)
   560  			return
   561  		}
   562  
   563  	case sys.ARM:
   564  		if e != binary.LittleEndian || elfobj.machine != ElfMachArm || hdr.Ident[4] != ElfClass32 {
   565  			Errorf(nil, "%s: elf object but not arm", pn)
   566  			return
   567  		}
   568  
   569  	case sys.AMD64:
   570  		if e != binary.LittleEndian || elfobj.machine != ElfMachAmd64 || hdr.Ident[4] != ElfClass64 {
   571  			Errorf(nil, "%s: elf object but not amd64", pn)
   572  			return
   573  		}
   574  
   575  	case sys.ARM64:
   576  		if e != binary.LittleEndian || elfobj.machine != ElfMachArm64 || hdr.Ident[4] != ElfClass64 {
   577  			Errorf(nil, "%s: elf object but not arm64", pn)
   578  			return
   579  		}
   580  
   581  	case sys.I386:
   582  		if e != binary.LittleEndian || elfobj.machine != ElfMach386 || hdr.Ident[4] != ElfClass32 {
   583  			Errorf(nil, "%s: elf object but not 386", pn)
   584  			return
   585  		}
   586  
   587  	case sys.PPC64:
   588  		if elfobj.machine != ElfMachPower64 || hdr.Ident[4] != ElfClass64 {
   589  			Errorf(nil, "%s: elf object but not ppc64", pn)
   590  			return
   591  		}
   592  
   593  	case sys.S390X:
   594  		if elfobj.machine != ElfMachS390 || hdr.Ident[4] != ElfClass64 {
   595  			Errorf(nil, "%s: elf object but not s390x", pn)
   596  			return
   597  		}
   598  	}
   599  
   600  	// load section list into memory.
   601  	elfobj.sect = make([]ElfSect, elfobj.shnum)
   602  
   603  	elfobj.nsect = uint(elfobj.shnum)
   604  	for i := 0; uint(i) < elfobj.nsect; i++ {
   605  		if f.Seek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0) < 0 {
   606  			goto bad
   607  		}
   608  		sect = &elfobj.sect[i]
   609  		if is64 != 0 {
   610  			var b ElfSectBytes64
   611  
   612  			if err = binary.Read(f, e, &b); err != nil {
   613  				goto bad
   614  			}
   615  
   616  			sect.nameoff = e.Uint32(b.Name[:])
   617  			sect.type_ = e.Uint32(b.Type[:])
   618  			sect.flags = e.Uint64(b.Flags[:])
   619  			sect.addr = e.Uint64(b.Addr[:])
   620  			sect.off = e.Uint64(b.Off[:])
   621  			sect.size = e.Uint64(b.Size[:])
   622  			sect.link = e.Uint32(b.Link[:])
   623  			sect.info = e.Uint32(b.Info[:])
   624  			sect.align = e.Uint64(b.Align[:])
   625  			sect.entsize = e.Uint64(b.Entsize[:])
   626  		} else {
   627  			var b ElfSectBytes
   628  
   629  			if err = binary.Read(f, e, &b); err != nil {
   630  				goto bad
   631  			}
   632  
   633  			sect.nameoff = e.Uint32(b.Name[:])
   634  			sect.type_ = e.Uint32(b.Type[:])
   635  			sect.flags = uint64(e.Uint32(b.Flags[:]))
   636  			sect.addr = uint64(e.Uint32(b.Addr[:]))
   637  			sect.off = uint64(e.Uint32(b.Off[:]))
   638  			sect.size = uint64(e.Uint32(b.Size[:]))
   639  			sect.link = e.Uint32(b.Link[:])
   640  			sect.info = e.Uint32(b.Info[:])
   641  			sect.align = uint64(e.Uint32(b.Align[:]))
   642  			sect.entsize = uint64(e.Uint32(b.Entsize[:]))
   643  		}
   644  	}
   645  
   646  	// read section string table and translate names
   647  	if elfobj.shstrndx >= uint32(elfobj.nsect) {
   648  		err = fmt.Errorf("shstrndx out of range %d >= %d", elfobj.shstrndx, elfobj.nsect)
   649  		goto bad
   650  	}
   651  
   652  	sect = &elfobj.sect[elfobj.shstrndx]
   653  	if err = elfmap(elfobj, sect); err != nil {
   654  		goto bad
   655  	}
   656  	for i := 0; uint(i) < elfobj.nsect; i++ {
   657  		if elfobj.sect[i].nameoff != 0 {
   658  			elfobj.sect[i].name = cstring(sect.base[elfobj.sect[i].nameoff:])
   659  		}
   660  	}
   661  
   662  	// load string table for symbols into memory.
   663  	elfobj.symtab = section(elfobj, ".symtab")
   664  
   665  	if elfobj.symtab == nil {
   666  		// our work is done here - no symbols means nothing can refer to this file
   667  		return
   668  	}
   669  
   670  	if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) {
   671  		Errorf(nil, "%s: elf object has symbol table with invalid string table link", pn)
   672  		return
   673  	}
   674  
   675  	elfobj.symstr = &elfobj.sect[elfobj.symtab.link]
   676  	if is64 != 0 {
   677  		elfobj.nsymtab = int(elfobj.symtab.size / ELF64SYMSIZE)
   678  	} else {
   679  		elfobj.nsymtab = int(elfobj.symtab.size / ELF32SYMSIZE)
   680  	}
   681  
   682  	if err = elfmap(elfobj, elfobj.symtab); err != nil {
   683  		goto bad
   684  	}
   685  	if err = elfmap(elfobj, elfobj.symstr); err != nil {
   686  		goto bad
   687  	}
   688  
   689  	// load text and data segments into memory.
   690  	// they are not as small as the section lists, but we'll need
   691  	// the memory anyway for the symbol images, so we might
   692  	// as well use one large chunk.
   693  
   694  	// create symbols for elfmapped sections
   695  	for i := 0; uint(i) < elfobj.nsect; i++ {
   696  		sect = &elfobj.sect[i]
   697  		if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" {
   698  			if err = elfmap(elfobj, sect); err != nil {
   699  				goto bad
   700  			}
   701  			parseArmAttributes(ctxt, e, sect.base[:sect.size])
   702  		}
   703  		if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 {
   704  			continue
   705  		}
   706  		if sect.type_ != ElfSectNobits {
   707  			if err = elfmap(elfobj, sect); err != nil {
   708  				goto bad
   709  			}
   710  		}
   711  
   712  		name = fmt.Sprintf("%s(%s)", pkg, sect.name)
   713  		s = ctxt.Syms.Lookup(name, localSymVersion)
   714  
   715  		switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) {
   716  		default:
   717  			err = fmt.Errorf("unexpected flags for ELF section %s", sect.name)
   718  			goto bad
   719  
   720  		case ElfSectFlagAlloc:
   721  			s.Type = obj.SRODATA
   722  
   723  		case ElfSectFlagAlloc + ElfSectFlagWrite:
   724  			if sect.type_ == ElfSectNobits {
   725  				s.Type = obj.SNOPTRBSS
   726  			} else {
   727  				s.Type = obj.SNOPTRDATA
   728  			}
   729  
   730  		case ElfSectFlagAlloc + ElfSectFlagExec:
   731  			s.Type = obj.STEXT
   732  		}
   733  
   734  		if sect.name == ".got" || sect.name == ".toc" {
   735  			s.Type = obj.SELFGOT
   736  		}
   737  		if sect.type_ == ElfSectProgbits {
   738  			s.P = sect.base
   739  			s.P = s.P[:sect.size]
   740  		}
   741  
   742  		s.Size = int64(sect.size)
   743  		s.Align = int32(sect.align)
   744  		sect.sym = s
   745  	}
   746  
   747  	// enter sub-symbols into symbol table.
   748  	// symbol 0 is the null symbol.
   749  	symbols = make([]*Symbol, elfobj.nsymtab)
   750  
   751  	for i := 1; i < elfobj.nsymtab; i++ {
   752  		if err = readelfsym(ctxt, elfobj, i, &sym, 1, localSymVersion); err != nil {
   753  			goto bad
   754  		}
   755  		symbols[i] = sym.sym
   756  		if sym.type_ != ElfSymTypeFunc && sym.type_ != ElfSymTypeObject && sym.type_ != ElfSymTypeNone && sym.type_ != ElfSymTypeCommon {
   757  			continue
   758  		}
   759  		if sym.shndx == ElfSymShnCommon || sym.type_ == ElfSymTypeCommon {
   760  			s = sym.sym
   761  			if uint64(s.Size) < sym.size {
   762  				s.Size = int64(sym.size)
   763  			}
   764  			if s.Type == 0 || s.Type == obj.SXREF {
   765  				s.Type = obj.SNOPTRBSS
   766  			}
   767  			continue
   768  		}
   769  
   770  		if uint(sym.shndx) >= elfobj.nsect || sym.shndx == 0 {
   771  			continue
   772  		}
   773  
   774  		// even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols
   775  		if sym.sym == nil {
   776  			continue
   777  		}
   778  		sect = &elfobj.sect[sym.shndx]
   779  		if sect.sym == nil {
   780  			if strings.HasPrefix(sym.name, ".Linfo_string") { // clang does this
   781  				continue
   782  			}
   783  
   784  			if sym.name == "" && sym.type_ == 0 && sect.name == ".debug_str" {
   785  				// This reportedly happens with clang 3.7 on ARM.
   786  				// See issue 13139.
   787  				continue
   788  			}
   789  
   790  			if strings.HasPrefix(sym.name, ".LASF") { // gcc on s390x does this
   791  				continue
   792  			}
   793  			Errorf(sym.sym, "%s: sym#%d: ignoring symbol in section %d (type %d)", pn, i, sym.shndx, sym.type_)
   794  			continue
   795  		}
   796  
   797  		s = sym.sym
   798  		if s.Outer != nil {
   799  			if s.Attr.DuplicateOK() {
   800  				continue
   801  			}
   802  			Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name)
   803  		}
   804  
   805  		s.Sub = sect.sym.Sub
   806  		sect.sym.Sub = s
   807  		s.Type = sect.sym.Type | s.Type&^obj.SMASK | obj.SSUB
   808  		if !s.Attr.CgoExportDynamic() {
   809  			s.Dynimplib = "" // satisfy dynimport
   810  		}
   811  		s.Value = int64(sym.value)
   812  		s.Size = int64(sym.size)
   813  		s.Outer = sect.sym
   814  		if sect.sym.Type == obj.STEXT {
   815  			if s.Attr.External() && !s.Attr.DuplicateOK() {
   816  				Errorf(s, "%s: duplicate symbol definition", pn)
   817  			}
   818  			s.Attr |= AttrExternal
   819  		}
   820  
   821  		if elfobj.machine == ElfMachPower64 {
   822  			flag = int(sym.other) >> 5
   823  			if 2 <= flag && flag <= 6 {
   824  				s.Localentry = 1 << uint(flag-2)
   825  			} else if flag == 7 {
   826  				Errorf(s, "%s: invalid sym.other 0x%x", pn, sym.other)
   827  			}
   828  		}
   829  	}
   830  
   831  	// Sort outer lists by address, adding to textp.
   832  	// This keeps textp in increasing address order.
   833  	for i := 0; uint(i) < elfobj.nsect; i++ {
   834  		s = elfobj.sect[i].sym
   835  		if s == nil {
   836  			continue
   837  		}
   838  		if s.Sub != nil {
   839  			s.Sub = listsort(s.Sub)
   840  		}
   841  		if s.Type == obj.STEXT {
   842  			if s.Attr.OnList() {
   843  				log.Fatalf("symbol %s listed multiple times", s.Name)
   844  			}
   845  			s.Attr |= AttrOnList
   846  			ctxt.Textp = append(ctxt.Textp, s)
   847  			for s = s.Sub; s != nil; s = s.Sub {
   848  				if s.Attr.OnList() {
   849  					log.Fatalf("symbol %s listed multiple times", s.Name)
   850  				}
   851  				s.Attr |= AttrOnList
   852  				ctxt.Textp = append(ctxt.Textp, s)
   853  			}
   854  		}
   855  	}
   856  
   857  	// load relocations
   858  	for i := 0; uint(i) < elfobj.nsect; i++ {
   859  		rsect = &elfobj.sect[i]
   860  		if rsect.type_ != ElfSectRela && rsect.type_ != ElfSectRel {
   861  			continue
   862  		}
   863  		if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil {
   864  			continue
   865  		}
   866  		sect = &elfobj.sect[rsect.info]
   867  		if err = elfmap(elfobj, rsect); err != nil {
   868  			goto bad
   869  		}
   870  		rela = 0
   871  		if rsect.type_ == ElfSectRela {
   872  			rela = 1
   873  		}
   874  		n = int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
   875  		r = make([]Reloc, n)
   876  		p = rsect.base
   877  		for j = 0; j < n; j++ {
   878  			add = 0
   879  			rp = &r[j]
   880  			if is64 != 0 {
   881  				// 64-bit rel/rela
   882  				rp.Off = int32(e.Uint64(p))
   883  
   884  				p = p[8:]
   885  				info = e.Uint64(p)
   886  				p = p[8:]
   887  				if rela != 0 {
   888  					add = e.Uint64(p)
   889  					p = p[8:]
   890  				}
   891  			} else {
   892  				// 32-bit rel/rela
   893  				rp.Off = int32(e.Uint32(p))
   894  
   895  				p = p[4:]
   896  				info = uint64(e.Uint32(p))
   897  				info = info>>8<<32 | info&0xff // convert to 64-bit info
   898  				p = p[4:]
   899  				if rela != 0 {
   900  					add = uint64(e.Uint32(p))
   901  					p = p[4:]
   902  				}
   903  			}
   904  
   905  			if info&0xffffffff == 0 { // skip R_*_NONE relocation
   906  				j--
   907  				n--
   908  				continue
   909  			}
   910  
   911  			if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol
   912  				rp.Sym = nil
   913  			} else {
   914  				if err = readelfsym(ctxt, elfobj, int(info>>32), &sym, 0, 0); err != nil {
   915  					goto bad
   916  				}
   917  				sym.sym = symbols[info>>32]
   918  				if sym.sym == nil {
   919  					err = fmt.Errorf("%s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", sect.sym.Name, j, int(info>>32), sym.name, sym.shndx, sym.type_)
   920  					goto bad
   921  				}
   922  
   923  				rp.Sym = sym.sym
   924  			}
   925  
   926  			rp.Type = 256 + obj.RelocType(info)
   927  			rp.Siz = relSize(ctxt, pn, uint32(info))
   928  			if rela != 0 {
   929  				rp.Add = int64(add)
   930  			} else {
   931  				// load addend from image
   932  				if rp.Siz == 4 {
   933  					rp.Add = int64(e.Uint32(sect.base[rp.Off:]))
   934  				} else if rp.Siz == 8 {
   935  					rp.Add = int64(e.Uint64(sect.base[rp.Off:]))
   936  				} else {
   937  					Errorf(nil, "invalid rela size %d", rp.Siz)
   938  				}
   939  			}
   940  
   941  			if rp.Siz == 2 {
   942  				rp.Add = int64(int16(rp.Add))
   943  			}
   944  			if rp.Siz == 4 {
   945  				rp.Add = int64(int32(rp.Add))
   946  			}
   947  		}
   948  
   949  		//print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add);
   950  		sort.Sort(rbyoff(r[:n]))
   951  		// just in case
   952  
   953  		s = sect.sym
   954  		s.R = r
   955  		s.R = s.R[:n]
   956  	}
   957  
   958  	return
   959  
   960  bad:
   961  	Errorf(nil, "%s: malformed elf file: %v", pn, err)
   962  }
   963  
   964  func section(elfobj *ElfObj, name string) *ElfSect {
   965  	for i := 0; uint(i) < elfobj.nsect; i++ {
   966  		if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name {
   967  			return &elfobj.sect[i]
   968  		}
   969  	}
   970  	return nil
   971  }
   972  
   973  func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
   974  	if sect.base != nil {
   975  		return nil
   976  	}
   977  
   978  	if sect.off+sect.size > uint64(elfobj.length) {
   979  		err = fmt.Errorf("elf section past end of file")
   980  		return err
   981  	}
   982  
   983  	sect.base = make([]byte, sect.size)
   984  	if elfobj.f.Seek(int64(uint64(elfobj.base)+sect.off), 0) < 0 {
   985  		return fmt.Errorf("short read: seek not successful")
   986  	}
   987  	if _, err := io.ReadFull(elfobj.f, sect.base); err != nil {
   988  		return fmt.Errorf("short read: %v", err)
   989  	}
   990  
   991  	return nil
   992  }
   993  
   994  func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, localSymVersion int) (err error) {
   995  	if i >= elfobj.nsymtab || i < 0 {
   996  		err = fmt.Errorf("invalid elf symbol index")
   997  		return err
   998  	}
   999  
  1000  	if i == 0 {
  1001  		Errorf(nil, "readym: read null symbol!")
  1002  	}
  1003  
  1004  	if elfobj.is64 != 0 {
  1005  		b := new(ElfSymBytes64)
  1006  		binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF64SYMSIZE:(i+1)*ELF64SYMSIZE]), elfobj.e, b)
  1007  		sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
  1008  		sym.value = elfobj.e.Uint64(b.Value[:])
  1009  		sym.size = elfobj.e.Uint64(b.Size[:])
  1010  		sym.shndx = elfobj.e.Uint16(b.Shndx[:])
  1011  		sym.bind = b.Info >> 4
  1012  		sym.type_ = b.Info & 0xf
  1013  		sym.other = b.Other
  1014  	} else {
  1015  		b := new(ElfSymBytes)
  1016  		binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF32SYMSIZE:(i+1)*ELF32SYMSIZE]), elfobj.e, b)
  1017  		sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
  1018  		sym.value = uint64(elfobj.e.Uint32(b.Value[:]))
  1019  		sym.size = uint64(elfobj.e.Uint32(b.Size[:]))
  1020  		sym.shndx = elfobj.e.Uint16(b.Shndx[:])
  1021  		sym.bind = b.Info >> 4
  1022  		sym.type_ = b.Info & 0xf
  1023  		sym.other = b.Other
  1024  	}
  1025  
  1026  	var s *Symbol
  1027  	if sym.name == "_GLOBAL_OFFSET_TABLE_" {
  1028  		sym.name = ".got"
  1029  	}
  1030  	if sym.name == ".TOC." {
  1031  		// Magic symbol on ppc64.  Will be set to this object
  1032  		// file's .got+0x8000.
  1033  		sym.bind = ElfSymBindLocal
  1034  	}
  1035  
  1036  	switch sym.type_ {
  1037  	case ElfSymTypeSection:
  1038  		s = elfobj.sect[sym.shndx].sym
  1039  
  1040  	case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone, ElfSymTypeCommon:
  1041  		switch sym.bind {
  1042  		case ElfSymBindGlobal:
  1043  			if needSym != 0 {
  1044  				s = ctxt.Syms.Lookup(sym.name, 0)
  1045  
  1046  				// for global scoped hidden symbols we should insert it into
  1047  				// symbol hash table, but mark them as hidden.
  1048  				// __i686.get_pc_thunk.bx is allowed to be duplicated, to
  1049  				// workaround that we set dupok.
  1050  				// TODO(minux): correctly handle __i686.get_pc_thunk.bx without
  1051  				// set dupok generally. See http://codereview.appspot.com/5823055/
  1052  				// comment #5 for details.
  1053  				if s != nil && sym.other == 2 {
  1054  					s.Type |= obj.SHIDDEN
  1055  					s.Attr |= AttrDuplicateOK
  1056  				}
  1057  			}
  1058  
  1059  		case ElfSymBindLocal:
  1060  			if SysArch.Family == sys.ARM && (strings.HasPrefix(sym.name, "$a") || strings.HasPrefix(sym.name, "$d")) {
  1061  				// binutils for arm generate these mapping
  1062  				// symbols, ignore these
  1063  				break
  1064  			}
  1065  
  1066  			if sym.name == ".TOC." {
  1067  				// We need to be able to look this up,
  1068  				// so put it in the hash table.
  1069  				if needSym != 0 {
  1070  					s = ctxt.Syms.Lookup(sym.name, localSymVersion)
  1071  					s.Type |= obj.SHIDDEN
  1072  				}
  1073  
  1074  				break
  1075  			}
  1076  
  1077  			if needSym != 0 {
  1078  				// local names and hidden global names are unique
  1079  				// and should only be referenced by their index, not name, so we
  1080  				// don't bother to add them into the hash table
  1081  				s = ctxt.Syms.newsym(sym.name, localSymVersion)
  1082  
  1083  				s.Type |= obj.SHIDDEN
  1084  			}
  1085  
  1086  		case ElfSymBindWeak:
  1087  			if needSym != 0 {
  1088  				s = ctxt.Syms.Lookup(sym.name, 0)
  1089  				if sym.other == 2 {
  1090  					s.Type |= obj.SHIDDEN
  1091  				}
  1092  			}
  1093  
  1094  		default:
  1095  			err = fmt.Errorf("%s: invalid symbol binding %d", sym.name, sym.bind)
  1096  			return err
  1097  		}
  1098  	}
  1099  
  1100  	if s != nil && s.Type == 0 && sym.type_ != ElfSymTypeSection {
  1101  		s.Type = obj.SXREF
  1102  	}
  1103  	sym.sym = s
  1104  
  1105  	return nil
  1106  }
  1107  
  1108  type rbyoff []Reloc
  1109  
  1110  func (x rbyoff) Len() int {
  1111  	return len(x)
  1112  }
  1113  
  1114  func (x rbyoff) Swap(i, j int) {
  1115  	x[i], x[j] = x[j], x[i]
  1116  }
  1117  
  1118  func (x rbyoff) Less(i, j int) bool {
  1119  	a := &x[i]
  1120  	b := &x[j]
  1121  	if a.Off < b.Off {
  1122  		return true
  1123  	}
  1124  	if a.Off > b.Off {
  1125  		return false
  1126  	}
  1127  	return false
  1128  }
  1129  
  1130  func relSize(ctxt *Link, pn string, elftype uint32) uint8 {
  1131  	// TODO(mdempsky): Replace this with a struct-valued switch statement
  1132  	// once golang.org/issue/15164 is fixed or found to not impair cmd/link
  1133  	// performance.
  1134  
  1135  	const (
  1136  		AMD64 = uint32(sys.AMD64)
  1137  		ARM   = uint32(sys.ARM)
  1138  		I386  = uint32(sys.I386)
  1139  		PPC64 = uint32(sys.PPC64)
  1140  		S390X = uint32(sys.S390X)
  1141  	)
  1142  
  1143  	switch uint32(SysArch.Family) | elftype<<24 {
  1144  	default:
  1145  		Errorf(nil, "%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
  1146  		fallthrough
  1147  
  1148  	case S390X | R_390_8<<24:
  1149  		return 1
  1150  
  1151  	case PPC64 | R_PPC64_TOC16<<24,
  1152  		PPC64 | R_PPC64_TOC16_LO<<24,
  1153  		PPC64 | R_PPC64_TOC16_HI<<24,
  1154  		PPC64 | R_PPC64_TOC16_HA<<24,
  1155  		PPC64 | R_PPC64_TOC16_DS<<24,
  1156  		PPC64 | R_PPC64_TOC16_LO_DS<<24,
  1157  		PPC64 | R_PPC64_REL16_LO<<24,
  1158  		PPC64 | R_PPC64_REL16_HI<<24,
  1159  		PPC64 | R_PPC64_REL16_HA<<24,
  1160  		S390X | R_390_16<<24,
  1161  		S390X | R_390_GOT16<<24,
  1162  		S390X | R_390_PC16<<24,
  1163  		S390X | R_390_PC16DBL<<24,
  1164  		S390X | R_390_PLT16DBL<<24:
  1165  		return 2
  1166  
  1167  	case ARM | R_ARM_ABS32<<24,
  1168  		ARM | R_ARM_GOT32<<24,
  1169  		ARM | R_ARM_PLT32<<24,
  1170  		ARM | R_ARM_GOTOFF<<24,
  1171  		ARM | R_ARM_GOTPC<<24,
  1172  		ARM | R_ARM_THM_PC22<<24,
  1173  		ARM | R_ARM_REL32<<24,
  1174  		ARM | R_ARM_CALL<<24,
  1175  		ARM | R_ARM_V4BX<<24,
  1176  		ARM | R_ARM_GOT_PREL<<24,
  1177  		ARM | R_ARM_PC24<<24,
  1178  		ARM | R_ARM_JUMP24<<24,
  1179  		AMD64 | R_X86_64_PC32<<24,
  1180  		AMD64 | R_X86_64_PLT32<<24,
  1181  		AMD64 | R_X86_64_GOTPCREL<<24,
  1182  		AMD64 | R_X86_64_GOTPCRELX<<24,
  1183  		AMD64 | R_X86_64_REX_GOTPCRELX<<24,
  1184  		I386 | R_386_32<<24,
  1185  		I386 | R_386_PC32<<24,
  1186  		I386 | R_386_GOT32<<24,
  1187  		I386 | R_386_PLT32<<24,
  1188  		I386 | R_386_GOTOFF<<24,
  1189  		I386 | R_386_GOTPC<<24,
  1190  		I386 | R_386_GOT32X<<24,
  1191  		PPC64 | R_PPC64_REL24<<24,
  1192  		PPC64 | R_PPC_REL32<<24,
  1193  		S390X | R_390_32<<24,
  1194  		S390X | R_390_PC32<<24,
  1195  		S390X | R_390_GOT32<<24,
  1196  		S390X | R_390_PLT32<<24,
  1197  		S390X | R_390_PC32DBL<<24,
  1198  		S390X | R_390_PLT32DBL<<24,
  1199  		S390X | R_390_GOTPCDBL<<24,
  1200  		S390X | R_390_GOTENT<<24:
  1201  		return 4
  1202  
  1203  	case AMD64 | R_X86_64_64<<24,
  1204  		PPC64 | R_PPC64_ADDR64<<24,
  1205  		S390X | R_390_GLOB_DAT<<24,
  1206  		S390X | R_390_RELATIVE<<24,
  1207  		S390X | R_390_GOTOFF<<24,
  1208  		S390X | R_390_GOTPC<<24,
  1209  		S390X | R_390_64<<24,
  1210  		S390X | R_390_PC64<<24,
  1211  		S390X | R_390_GOT64<<24,
  1212  		S390X | R_390_PLT64<<24:
  1213  		return 8
  1214  	}
  1215  }