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