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