github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/src/cmd/link/internal/ld/ldelf.go (about)

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