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