github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/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  	case sys.SPARC64:
   599  		if elfobj.machine != ElfMachSparc9 || hdr.Ident[4] != ElfClass64 {
   600  			Diag("%s: elf object but not sparc64", pn)
   601  			return
   602  		}
   603  	}
   604  
   605  	// load section list into memory.
   606  	elfobj.sect = make([]ElfSect, elfobj.shnum)
   607  
   608  	elfobj.nsect = uint(elfobj.shnum)
   609  	for i := 0; uint(i) < elfobj.nsect; i++ {
   610  		if f.Seek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0) < 0 {
   611  			goto bad
   612  		}
   613  		sect = &elfobj.sect[i]
   614  		if is64 != 0 {
   615  			var b ElfSectBytes64
   616  
   617  			if err = binary.Read(f, e, &b); err != nil {
   618  				goto bad
   619  			}
   620  
   621  			sect.nameoff = e.Uint32(b.Name[:])
   622  			sect.type_ = e.Uint32(b.Type[:])
   623  			sect.flags = e.Uint64(b.Flags[:])
   624  			sect.addr = e.Uint64(b.Addr[:])
   625  			sect.off = e.Uint64(b.Off[:])
   626  			sect.size = e.Uint64(b.Size[:])
   627  			sect.link = e.Uint32(b.Link[:])
   628  			sect.info = e.Uint32(b.Info[:])
   629  			sect.align = e.Uint64(b.Align[:])
   630  			sect.entsize = e.Uint64(b.Entsize[:])
   631  		} else {
   632  			var b ElfSectBytes
   633  
   634  			if err = binary.Read(f, e, &b); err != nil {
   635  				goto bad
   636  			}
   637  
   638  			sect.nameoff = e.Uint32(b.Name[:])
   639  			sect.type_ = e.Uint32(b.Type[:])
   640  			sect.flags = uint64(e.Uint32(b.Flags[:]))
   641  			sect.addr = uint64(e.Uint32(b.Addr[:]))
   642  			sect.off = uint64(e.Uint32(b.Off[:]))
   643  			sect.size = uint64(e.Uint32(b.Size[:]))
   644  			sect.link = e.Uint32(b.Link[:])
   645  			sect.info = e.Uint32(b.Info[:])
   646  			sect.align = uint64(e.Uint32(b.Align[:]))
   647  			sect.entsize = uint64(e.Uint32(b.Entsize[:]))
   648  		}
   649  	}
   650  
   651  	// read section string table and translate names
   652  	if elfobj.shstrndx >= uint32(elfobj.nsect) {
   653  		err = fmt.Errorf("shstrndx out of range %d >= %d", elfobj.shstrndx, elfobj.nsect)
   654  		goto bad
   655  	}
   656  
   657  	sect = &elfobj.sect[elfobj.shstrndx]
   658  	if err = elfmap(elfobj, sect); err != nil {
   659  		goto bad
   660  	}
   661  	for i := 0; uint(i) < elfobj.nsect; i++ {
   662  		if elfobj.sect[i].nameoff != 0 {
   663  			elfobj.sect[i].name = cstring(sect.base[elfobj.sect[i].nameoff:])
   664  		}
   665  	}
   666  
   667  	// load string table for symbols into memory.
   668  	elfobj.symtab = section(elfobj, ".symtab")
   669  
   670  	if elfobj.symtab == nil {
   671  		// our work is done here - no symbols means nothing can refer to this file
   672  		return
   673  	}
   674  
   675  	if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) {
   676  		Diag("%s: elf object has symbol table with invalid string table link", pn)
   677  		return
   678  	}
   679  
   680  	elfobj.symstr = &elfobj.sect[elfobj.symtab.link]
   681  	if is64 != 0 {
   682  		elfobj.nsymtab = int(elfobj.symtab.size / ELF64SYMSIZE)
   683  	} else {
   684  		elfobj.nsymtab = int(elfobj.symtab.size / ELF32SYMSIZE)
   685  	}
   686  
   687  	if err = elfmap(elfobj, elfobj.symtab); err != nil {
   688  		goto bad
   689  	}
   690  	if err = elfmap(elfobj, elfobj.symstr); err != nil {
   691  		goto bad
   692  	}
   693  
   694  	// load text and data segments into memory.
   695  	// they are not as small as the section lists, but we'll need
   696  	// the memory anyway for the symbol images, so we might
   697  	// as well use one large chunk.
   698  
   699  	// create symbols for elfmapped sections
   700  	for i := 0; uint(i) < elfobj.nsect; i++ {
   701  		sect = &elfobj.sect[i]
   702  		if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" {
   703  			if err = elfmap(elfobj, sect); err != nil {
   704  				goto bad
   705  			}
   706  			parseArmAttributes(e, sect.base[:sect.size])
   707  		}
   708  		if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 {
   709  			continue
   710  		}
   711  		if sect.type_ != ElfSectNobits {
   712  			if err = elfmap(elfobj, sect); err != nil {
   713  				goto bad
   714  			}
   715  		}
   716  
   717  		name = fmt.Sprintf("%s(%s)", pkg, sect.name)
   718  		s = Linklookup(Ctxt, name, Ctxt.Version)
   719  
   720  		switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) {
   721  		default:
   722  			err = fmt.Errorf("unexpected flags for ELF section %s", sect.name)
   723  			goto bad
   724  
   725  		case ElfSectFlagAlloc:
   726  			s.Type = obj.SRODATA
   727  
   728  		case ElfSectFlagAlloc + ElfSectFlagWrite:
   729  			if sect.type_ == ElfSectNobits {
   730  				s.Type = obj.SNOPTRBSS
   731  			} else {
   732  				s.Type = obj.SNOPTRDATA
   733  			}
   734  
   735  		case ElfSectFlagAlloc + ElfSectFlagExec:
   736  			s.Type = obj.STEXT
   737  		}
   738  
   739  		if sect.name == ".got" || sect.name == ".toc" {
   740  			s.Type = obj.SELFGOT
   741  		}
   742  		if sect.type_ == ElfSectProgbits {
   743  			s.P = sect.base
   744  			s.P = s.P[:sect.size]
   745  		}
   746  
   747  		s.Size = int64(sect.size)
   748  		s.Align = int32(sect.align)
   749  		sect.sym = s
   750  	}
   751  
   752  	// enter sub-symbols into symbol table.
   753  	// symbol 0 is the null symbol.
   754  	symbols = make([]*LSym, elfobj.nsymtab)
   755  
   756  	for i := 1; i < elfobj.nsymtab; i++ {
   757  		if err = readelfsym(elfobj, i, &sym, 1); err != nil {
   758  			goto bad
   759  		}
   760  		symbols[i] = sym.sym
   761  		if sym.type_ != ElfSymTypeFunc && sym.type_ != ElfSymTypeObject && sym.type_ != ElfSymTypeNone {
   762  			continue
   763  		}
   764  		if sym.shndx == ElfSymShnCommon {
   765  			s = sym.sym
   766  			if uint64(s.Size) < sym.size {
   767  				s.Size = int64(sym.size)
   768  			}
   769  			if s.Type == 0 || s.Type == obj.SXREF {
   770  				s.Type = obj.SNOPTRBSS
   771  			}
   772  			continue
   773  		}
   774  
   775  		if uint(sym.shndx) >= elfobj.nsect || sym.shndx == 0 {
   776  			continue
   777  		}
   778  
   779  		// even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols
   780  		if sym.sym == nil {
   781  			continue
   782  		}
   783  		sect = &elfobj.sect[sym.shndx]
   784  		if sect.sym == nil {
   785  			if strings.HasPrefix(sym.name, ".Linfo_string") { // clang does this
   786  				continue
   787  			}
   788  
   789  			if sym.name == "" && sym.type_ == 0 && sect.name == ".debug_str" {
   790  				// This reportedly happens with clang 3.7 on ARM.
   791  				// See issue 13139.
   792  				continue
   793  			}
   794  
   795  			if strings.HasPrefix(sym.name, ".LASF") { // gcc on s390x does this
   796  				continue
   797  			}
   798  			Diag("%s: sym#%d: ignoring %s in section %d (type %d)", pn, i, sym.name, sym.shndx, sym.type_)
   799  			continue
   800  		}
   801  
   802  		s = sym.sym
   803  		if s.Outer != nil {
   804  			if s.Attr.DuplicateOK() {
   805  				continue
   806  			}
   807  			Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name)
   808  		}
   809  
   810  		s.Sub = sect.sym.Sub
   811  		sect.sym.Sub = s
   812  		s.Type = sect.sym.Type | s.Type&^obj.SMASK | obj.SSUB
   813  		if !s.Attr.CgoExportDynamic() {
   814  			s.Dynimplib = "" // satisfy dynimport
   815  		}
   816  		s.Value = int64(sym.value)
   817  		s.Size = int64(sym.size)
   818  		s.Outer = sect.sym
   819  		if sect.sym.Type == obj.STEXT {
   820  			if s.Attr.External() && !s.Attr.DuplicateOK() {
   821  				Diag("%s: duplicate definition of %s", pn, s.Name)
   822  			}
   823  			s.Attr |= AttrExternal
   824  		}
   825  
   826  		if elfobj.machine == ElfMachPower64 {
   827  			flag = int(sym.other) >> 5
   828  			if 2 <= flag && flag <= 6 {
   829  				s.Localentry = 1 << uint(flag-2)
   830  			} else if flag == 7 {
   831  				Diag("%s: invalid sym.other 0x%x for %s", pn, sym.other, s.Name)
   832  			}
   833  		}
   834  	}
   835  
   836  	// Sort outer lists by address, adding to textp.
   837  	// This keeps textp in increasing address order.
   838  	for i := 0; uint(i) < elfobj.nsect; i++ {
   839  		s = elfobj.sect[i].sym
   840  		if s == nil {
   841  			continue
   842  		}
   843  		if s.Sub != nil {
   844  			s.Sub = listsort(s.Sub, valuecmp, listsubp)
   845  		}
   846  		if s.Type == obj.STEXT {
   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  			for s = s.Sub; s != nil; s = s.Sub {
   853  				if s.Attr.OnList() {
   854  					log.Fatalf("symbol %s listed multiple times", s.Name)
   855  				}
   856  				s.Attr |= AttrOnList
   857  				Ctxt.Textp = append(Ctxt.Textp, s)
   858  			}
   859  		}
   860  	}
   861  
   862  	// load relocations
   863  	for i := 0; uint(i) < elfobj.nsect; i++ {
   864  		rsect = &elfobj.sect[i]
   865  		if rsect.type_ != ElfSectRela && rsect.type_ != ElfSectRel {
   866  			continue
   867  		}
   868  		if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil {
   869  			continue
   870  		}
   871  		sect = &elfobj.sect[rsect.info]
   872  		if err = elfmap(elfobj, rsect); err != nil {
   873  			goto bad
   874  		}
   875  		rela = 0
   876  		if rsect.type_ == ElfSectRela {
   877  			rela = 1
   878  		}
   879  		n = int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
   880  		r = make([]Reloc, n)
   881  		p = rsect.base
   882  		for j = 0; j < n; j++ {
   883  			add = 0
   884  			rp = &r[j]
   885  			if is64 != 0 {
   886  				// 64-bit rel/rela
   887  				rp.Off = int32(e.Uint64(p))
   888  
   889  				p = p[8:]
   890  				info = e.Uint64(p)
   891  				p = p[8:]
   892  				if rela != 0 {
   893  					add = e.Uint64(p)
   894  					p = p[8:]
   895  				}
   896  			} else {
   897  				// 32-bit rel/rela
   898  				rp.Off = int32(e.Uint32(p))
   899  
   900  				p = p[4:]
   901  				info = uint64(e.Uint32(p))
   902  				info = info>>8<<32 | info&0xff // convert to 64-bit info
   903  				p = p[4:]
   904  				if rela != 0 {
   905  					add = uint64(e.Uint32(p))
   906  					p = p[4:]
   907  				}
   908  			}
   909  
   910  			if info&0xffffffff == 0 { // skip R_*_NONE relocation
   911  				j--
   912  				n--
   913  				continue
   914  			}
   915  
   916  			if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol
   917  				rp.Sym = nil
   918  			} else {
   919  				if err = readelfsym(elfobj, int(info>>32), &sym, 0); err != nil {
   920  					goto bad
   921  				}
   922  				sym.sym = symbols[info>>32]
   923  				if sym.sym == nil {
   924  					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_)
   925  					goto bad
   926  				}
   927  
   928  				rp.Sym = sym.sym
   929  			}
   930  
   931  			rp.Type = 256 + int32(info)
   932  			rp.Siz = relSize(pn, uint32(info))
   933  			if rela != 0 {
   934  				rp.Add = int64(add)
   935  			} else {
   936  				// load addend from image
   937  				if rp.Siz == 4 {
   938  					rp.Add = int64(e.Uint32(sect.base[rp.Off:]))
   939  				} else if rp.Siz == 8 {
   940  					rp.Add = int64(e.Uint64(sect.base[rp.Off:]))
   941  				} else {
   942  					Diag("invalid rela size %d", rp.Siz)
   943  				}
   944  			}
   945  
   946  			if rp.Siz == 2 {
   947  				rp.Add = int64(int16(rp.Add))
   948  			}
   949  			if rp.Siz == 4 {
   950  				rp.Add = int64(int32(rp.Add))
   951  			}
   952  		}
   953  
   954  		//print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add);
   955  		sort.Sort(rbyoff(r[:n]))
   956  		// just in case
   957  
   958  		s = sect.sym
   959  		s.R = r
   960  		s.R = s.R[:n]
   961  	}
   962  
   963  	return
   964  
   965  bad:
   966  	Diag("%s: malformed elf file: %v", pn, err)
   967  }
   968  
   969  func section(elfobj *ElfObj, name string) *ElfSect {
   970  	for i := 0; uint(i) < elfobj.nsect; i++ {
   971  		if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name {
   972  			return &elfobj.sect[i]
   973  		}
   974  	}
   975  	return nil
   976  }
   977  
   978  func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
   979  	if sect.base != nil {
   980  		return nil
   981  	}
   982  
   983  	if sect.off+sect.size > uint64(elfobj.length) {
   984  		err = fmt.Errorf("elf section past end of file")
   985  		return err
   986  	}
   987  
   988  	sect.base = make([]byte, sect.size)
   989  	if elfobj.f.Seek(int64(uint64(elfobj.base)+sect.off), 0) < 0 {
   990  		return fmt.Errorf("short read: seek not successful")
   991  	}
   992  	if _, err := io.ReadFull(elfobj.f, sect.base); err != nil {
   993  		return fmt.Errorf("short read: %v", err)
   994  	}
   995  
   996  	return nil
   997  }
   998  
   999  func readelfsym(elfobj *ElfObj, i int, sym *ElfSym, needSym int) (err error) {
  1000  	if i >= elfobj.nsymtab || i < 0 {
  1001  		err = fmt.Errorf("invalid elf symbol index")
  1002  		return err
  1003  	}
  1004  
  1005  	if i == 0 {
  1006  		Diag("readym: read null symbol!")
  1007  	}
  1008  
  1009  	if elfobj.is64 != 0 {
  1010  		b := new(ElfSymBytes64)
  1011  		binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF64SYMSIZE:(i+1)*ELF64SYMSIZE]), elfobj.e, b)
  1012  		sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
  1013  		sym.value = elfobj.e.Uint64(b.Value[:])
  1014  		sym.size = elfobj.e.Uint64(b.Size[:])
  1015  		sym.shndx = elfobj.e.Uint16(b.Shndx[:])
  1016  		sym.bind = b.Info >> 4
  1017  		sym.type_ = b.Info & 0xf
  1018  		sym.other = b.Other
  1019  	} else {
  1020  		b := new(ElfSymBytes)
  1021  		binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF32SYMSIZE:(i+1)*ELF32SYMSIZE]), elfobj.e, b)
  1022  		sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
  1023  		sym.value = uint64(elfobj.e.Uint32(b.Value[:]))
  1024  		sym.size = uint64(elfobj.e.Uint32(b.Size[:]))
  1025  		sym.shndx = elfobj.e.Uint16(b.Shndx[:])
  1026  		sym.bind = b.Info >> 4
  1027  		sym.type_ = b.Info & 0xf
  1028  		sym.other = b.Other
  1029  	}
  1030  
  1031  	var s *LSym
  1032  	if sym.name == "_GLOBAL_OFFSET_TABLE_" {
  1033  		sym.name = ".got"
  1034  	}
  1035  	if sym.name == ".TOC." {
  1036  		// Magic symbol on ppc64.  Will be set to this object
  1037  		// file's .got+0x8000.
  1038  		sym.bind = ElfSymBindLocal
  1039  	}
  1040  
  1041  	switch sym.type_ {
  1042  	case ElfSymTypeSection:
  1043  		s = elfobj.sect[sym.shndx].sym
  1044  
  1045  	case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone:
  1046  		switch sym.bind {
  1047  		case ElfSymBindGlobal:
  1048  			if needSym != 0 {
  1049  				s = Linklookup(Ctxt, sym.name, 0)
  1050  
  1051  				// for global scoped hidden symbols we should insert it into
  1052  				// symbol hash table, but mark them as hidden.
  1053  				// __i686.get_pc_thunk.bx is allowed to be duplicated, to
  1054  				// workaround that we set dupok.
  1055  				// TODO(minux): correctly handle __i686.get_pc_thunk.bx without
  1056  				// set dupok generally. See http://codereview.appspot.com/5823055/
  1057  				// comment #5 for details.
  1058  				if s != nil && sym.other == 2 {
  1059  					s.Type |= obj.SHIDDEN
  1060  					s.Attr |= AttrDuplicateOK
  1061  				}
  1062  			}
  1063  
  1064  		case ElfSymBindLocal:
  1065  			if SysArch.Family == sys.ARM && (strings.HasPrefix(sym.name, "$a") || strings.HasPrefix(sym.name, "$d")) {
  1066  				// binutils for arm generate these mapping
  1067  				// symbols, ignore these
  1068  				break
  1069  			}
  1070  
  1071  			if sym.name == ".TOC." {
  1072  				// We need to be able to look this up,
  1073  				// so put it in the hash table.
  1074  				if needSym != 0 {
  1075  					s = Linklookup(Ctxt, sym.name, Ctxt.Version)
  1076  					s.Type |= obj.SHIDDEN
  1077  				}
  1078  
  1079  				break
  1080  			}
  1081  
  1082  			if needSym != 0 {
  1083  				// local names and hidden global names are unique
  1084  				// and should only be referenced by their index, not name, so we
  1085  				// don't bother to add them into the hash table
  1086  				s = linknewsym(Ctxt, sym.name, Ctxt.Version)
  1087  
  1088  				s.Type |= obj.SHIDDEN
  1089  			}
  1090  
  1091  		case ElfSymBindWeak:
  1092  			if needSym != 0 {
  1093  				s = Linklookup(Ctxt, sym.name, 0)
  1094  				if sym.other == 2 {
  1095  					s.Type |= obj.SHIDDEN
  1096  				}
  1097  			}
  1098  
  1099  		default:
  1100  			err = fmt.Errorf("%s: invalid symbol binding %d", sym.name, sym.bind)
  1101  			return err
  1102  		}
  1103  	}
  1104  
  1105  	if s != nil && s.Type == 0 && sym.type_ != ElfSymTypeSection {
  1106  		s.Type = obj.SXREF
  1107  	}
  1108  	sym.sym = s
  1109  
  1110  	return nil
  1111  }
  1112  
  1113  type rbyoff []Reloc
  1114  
  1115  func (x rbyoff) Len() int {
  1116  	return len(x)
  1117  }
  1118  
  1119  func (x rbyoff) Swap(i, j int) {
  1120  	x[i], x[j] = x[j], x[i]
  1121  }
  1122  
  1123  func (x rbyoff) Less(i, j int) bool {
  1124  	a := &x[i]
  1125  	b := &x[j]
  1126  	if a.Off < b.Off {
  1127  		return true
  1128  	}
  1129  	if a.Off > b.Off {
  1130  		return false
  1131  	}
  1132  	return false
  1133  }
  1134  
  1135  func relSize(pn string, elftype uint32) uint8 {
  1136  	// TODO(mdempsky): Replace this with a struct-valued switch statement
  1137  	// once golang.org/issue/15164 is fixed or found to not impair cmd/link
  1138  	// performance.
  1139  
  1140  	const (
  1141  		AMD64   = uint32(sys.AMD64)
  1142  		ARM     = uint32(sys.ARM)
  1143  		I386    = uint32(sys.I386)
  1144  		PPC64   = uint32(sys.PPC64)
  1145  		S390X   = uint32(sys.S390X)
  1146  		SPARC64 = uint32(sys.SPARC64)
  1147  	)
  1148  
  1149  	switch uint32(SysArch.Family) | elftype<<24 {
  1150  	default:
  1151  		Diag("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
  1152  		fallthrough
  1153  
  1154  	case SPARC64 | R_SPARC_GOTDATA_OP<<24:
  1155  		// These are "special" and don't technically have a size.
  1156  		return 0
  1157  
  1158  	case SPARC64 | R_SPARC_8<<24,
  1159  		SPARC64 | R_SPARC_DISP8<<24:
  1160  		return 1
  1161  
  1162  	case SPARC64 | R_SPARC_16<<24,
  1163  		SPARC64 | R_SPARC_DISP16<<24,
  1164  		SPARC64 | R_SPARC_UA16<<24:
  1165  		return 2
  1166  
  1167  	case SPARC64 | R_SPARC_32<<24,
  1168  		SPARC64 | R_SPARC_DISP32<<24,
  1169  		SPARC64 | R_SPARC_WDISP30<<24,
  1170  		SPARC64 | R_SPARC_WDISP22<<24,
  1171  		SPARC64 | R_SPARC_HI22<<24,
  1172  		SPARC64 | R_SPARC_22<<24,
  1173  		SPARC64 | R_SPARC_13<<24,
  1174  		SPARC64 | R_SPARC_LO10<<24,
  1175  		SPARC64 | R_SPARC_GOT10<<24,
  1176  		SPARC64 | R_SPARC_GOT13<<24,
  1177  		SPARC64 | R_SPARC_GOT22<<24,
  1178  		SPARC64 | R_SPARC_PC10<<24,
  1179  		SPARC64 | R_SPARC_PC22<<24,
  1180  		SPARC64 | R_SPARC_WPLT30<<24,
  1181  		SPARC64 | R_SPARC_UA32<<24,
  1182  		SPARC64 | R_SPARC_PLT32<<24,
  1183  		SPARC64 | R_SPARC_HIPLT22<<24,
  1184  		SPARC64 | R_SPARC_LOPLT10<<24,
  1185  		SPARC64 | R_SPARC_PCPLT32<<24,
  1186  		SPARC64 | R_SPARC_PCPLT22<<24,
  1187  		SPARC64 | R_SPARC_PCPLT10<<24,
  1188  		SPARC64 | R_SPARC_10<<24,
  1189  		SPARC64 | R_SPARC_11<<24,
  1190  		SPARC64 | R_SPARC_OLO10<<24,
  1191  		SPARC64 | R_SPARC_HH22<<24,
  1192  		SPARC64 | R_SPARC_HM10<<24,
  1193  		SPARC64 | R_SPARC_LM22<<24,
  1194  		SPARC64 | R_SPARC_PC_HH22<<24,
  1195  		SPARC64 | R_SPARC_PC_HM10<<24,
  1196  		SPARC64 | R_SPARC_PC_LM22<<24,
  1197  		SPARC64 | R_SPARC_WDISP16<<24,
  1198  		SPARC64 | R_SPARC_WDISP19<<24,
  1199  		SPARC64 | R_SPARC_7<<24,
  1200  		SPARC64 | R_SPARC_5<<24,
  1201  		SPARC64 | R_SPARC_6<<24,
  1202  		SPARC64 | R_SPARC_HIX22<<24,
  1203  		SPARC64 | R_SPARC_LOX10<<24,
  1204  		SPARC64 | R_SPARC_H44<<24,
  1205  		SPARC64 | R_SPARC_M44<<24,
  1206  		SPARC64 | R_SPARC_L44<<24,
  1207  		SPARC64 | R_SPARC_TLS_GD_HI22<<24,
  1208  		SPARC64 | R_SPARC_TLS_GD_LO10<<24,
  1209  		SPARC64 | R_SPARC_TLS_LDM_HI22<<24,
  1210  		SPARC64 | R_SPARC_TLS_LDM_LO10<<24,
  1211  		SPARC64 | R_SPARC_TLS_LDO_HIX22<<24,
  1212  		SPARC64 | R_SPARC_TLS_LDO_LOX10<<24,
  1213  		SPARC64 | R_SPARC_TLS_IE_HI22<<24,
  1214  		SPARC64 | R_SPARC_TLS_IE_LO10<<24,
  1215  		SPARC64 | R_SPARC_TLS_LE_HIX22<<24,
  1216  		SPARC64 | R_SPARC_TLS_LE_LOX10<<24,
  1217  		SPARC64 | R_SPARC_TLS_DTPMOD32<<24,
  1218  		SPARC64 | R_SPARC_TLS_DTPOFF32<<24,
  1219  		SPARC64 | R_SPARC_TLS_TPOFF32<<24,
  1220  		SPARC64 | R_SPARC_GOTDATA_HIX22<<24,
  1221  		SPARC64 | R_SPARC_GOTDATA_LOX10<<24,
  1222  		SPARC64 | R_SPARC_GOTDATA_OP_HIX22<<24,
  1223  		SPARC64 | R_SPARC_GOTDATA_OP_LOX10<<24,
  1224  		SPARC64 | R_SPARC_H34<<24,
  1225  		SPARC64 | R_SPARC_SIZE32<<24,
  1226  		SPARC64 | R_SPARC_WDISP10<<24:
  1227  		return 4
  1228  
  1229  	case SPARC64 | R_SPARC_GLOB_DAT<<24,
  1230  		SPARC64 | R_SPARC_RELATIVE<<24,
  1231  		SPARC64 | R_SPARC_64<<24,
  1232  		SPARC64 | R_SPARC_DISP64<<24,
  1233  		SPARC64 | R_SPARC_PLT64<<24,
  1234  		SPARC64 | R_SPARC_UA64<<24,
  1235  		SPARC64 | R_SPARC_TLS_DTPMOD64<<24,
  1236  		SPARC64 | R_SPARC_TLS_DTPOFF64<<24,
  1237  		SPARC64 | R_SPARC_TLS_TPOFF64<<24,
  1238  		SPARC64 | R_SPARC_SIZE64<<24:
  1239  		return 8
  1240  
  1241  	case S390X | R_390_8<<24:
  1242  		return 1
  1243  
  1244  	case PPC64 | R_PPC64_TOC16<<24,
  1245  		PPC64 | R_PPC64_TOC16_LO<<24,
  1246  		PPC64 | R_PPC64_TOC16_HI<<24,
  1247  		PPC64 | R_PPC64_TOC16_HA<<24,
  1248  		PPC64 | R_PPC64_TOC16_DS<<24,
  1249  		PPC64 | R_PPC64_TOC16_LO_DS<<24,
  1250  		PPC64 | R_PPC64_REL16_LO<<24,
  1251  		PPC64 | R_PPC64_REL16_HI<<24,
  1252  		PPC64 | R_PPC64_REL16_HA<<24,
  1253  		S390X | R_390_16<<24,
  1254  		S390X | R_390_GOT16<<24,
  1255  		S390X | R_390_PC16<<24,
  1256  		S390X | R_390_PC16DBL<<24,
  1257  		S390X | R_390_PLT16DBL<<24:
  1258  		return 2
  1259  
  1260  	case ARM | R_ARM_ABS32<<24,
  1261  		ARM | R_ARM_GOT32<<24,
  1262  		ARM | R_ARM_PLT32<<24,
  1263  		ARM | R_ARM_GOTOFF<<24,
  1264  		ARM | R_ARM_GOTPC<<24,
  1265  		ARM | R_ARM_THM_PC22<<24,
  1266  		ARM | R_ARM_REL32<<24,
  1267  		ARM | R_ARM_CALL<<24,
  1268  		ARM | R_ARM_V4BX<<24,
  1269  		ARM | R_ARM_GOT_PREL<<24,
  1270  		ARM | R_ARM_PC24<<24,
  1271  		ARM | R_ARM_JUMP24<<24,
  1272  		AMD64 | R_X86_64_PC32<<24,
  1273  		AMD64 | R_X86_64_PLT32<<24,
  1274  		AMD64 | R_X86_64_GOTPCREL<<24,
  1275  		AMD64 | R_X86_64_GOTPCRELX<<24,
  1276  		AMD64 | R_X86_64_REX_GOTPCRELX<<24,
  1277  		I386 | R_386_32<<24,
  1278  		I386 | R_386_PC32<<24,
  1279  		I386 | R_386_GOT32<<24,
  1280  		I386 | R_386_PLT32<<24,
  1281  		I386 | R_386_GOTOFF<<24,
  1282  		I386 | R_386_GOTPC<<24,
  1283  		I386 | R_386_GOT32X<<24,
  1284  		PPC64 | R_PPC64_REL24<<24,
  1285  		PPC64 | R_PPC_REL32<<24,
  1286  		S390X | R_390_32<<24,
  1287  		S390X | R_390_PC32<<24,
  1288  		S390X | R_390_GOT32<<24,
  1289  		S390X | R_390_PLT32<<24,
  1290  		S390X | R_390_PC32DBL<<24,
  1291  		S390X | R_390_PLT32DBL<<24,
  1292  		S390X | R_390_GOTPCDBL<<24,
  1293  		S390X | R_390_GOTENT<<24:
  1294  		return 4
  1295  
  1296  	case AMD64 | R_X86_64_64<<24,
  1297  		PPC64 | R_PPC64_ADDR64<<24,
  1298  		S390X | R_390_GLOB_DAT<<24,
  1299  		S390X | R_390_RELATIVE<<24,
  1300  		S390X | R_390_GOTOFF<<24,
  1301  		S390X | R_390_GOTPC<<24,
  1302  		S390X | R_390_64<<24,
  1303  		S390X | R_390_PC64<<24,
  1304  		S390X | R_390_GOT64<<24,
  1305  		S390X | R_390_PLT64<<24:
  1306  		return 8
  1307  	}
  1308  }