github.com/stingnevermore/go@v0.0.0-20180120041312-3810f5bfed72/src/cmd/link/internal/loadelf/ldelf.go (about)

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