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