// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package loadelf implements an ELF file reader.
package loadelf

import (
	"bytes"
	"cmd/internal/bio"
	"cmd/internal/objabi"
	"cmd/internal/sys"
	"cmd/link/internal/sym"
	"debug/elf"
	"encoding/binary"
	"fmt"
	"io"
	"log"
	"sort"
	"strings"
)

/*
Derived from Plan 9 from User Space's src/libmach/elf.h, elf.c
http://code.swtch.com/plan9port/src/tip/src/libmach/

	Copyright © 2004 Russ Cox.
	Portions Copyright © 2008-2010 Google Inc.
	Portions Copyright © 2010 The Go Authors.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
const (
	ElfClassNone = 0
	ElfClass32   = 1
	ElfClass64   = 2
)

const (
	ElfDataNone = 0
	ElfDataLsb  = 1
	ElfDataMsb  = 2
)

const (
	ElfTypeNone         = 0
	ElfTypeRelocatable  = 1
	ElfTypeExecutable   = 2
	ElfTypeSharedObject = 3
	ElfTypeCore         = 4
)

const (
	ElfMachNone        = 0
	ElfMach32100       = 1
	ElfMachSparc       = 2
	ElfMach386         = 3
	ElfMach68000       = 4
	ElfMach88000       = 5
	ElfMach486         = 6
	ElfMach860         = 7
	ElfMachMips        = 8
	ElfMachS370        = 9
	ElfMachMipsLe      = 10
	ElfMachParisc      = 15
	ElfMachVpp500      = 17
	ElfMachSparc32Plus = 18
	ElfMach960         = 19
	ElfMachPower       = 20
	ElfMachPower64     = 21
	ElfMachS390        = 22
	ElfMachV800        = 36
	ElfMachFr20        = 37
	ElfMachRh32        = 38
	ElfMachRce         = 39
	ElfMachArm         = 40
	ElfMachAlpha       = 41
	ElfMachSH          = 42
	ElfMachSparc9      = 43
	ElfMachAmd64       = 62
	ElfMachArm64       = 183
)

const (
	ElfAbiNone     = 0
	ElfAbiSystemV  = 0
	ElfAbiHPUX     = 1
	ElfAbiNetBSD   = 2
	ElfAbiLinux    = 3
	ElfAbiSolaris  = 6
	ElfAbiAix      = 7
	ElfAbiIrix     = 8
	ElfAbiFreeBSD  = 9
	ElfAbiTru64    = 10
	ElfAbiModesto  = 11
	ElfAbiOpenBSD  = 12
	ElfAbiARM      = 97
	ElfAbiEmbedded = 255
)

const (
	ElfSectNone      = 0
	ElfSectProgbits  = 1
	ElfSectSymtab    = 2
	ElfSectStrtab    = 3
	ElfSectRela      = 4
	ElfSectHash      = 5
	ElfSectDynamic   = 6
	ElfSectNote      = 7
	ElfSectNobits    = 8
	ElfSectRel       = 9
	ElfSectShlib     = 10
	ElfSectDynsym    = 11
	ElfSectFlagWrite = 0x1
	ElfSectFlagAlloc = 0x2
	ElfSectFlagExec  = 0x4
)

const (
	ElfSymBindLocal  = 0
	ElfSymBindGlobal = 1
	ElfSymBindWeak   = 2
)

const (
	ElfSymTypeNone    = 0
	ElfSymTypeObject  = 1
	ElfSymTypeFunc    = 2
	ElfSymTypeSection = 3
	ElfSymTypeFile    = 4
	ElfSymTypeCommon  = 5
	ElfSymTypeTLS     = 6
)

const (
	ElfSymShnNone   = 0
	ElfSymShnAbs    = 0xFFF1
	ElfSymShnCommon = 0xFFF2
)

const (
	ElfProgNone      = 0
	ElfProgLoad      = 1
	ElfProgDynamic   = 2
	ElfProgInterp    = 3
	ElfProgNote      = 4
	ElfProgShlib     = 5
	ElfProgPhdr      = 6
	ElfProgFlagExec  = 0x1
	ElfProgFlagWrite = 0x2
	ElfProgFlagRead  = 0x4
)

const (
	ElfNotePrStatus     = 1
	ElfNotePrFpreg      = 2
	ElfNotePrPsinfo     = 3
	ElfNotePrTaskstruct = 4
	ElfNotePrAuxv       = 6
	ElfNotePrXfpreg     = 0x46e62b7f
)

// TODO(crawshaw): de-duplicate with cmd/link/internal/ld/elf.go.
const (
	ELF64SYMSIZE = 24
	ELF32SYMSIZE = 16

	SHT_ARM_ATTRIBUTES = 0x70000003
)

type ElfHdrBytes struct {
	Ident     [16]uint8
	Type      [2]uint8
	Machine   [2]uint8
	Version   [4]uint8
	Entry     [4]uint8
	Phoff     [4]uint8
	Shoff     [4]uint8
	Flags     [4]uint8
	Ehsize    [2]uint8
	Phentsize [2]uint8
	Phnum     [2]uint8
	Shentsize [2]uint8
	Shnum     [2]uint8
	Shstrndx  [2]uint8
}

type ElfSectBytes struct {
	Name    [4]uint8
	Type    [4]uint8
	Flags   [4]uint8
	Addr    [4]uint8
	Off     [4]uint8
	Size    [4]uint8
	Link    [4]uint8
	Info    [4]uint8
	Align   [4]uint8
	Entsize [4]uint8
}

type ElfProgBytes struct {
}

type ElfSymBytes struct {
	Name  [4]uint8
	Value [4]uint8
	Size  [4]uint8
	Info  uint8
	Other uint8
	Shndx [2]uint8
}

type ElfHdrBytes64 struct {
	Ident     [16]uint8
	Type      [2]uint8
	Machine   [2]uint8
	Version   [4]uint8
	Entry     [8]uint8
	Phoff     [8]uint8
	Shoff     [8]uint8
	Flags     [4]uint8
	Ehsize    [2]uint8
	Phentsize [2]uint8
	Phnum     [2]uint8
	Shentsize [2]uint8
	Shnum     [2]uint8
	Shstrndx  [2]uint8
}

type ElfSectBytes64 struct {
	Name    [4]uint8
	Type    [4]uint8
	Flags   [8]uint8
	Addr    [8]uint8
	Off     [8]uint8
	Size    [8]uint8
	Link    [4]uint8
	Info    [4]uint8
	Align   [8]uint8
	Entsize [8]uint8
}

type ElfProgBytes64 struct {
}

type ElfSymBytes64 struct {
	Name  [4]uint8
	Info  uint8
	Other uint8
	Shndx [2]uint8
	Value [8]uint8
	Size  [8]uint8
}

type ElfSect struct {
	name    string
	nameoff uint32
	type_   uint32
	flags   uint64
	addr    uint64
	off     uint64
	size    uint64
	link    uint32
	info    uint32
	align   uint64
	entsize uint64
	base    []byte
	sym     *sym.Symbol
}

type ElfObj struct {
	f         *bio.Reader
	base      int64 // offset in f where ELF begins
	length    int64 // length of ELF
	is64      int
	name      string
	e         binary.ByteOrder
	sect      []ElfSect
	nsect     uint
	nsymtab   int
	symtab    *ElfSect
	symstr    *ElfSect
	type_     uint32
	machine   uint32
	version   uint32
	entry     uint64
	phoff     uint64
	shoff     uint64
	flags     uint32
	ehsize    uint32
	phentsize uint32
	phnum     uint32
	shentsize uint32
	shnum     uint32
	shstrndx  uint32
}

type ElfSym struct {
	name  string
	value uint64
	size  uint64
	bind  uint8
	type_ uint8
	other uint8
	shndx uint16
	sym   *sym.Symbol
}

var ElfMagic = [4]uint8{0x7F, 'E', 'L', 'F'}

const (
	TagFile               = 1
	TagCPUName            = 4
	TagCPURawName         = 5
	TagCompatibility      = 32
	TagNoDefaults         = 64
	TagAlsoCompatibleWith = 65
	TagABIVFPArgs         = 28
)

type elfAttribute struct {
	tag  uint64
	sval string
	ival uint64
}

type elfAttributeList struct {
	data []byte
	err  error
}

func (a *elfAttributeList) string() string {
	if a.err != nil {
		return ""
	}
	nul := bytes.IndexByte(a.data, 0)
	if nul < 0 {
		a.err = io.EOF
		return ""
	}
	s := string(a.data[:nul])
	a.data = a.data[nul+1:]
	return s
}

func (a *elfAttributeList) uleb128() uint64 {
	if a.err != nil {
		return 0
	}
	v, size := binary.Uvarint(a.data)
	a.data = a.data[size:]
	return v
}

// Read an elfAttribute from the list following the rules used on ARM systems.
func (a *elfAttributeList) armAttr() elfAttribute {
	attr := elfAttribute{tag: a.uleb128()}
	switch {
	case attr.tag == TagCompatibility:
		attr.ival = a.uleb128()
		attr.sval = a.string()

	case attr.tag == 64: // Tag_nodefaults has no argument

	case attr.tag == 65: // Tag_also_compatible_with
		// Not really, but we don't actually care about this tag.
		attr.sval = a.string()

	// Tag with string argument
	case attr.tag == TagCPUName || attr.tag == TagCPURawName || (attr.tag >= 32 && attr.tag&1 != 0):
		attr.sval = a.string()

	default: // Tag with integer argument
		attr.ival = a.uleb128()
	}
	return attr
}

func (a *elfAttributeList) done() bool {
	if a.err != nil || len(a.data) == 0 {
		return true
	}
	return false
}

// Look for the attribute that indicates the object uses the hard-float ABI (a
// file-level attribute with tag Tag_VFP_arch and value 1). Unfortunately the
// format used means that we have to parse all of the file-level attributes to
// find the one we are looking for. This format is slightly documented in "ELF
// for the ARM Architecture" but mostly this is derived from reading the source
// to gold and readelf.
func parseArmAttributes(e binary.ByteOrder, data []byte) (found bool, ehdrFlags uint32, err error) {
	found = false
	if data[0] != 'A' {
		return false, 0, fmt.Errorf(".ARM.attributes has unexpected format %c\n", data[0])
	}
	data = data[1:]
	for len(data) != 0 {
		sectionlength := e.Uint32(data)
		sectiondata := data[4:sectionlength]
		data = data[sectionlength:]

		nulIndex := bytes.IndexByte(sectiondata, 0)
		if nulIndex < 0 {
			return false, 0, fmt.Errorf("corrupt .ARM.attributes (section name not NUL-terminated)\n")
		}
		name := string(sectiondata[:nulIndex])
		sectiondata = sectiondata[nulIndex+1:]

		if name != "aeabi" {
			continue
		}
		for len(sectiondata) != 0 {
			subsectiontag, sz := binary.Uvarint(sectiondata)
			subsectionsize := e.Uint32(sectiondata[sz:])
			subsectiondata := sectiondata[sz+4 : subsectionsize]
			sectiondata = sectiondata[subsectionsize:]

			if subsectiontag != TagFile {
				continue
			}
			attrList := elfAttributeList{data: subsectiondata}
			for !attrList.done() {
				attr := attrList.armAttr()
				if attr.tag == TagABIVFPArgs && attr.ival == 1 {
					found = true
					ehdrFlags = 0x5000402 // has entry point, Version5 EABI, hard-float ABI
				}
			}
			if attrList.err != nil {
				return false, 0, fmt.Errorf("could not parse .ARM.attributes\n")
			}
		}
	}
	return found, ehdrFlags, nil
}

// Load loads the ELF file pn from f.
// Symbols are written into syms, and a slice of the text symbols is returned.
//
// On ARM systems, Load will attempt to determine what ELF header flags to
// emit by scanning the attributes in the ELF file being loaded. The
// parameter initEhdrFlags contains the current header flags for the output
// object, and the returned ehdrFlags contains what this Load function computes.
// TODO: find a better place for this logic.
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) {
	errorf := func(str string, args ...interface{}) ([]*sym.Symbol, uint32, error) {
		return nil, 0, fmt.Errorf("loadelf: %s: %v", pn, fmt.Sprintf(str, args...))
	}

	localSymVersion := syms.IncVersion()
	base := f.Offset()

	var hdrbuf [64]uint8
	if _, err := io.ReadFull(f, hdrbuf[:]); err != nil {
		return errorf("malformed elf file: %v", err)
	}
	hdr := new(ElfHdrBytes)
	binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter
	if string(hdr.Ident[:4]) != "\x7FELF" {
		return errorf("malformed elf file, bad header")
	}
	var e binary.ByteOrder
	switch hdr.Ident[5] {
	case ElfDataLsb:
		e = binary.LittleEndian

	case ElfDataMsb:
		e = binary.BigEndian

	default:
		return errorf("malformed elf file, unknown header")
	}

	// read header
	elfobj := new(ElfObj)

	elfobj.e = e
	elfobj.f = f
	elfobj.base = base
	elfobj.length = length
	elfobj.name = pn

	is64 := 0
	if hdr.Ident[4] == ElfClass64 {
		is64 = 1
		hdr := new(ElfHdrBytes64)
		binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter
		elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
		elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
		elfobj.version = e.Uint32(hdr.Version[:])
		elfobj.phoff = e.Uint64(hdr.Phoff[:])
		elfobj.shoff = e.Uint64(hdr.Shoff[:])
		elfobj.flags = e.Uint32(hdr.Flags[:])
		elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:]))
		elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:]))
		elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:]))
		elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:]))
		elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:]))
		elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:]))
	} else {
		elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
		elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
		elfobj.version = e.Uint32(hdr.Version[:])
		elfobj.entry = uint64(e.Uint32(hdr.Entry[:]))
		elfobj.phoff = uint64(e.Uint32(hdr.Phoff[:]))
		elfobj.shoff = uint64(e.Uint32(hdr.Shoff[:]))
		elfobj.flags = e.Uint32(hdr.Flags[:])
		elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:]))
		elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:]))
		elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:]))
		elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:]))
		elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:]))
		elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:]))
	}

	elfobj.is64 = is64

	if v := uint32(hdr.Ident[6]); v != elfobj.version {
		return errorf("malformed elf version: got %d, want %d", v, elfobj.version)
	}

	if e.Uint16(hdr.Type[:]) != ElfTypeRelocatable {
		return errorf("elf but not elf relocatable object")
	}

	switch arch.Family {
	default:
		return errorf("elf %s unimplemented", arch.Name)

	case sys.MIPS:
		if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass32 {
			return errorf("elf object but not mips")
		}

	case sys.MIPS64:
		if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass64 {
			return errorf("elf object but not mips64")
		}

	case sys.ARM:
		if e != binary.LittleEndian || elfobj.machine != ElfMachArm || hdr.Ident[4] != ElfClass32 {
			return errorf("elf object but not arm")
		}

	case sys.AMD64:
		if e != binary.LittleEndian || elfobj.machine != ElfMachAmd64 || hdr.Ident[4] != ElfClass64 {
			return errorf("elf object but not amd64")
		}

	case sys.ARM64:
		if e != binary.LittleEndian || elfobj.machine != ElfMachArm64 || hdr.Ident[4] != ElfClass64 {
			return errorf("elf object but not arm64")
		}

	case sys.I386:
		if e != binary.LittleEndian || elfobj.machine != ElfMach386 || hdr.Ident[4] != ElfClass32 {
			return errorf("elf object but not 386")
		}

	case sys.PPC64:
		if elfobj.machine != ElfMachPower64 || hdr.Ident[4] != ElfClass64 {
			return errorf("elf object but not ppc64")
		}

	case sys.S390X:
		if elfobj.machine != ElfMachS390 || hdr.Ident[4] != ElfClass64 {
			return errorf("elf object but not s390x")
		}
	}

	// load section list into memory.
	elfobj.sect = make([]ElfSect, elfobj.shnum)

	elfobj.nsect = uint(elfobj.shnum)
	for i := 0; uint(i) < elfobj.nsect; i++ {
		if f.Seek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0) < 0 {
			return errorf("malformed elf file: negative seek")
		}
		sect := &elfobj.sect[i]
		if is64 != 0 {
			var b ElfSectBytes64

			if err := binary.Read(f, e, &b); err != nil {
				return errorf("malformed elf file: %v", err)
			}

			sect.nameoff = e.Uint32(b.Name[:])
			sect.type_ = e.Uint32(b.Type[:])
			sect.flags = e.Uint64(b.Flags[:])
			sect.addr = e.Uint64(b.Addr[:])
			sect.off = e.Uint64(b.Off[:])
			sect.size = e.Uint64(b.Size[:])
			sect.link = e.Uint32(b.Link[:])
			sect.info = e.Uint32(b.Info[:])
			sect.align = e.Uint64(b.Align[:])
			sect.entsize = e.Uint64(b.Entsize[:])
		} else {
			var b ElfSectBytes

			if err := binary.Read(f, e, &b); err != nil {
				return errorf("malformed elf file: %v", err)
			}

			sect.nameoff = e.Uint32(b.Name[:])
			sect.type_ = e.Uint32(b.Type[:])
			sect.flags = uint64(e.Uint32(b.Flags[:]))
			sect.addr = uint64(e.Uint32(b.Addr[:]))
			sect.off = uint64(e.Uint32(b.Off[:]))
			sect.size = uint64(e.Uint32(b.Size[:]))
			sect.link = e.Uint32(b.Link[:])
			sect.info = e.Uint32(b.Info[:])
			sect.align = uint64(e.Uint32(b.Align[:]))
			sect.entsize = uint64(e.Uint32(b.Entsize[:]))
		}
	}

	// read section string table and translate names
	if elfobj.shstrndx >= uint32(elfobj.nsect) {
		return errorf("malformed elf file: shstrndx out of range %d >= %d", elfobj.shstrndx, elfobj.nsect)
	}

	sect := &elfobj.sect[elfobj.shstrndx]
	if err := elfmap(elfobj, sect); err != nil {
		return errorf("malformed elf file: %v", err)
	}
	for i := 0; uint(i) < elfobj.nsect; i++ {
		if elfobj.sect[i].nameoff != 0 {
			elfobj.sect[i].name = cstring(sect.base[elfobj.sect[i].nameoff:])
		}
	}

	// load string table for symbols into memory.
	elfobj.symtab = section(elfobj, ".symtab")

	if elfobj.symtab == nil {
		// our work is done here - no symbols means nothing can refer to this file
		return
	}

	if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) {
		return errorf("elf object has symbol table with invalid string table link")
	}

	elfobj.symstr = &elfobj.sect[elfobj.symtab.link]
	if is64 != 0 {
		elfobj.nsymtab = int(elfobj.symtab.size / ELF64SYMSIZE)
	} else {
		elfobj.nsymtab = int(elfobj.symtab.size / ELF32SYMSIZE)
	}

	if err := elfmap(elfobj, elfobj.symtab); err != nil {
		return errorf("malformed elf file: %v", err)
	}
	if err := elfmap(elfobj, elfobj.symstr); err != nil {
		return errorf("malformed elf file: %v", err)
	}

	// load text and data segments into memory.
	// they are not as small as the section lists, but we'll need
	// the memory anyway for the symbol images, so we might
	// as well use one large chunk.

	// create symbols for elfmapped sections
	for i := 0; uint(i) < elfobj.nsect; i++ {
		sect = &elfobj.sect[i]
		if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" {
			if err := elfmap(elfobj, sect); err != nil {
				return errorf("%s: malformed elf file: %v", pn, err)
			}
			// We assume the soft-float ABI unless we see a tag indicating otherwise.
			if initEhdrFlags == 0x5000002 {
				ehdrFlags = 0x5000202
			} else {
				ehdrFlags = initEhdrFlags
			}
			found, newEhdrFlags, err := parseArmAttributes(e, sect.base[:sect.size])
			if err != nil {
				// TODO(dfc) should this return an error?
				log.Printf("%s: %v", pn, err)
			}
			if found {
				ehdrFlags = newEhdrFlags
			}
		}
		if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 {
			continue
		}
		if sect.type_ != ElfSectNobits {
			if err := elfmap(elfobj, sect); err != nil {
				return errorf("%s: malformed elf file: %v", pn, err)
			}
		}

		name := fmt.Sprintf("%s(%s)", pkg, sect.name)
		s := syms.Lookup(name, localSymVersion)

		switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) {
		default:
			return errorf("%s: unexpected flags for ELF section %s", pn, sect.name)

		case ElfSectFlagAlloc:
			s.Type = sym.SRODATA

		case ElfSectFlagAlloc + ElfSectFlagWrite:
			if sect.type_ == ElfSectNobits {
				s.Type = sym.SNOPTRBSS
			} else {
				s.Type = sym.SNOPTRDATA
			}

		case ElfSectFlagAlloc + ElfSectFlagExec:
			s.Type = sym.STEXT
		}

		if sect.name == ".got" || sect.name == ".toc" {
			s.Type = sym.SELFGOT
		}
		if sect.type_ == ElfSectProgbits {
			s.P = sect.base
			s.P = s.P[:sect.size]
		}

		s.Size = int64(sect.size)
		s.Align = int32(sect.align)
		sect.sym = s
	}

	// enter sub-symbols into symbol table.
	// symbol 0 is the null symbol.
	symbols := make([]*sym.Symbol, elfobj.nsymtab)

	for i := 1; i < elfobj.nsymtab; i++ {
		var elfsym ElfSym
		if err := readelfsym(arch, syms, elfobj, i, &elfsym, 1, localSymVersion); err != nil {
			return errorf("%s: malformed elf file: %v", pn, err)
		}
		symbols[i] = elfsym.sym
		if elfsym.type_ != ElfSymTypeFunc && elfsym.type_ != ElfSymTypeObject && elfsym.type_ != ElfSymTypeNone && elfsym.type_ != ElfSymTypeCommon {
			continue
		}
		if elfsym.shndx == ElfSymShnCommon || elfsym.type_ == ElfSymTypeCommon {
			s := elfsym.sym
			if uint64(s.Size) < elfsym.size {
				s.Size = int64(elfsym.size)
			}
			if s.Type == 0 || s.Type == sym.SXREF {
				s.Type = sym.SNOPTRBSS
			}
			continue
		}

		if uint(elfsym.shndx) >= elfobj.nsect || elfsym.shndx == 0 {
			continue
		}

		// even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols
		if elfsym.sym == nil {
			continue
		}
		sect = &elfobj.sect[elfsym.shndx]
		if sect.sym == nil {
			if strings.HasPrefix(elfsym.name, ".Linfo_string") { // clang does this
				continue
			}

			if elfsym.name == "" && elfsym.type_ == 0 && sect.name == ".debug_str" {
				// This reportedly happens with clang 3.7 on ARM.
				// See issue 13139.
				continue
			}

			if strings.HasPrefix(elfsym.name, ".LASF") { // gcc on s390x does this
				continue
			}
			return errorf("%v: sym#%d: ignoring symbol in section %d (type %d)", elfsym.sym, i, elfsym.shndx, elfsym.type_)
		}

		s := elfsym.sym
		if s.Outer != nil {
			if s.Attr.DuplicateOK() {
				continue
			}
			return errorf("duplicate symbol reference: %s in both %s and %s", s.Name, s.Outer.Name, sect.sym.Name)
		}

		s.Sub = sect.sym.Sub
		sect.sym.Sub = s
		s.Type = sect.sym.Type
		s.Attr |= sym.AttrSubSymbol
		if !s.Attr.CgoExportDynamic() {
			s.SetDynimplib("") // satisfy dynimport
		}
		s.Value = int64(elfsym.value)
		s.Size = int64(elfsym.size)
		s.Outer = sect.sym
		if sect.sym.Type == sym.STEXT {
			if s.Attr.External() && !s.Attr.DuplicateOK() {
				return errorf("%v: duplicate symbol definition", s)
			}
			s.Attr |= sym.AttrExternal
		}

		if elfobj.machine == ElfMachPower64 {
			flag := int(elfsym.other) >> 5
			if 2 <= flag && flag <= 6 {
				s.Localentry = 1 << uint(flag-2)
			} else if flag == 7 {
				return errorf("%v: invalid sym.other 0x%x", s, elfsym.other)
			}
		}
	}

	// Sort outer lists by address, adding to textp.
	// This keeps textp in increasing address order.
	for i := uint(0); i < elfobj.nsect; i++ {
		s := elfobj.sect[i].sym
		if s == nil {
			continue
		}
		if s.Sub != nil {
			s.Sub = sym.SortSub(s.Sub)
		}
		if s.Type == sym.STEXT {
			if s.Attr.OnList() {
				return errorf("symbol %s listed multiple times", s.Name)
			}
			s.Attr |= sym.AttrOnList
			textp = append(textp, s)
			for s = s.Sub; s != nil; s = s.Sub {
				if s.Attr.OnList() {
					return errorf("symbol %s listed multiple times", s.Name)
				}
				s.Attr |= sym.AttrOnList
				textp = append(textp, s)
			}
		}
	}

	// load relocations
	for i := uint(0); i < elfobj.nsect; i++ {
		rsect := &elfobj.sect[i]
		if rsect.type_ != ElfSectRela && rsect.type_ != ElfSectRel {
			continue
		}
		if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil {
			continue
		}
		sect = &elfobj.sect[rsect.info]
		if err := elfmap(elfobj, rsect); err != nil {
			return errorf("malformed elf file: %v", err)
		}
		rela := 0
		if rsect.type_ == ElfSectRela {
			rela = 1
		}
		n := int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
		r := make([]sym.Reloc, n)
		p := rsect.base
		for j := 0; j < n; j++ {
			var add uint64
			rp := &r[j]
			var info uint64
			if is64 != 0 {
				// 64-bit rel/rela
				rp.Off = int32(e.Uint64(p))

				p = p[8:]
				info = e.Uint64(p)
				p = p[8:]
				if rela != 0 {
					add = e.Uint64(p)
					p = p[8:]
				}
			} else {
				// 32-bit rel/rela
				rp.Off = int32(e.Uint32(p))

				p = p[4:]
				info = uint64(e.Uint32(p))
				info = info>>8<<32 | info&0xff // convert to 64-bit info
				p = p[4:]
				if rela != 0 {
					add = uint64(e.Uint32(p))
					p = p[4:]
				}
			}

			if info&0xffffffff == 0 { // skip R_*_NONE relocation
				j--
				n--
				continue
			}

			if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol
				rp.Sym = nil
			} else {
				var elfsym ElfSym
				if err := readelfsym(arch, syms, elfobj, int(info>>32), &elfsym, 0, 0); err != nil {
					return errorf("malformed elf file: %v", err)
				}
				elfsym.sym = symbols[info>>32]
				if elfsym.sym == nil {
					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_)
				}

				rp.Sym = elfsym.sym
			}

			rp.Type = 256 + objabi.RelocType(info)
			rp.Siz, err = relSize(arch, pn, uint32(info))
			if err != nil {
				return nil, 0, err
			}
			if rela != 0 {
				rp.Add = int64(add)
			} else {
				// load addend from image
				if rp.Siz == 4 {
					rp.Add = int64(e.Uint32(sect.base[rp.Off:]))
				} else if rp.Siz == 8 {
					rp.Add = int64(e.Uint64(sect.base[rp.Off:]))
				} else {
					return errorf("invalid rela size %d", rp.Siz)
				}
			}

			if rp.Siz == 2 {
				rp.Add = int64(int16(rp.Add))
			}
			if rp.Siz == 4 {
				rp.Add = int64(int32(rp.Add))
			}
		}

		//print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add);
		sort.Sort(sym.RelocByOff(r[:n]))
		// just in case

		s := sect.sym
		s.R = r
		s.R = s.R[:n]
	}

	return textp, ehdrFlags, nil
}

func section(elfobj *ElfObj, name string) *ElfSect {
	for i := 0; uint(i) < elfobj.nsect; i++ {
		if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name {
			return &elfobj.sect[i]
		}
	}
	return nil
}

func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
	if sect.base != nil {
		return nil
	}

	if sect.off+sect.size > uint64(elfobj.length) {
		err = fmt.Errorf("elf section past end of file")
		return err
	}

	sect.base = make([]byte, sect.size)
	if elfobj.f.Seek(int64(uint64(elfobj.base)+sect.off), 0) < 0 {
		return fmt.Errorf("short read: seek not successful")
	}
	if _, err := io.ReadFull(elfobj.f, sect.base); err != nil {
		return fmt.Errorf("short read: %v", err)
	}

	return nil
}

func readelfsym(arch *sys.Arch, syms *sym.Symbols, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, localSymVersion int) (err error) {
	if i >= elfobj.nsymtab || i < 0 {
		err = fmt.Errorf("invalid elf symbol index")
		return err
	}

	if i == 0 {
		return fmt.Errorf("readym: read null symbol!")
	}

	if elfobj.is64 != 0 {
		b := new(ElfSymBytes64)
		binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF64SYMSIZE:(i+1)*ELF64SYMSIZE]), elfobj.e, b)
		elfsym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
		elfsym.value = elfobj.e.Uint64(b.Value[:])
		elfsym.size = elfobj.e.Uint64(b.Size[:])
		elfsym.shndx = elfobj.e.Uint16(b.Shndx[:])
		elfsym.bind = b.Info >> 4
		elfsym.type_ = b.Info & 0xf
		elfsym.other = b.Other
	} else {
		b := new(ElfSymBytes)
		binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF32SYMSIZE:(i+1)*ELF32SYMSIZE]), elfobj.e, b)
		elfsym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
		elfsym.value = uint64(elfobj.e.Uint32(b.Value[:]))
		elfsym.size = uint64(elfobj.e.Uint32(b.Size[:]))
		elfsym.shndx = elfobj.e.Uint16(b.Shndx[:])
		elfsym.bind = b.Info >> 4
		elfsym.type_ = b.Info & 0xf
		elfsym.other = b.Other
	}

	var s *sym.Symbol
	if elfsym.name == "_GLOBAL_OFFSET_TABLE_" {
		elfsym.name = ".got"
	}
	if elfsym.name == ".TOC." {
		// Magic symbol on ppc64.  Will be set to this object
		// file's .got+0x8000.
		elfsym.bind = ElfSymBindLocal
	}

	switch elfsym.type_ {
	case ElfSymTypeSection:
		s = elfobj.sect[elfsym.shndx].sym

	case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone, ElfSymTypeCommon:
		switch elfsym.bind {
		case ElfSymBindGlobal:
			if needSym != 0 {
				s = syms.Lookup(elfsym.name, 0)

				// for global scoped hidden symbols we should insert it into
				// symbol hash table, but mark them as hidden.
				// __i686.get_pc_thunk.bx is allowed to be duplicated, to
				// workaround that we set dupok.
				// TODO(minux): correctly handle __i686.get_pc_thunk.bx without
				// set dupok generally. See https://golang.org/cl/5823055
				// comment #5 for details.
				if s != nil && elfsym.other == 2 {
					s.Attr |= sym.AttrDuplicateOK | sym.AttrVisibilityHidden
				}
			}

		case ElfSymBindLocal:
			if arch.Family == sys.ARM && (strings.HasPrefix(elfsym.name, "$a") || strings.HasPrefix(elfsym.name, "$d")) {
				// binutils for arm generate these mapping
				// symbols, ignore these
				break
			}

			if elfsym.name == ".TOC." {
				// We need to be able to look this up,
				// so put it in the hash table.
				if needSym != 0 {
					s = syms.Lookup(elfsym.name, localSymVersion)
					s.Attr |= sym.AttrVisibilityHidden
				}

				break
			}

			if needSym != 0 {
				// local names and hidden global names are unique
				// and should only be referenced by their index, not name, so we
				// don't bother to add them into the hash table
				s = syms.Newsym(elfsym.name, localSymVersion)

				s.Attr |= sym.AttrVisibilityHidden
			}

		case ElfSymBindWeak:
			if needSym != 0 {
				s = syms.Lookup(elfsym.name, 0)
				if elfsym.other == 2 {
					s.Attr |= sym.AttrVisibilityHidden
				}
			}

		default:
			err = fmt.Errorf("%s: invalid symbol binding %d", elfsym.name, elfsym.bind)
			return err
		}
	}

	// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
	// sense and should be removed when someone has thought about it properly.
	if s != nil && s.Type == 0 && !s.Attr.VisibilityHidden() && elfsym.type_ != ElfSymTypeSection {
		s.Type = sym.SXREF
	}
	elfsym.sym = s

	return nil
}

func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) {
	// TODO(mdempsky): Replace this with a struct-valued switch statement
	// once golang.org/issue/15164 is fixed or found to not impair cmd/link
	// performance.

	const (
		AMD64 = uint32(sys.AMD64)
		ARM   = uint32(sys.ARM)
		I386  = uint32(sys.I386)
		PPC64 = uint32(sys.PPC64)
		S390X = uint32(sys.S390X)
	)

	switch uint32(arch.Family) | elftype<<24 {
	default:
		return 0, fmt.Errorf("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)

	case S390X | uint32(elf.R_390_8)<<24:
		return 1, nil

	case PPC64 | uint32(elf.R_PPC64_TOC16)<<24,
		PPC64 | uint32(elf.R_PPC64_TOC16_LO)<<24,
		PPC64 | uint32(elf.R_PPC64_TOC16_HI)<<24,
		PPC64 | uint32(elf.R_PPC64_TOC16_HA)<<24,
		PPC64 | uint32(elf.R_PPC64_TOC16_DS)<<24,
		PPC64 | uint32(elf.R_PPC64_TOC16_LO_DS)<<24,
		PPC64 | uint32(elf.R_PPC64_REL16_LO)<<24,
		PPC64 | uint32(elf.R_PPC64_REL16_HI)<<24,
		PPC64 | uint32(elf.R_PPC64_REL16_HA)<<24,
		S390X | uint32(elf.R_390_16)<<24,
		S390X | uint32(elf.R_390_GOT16)<<24,
		S390X | uint32(elf.R_390_PC16)<<24,
		S390X | uint32(elf.R_390_PC16DBL)<<24,
		S390X | uint32(elf.R_390_PLT16DBL)<<24:
		return 2, nil

	case ARM | uint32(elf.R_ARM_ABS32)<<24,
		ARM | uint32(elf.R_ARM_GOT32)<<24,
		ARM | uint32(elf.R_ARM_PLT32)<<24,
		ARM | uint32(elf.R_ARM_GOTOFF)<<24,
		ARM | uint32(elf.R_ARM_GOTPC)<<24,
		ARM | uint32(elf.R_ARM_THM_PC22)<<24,
		ARM | uint32(elf.R_ARM_REL32)<<24,
		ARM | uint32(elf.R_ARM_CALL)<<24,
		ARM | uint32(elf.R_ARM_V4BX)<<24,
		ARM | uint32(elf.R_ARM_GOT_PREL)<<24,
		ARM | uint32(elf.R_ARM_PC24)<<24,
		ARM | uint32(elf.R_ARM_JUMP24)<<24,
		AMD64 | uint32(elf.R_X86_64_PC32)<<24,
		AMD64 | uint32(elf.R_X86_64_PLT32)<<24,
		AMD64 | uint32(elf.R_X86_64_GOTPCREL)<<24,
		AMD64 | uint32(elf.R_X86_64_GOTPCRELX)<<24,
		AMD64 | uint32(elf.R_X86_64_REX_GOTPCRELX)<<24,
		I386 | uint32(elf.R_386_32)<<24,
		I386 | uint32(elf.R_386_PC32)<<24,
		I386 | uint32(elf.R_386_GOT32)<<24,
		I386 | uint32(elf.R_386_PLT32)<<24,
		I386 | uint32(elf.R_386_GOTOFF)<<24,
		I386 | uint32(elf.R_386_GOTPC)<<24,
		I386 | uint32(elf.R_386_GOT32X)<<24,
		PPC64 | uint32(elf.R_PPC64_REL24)<<24,
		PPC64 | uint32(elf.R_PPC_REL32)<<24,
		S390X | uint32(elf.R_390_32)<<24,
		S390X | uint32(elf.R_390_PC32)<<24,
		S390X | uint32(elf.R_390_GOT32)<<24,
		S390X | uint32(elf.R_390_PLT32)<<24,
		S390X | uint32(elf.R_390_PC32DBL)<<24,
		S390X | uint32(elf.R_390_PLT32DBL)<<24,
		S390X | uint32(elf.R_390_GOTPCDBL)<<24,
		S390X | uint32(elf.R_390_GOTENT)<<24:
		return 4, nil

	case AMD64 | uint32(elf.R_X86_64_64)<<24,
		AMD64 | uint32(elf.R_X86_64_PC64)<<24,
		PPC64 | uint32(elf.R_PPC64_ADDR64)<<24,
		S390X | uint32(elf.R_390_GLOB_DAT)<<24,
		S390X | uint32(elf.R_390_RELATIVE)<<24,
		S390X | uint32(elf.R_390_GOTOFF)<<24,
		S390X | uint32(elf.R_390_GOTPC)<<24,
		S390X | uint32(elf.R_390_64)<<24,
		S390X | uint32(elf.R_390_PC64)<<24,
		S390X | uint32(elf.R_390_GOT64)<<24,
		S390X | uint32(elf.R_390_PLT64)<<24:
		return 8, nil
	}
}

func cstring(x []byte) string {
	i := bytes.IndexByte(x, '\x00')
	if i >= 0 {
		x = x[:i]
	}
	return string(x)
}
