package ld

import (
	"bytes"
	"cmd/internal/bio"
	"cmd/internal/obj"
	"cmd/internal/sys"
	"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
)

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     *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
	shstrtab  string
	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   *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(ctxt *Link, e binary.ByteOrder, data []byte) {
	// We assume the soft-float ABI unless we see a tag indicating otherwise.
	if ehdr.flags == 0x5000002 {
		ehdr.flags = 0x5000202
	}
	if data[0] != 'A' {
		// TODO(dfc) should this be ctxt.Diag ?
		ctxt.Logf(".ARM.attributes has unexpected format %c\n", data[0])
		return
	}
	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 {
			// TODO(dfc) should this be ctxt.Diag ?
			ctxt.Logf("corrupt .ARM.attributes (section name not NUL-terminated)\n")
			return
		}
		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 {
				attrList := elfAttributeList{data: subsectiondata}
				for !attrList.done() {
					attr := attrList.armAttr()
					if attr.tag == TagABIVFPArgs && attr.ival == 1 {
						ehdr.flags = 0x5000402 // has entry point, Version5 EABI, hard-float ABI
					}
				}
				if attrList.err != nil {
					// TODO(dfc) should this be ctxt.Diag ?
					ctxt.Logf("could not parse .ARM.attributes\n")
				}
			}
		}
	}
}

func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
	if ctxt.Debugvlog != 0 {
		ctxt.Logf("%5.2f ldelf %s\n", obj.Cputime(), pn)
	}

	localSymVersion := ctxt.Syms.IncVersion()
	base := f.Offset()

	var add uint64
	var e binary.ByteOrder
	var elfobj *ElfObj
	var err error
	var flag int
	var hdr *ElfHdrBytes
	var hdrbuf [64]uint8
	var info uint64
	var is64 int
	var j int
	var n int
	var name string
	var p []byte
	var r []Reloc
	var rela int
	var rp *Reloc
	var rsect *ElfSect
	var s *Symbol
	var sect *ElfSect
	var sym ElfSym
	var symbols []*Symbol
	if _, err := io.ReadFull(f, hdrbuf[:]); err != nil {
		goto bad
	}
	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" {
		goto bad
	}
	switch hdr.Ident[5] {
	case ElfDataLsb:
		e = binary.LittleEndian

	case ElfDataMsb:
		e = binary.BigEndian

	default:
		goto bad
	}

	// 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 uint32(hdr.Ident[6]) != elfobj.version {
		goto bad
	}

	if e.Uint16(hdr.Type[:]) != ElfTypeRelocatable {
		Errorf(nil, "%s: elf but not elf relocatable object", pn)
		return
	}

	switch SysArch.Family {
	default:
		Errorf(nil, "%s: elf %s unimplemented", pn, SysArch.Name)
		return

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

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

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

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

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

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

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

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

	// 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 {
			goto bad
		}
		sect = &elfobj.sect[i]
		if is64 != 0 {
			var b ElfSectBytes64

			if err = binary.Read(f, e, &b); err != nil {
				goto bad
			}

			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 {
				goto bad
			}

			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) {
		err = fmt.Errorf("shstrndx out of range %d >= %d", elfobj.shstrndx, elfobj.nsect)
		goto bad
	}

	sect = &elfobj.sect[elfobj.shstrndx]
	if err = elfmap(elfobj, sect); err != nil {
		goto bad
	}
	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) {
		Errorf(nil, "%s: elf object has symbol table with invalid string table link", pn)
		return
	}

	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 {
		goto bad
	}
	if err = elfmap(elfobj, elfobj.symstr); err != nil {
		goto bad
	}

	// 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 {
				goto bad
			}
			parseArmAttributes(ctxt, e, sect.base[:sect.size])
		}
		if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 {
			continue
		}
		if sect.type_ != ElfSectNobits {
			if err = elfmap(elfobj, sect); err != nil {
				goto bad
			}
		}

		name = fmt.Sprintf("%s(%s)", pkg, sect.name)
		s = ctxt.Syms.Lookup(name, localSymVersion)

		switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) {
		default:
			err = fmt.Errorf("unexpected flags for ELF section %s", sect.name)
			goto bad

		case ElfSectFlagAlloc:
			s.Type = obj.SRODATA

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

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

		if sect.name == ".got" || sect.name == ".toc" {
			s.Type = obj.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([]*Symbol, elfobj.nsymtab)

	for i := 1; i < elfobj.nsymtab; i++ {
		if err = readelfsym(ctxt, elfobj, i, &sym, 1, localSymVersion); err != nil {
			goto bad
		}
		symbols[i] = sym.sym
		if sym.type_ != ElfSymTypeFunc && sym.type_ != ElfSymTypeObject && sym.type_ != ElfSymTypeNone && sym.type_ != ElfSymTypeCommon {
			continue
		}
		if sym.shndx == ElfSymShnCommon || sym.type_ == ElfSymTypeCommon {
			s = sym.sym
			if uint64(s.Size) < sym.size {
				s.Size = int64(sym.size)
			}
			if s.Type == 0 || s.Type == obj.SXREF {
				s.Type = obj.SNOPTRBSS
			}
			continue
		}

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

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

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

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

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

		s.Sub = sect.sym.Sub
		sect.sym.Sub = s
		s.Type = sect.sym.Type | s.Type&^obj.SMASK | obj.SSUB
		if !s.Attr.CgoExportDynamic() {
			s.Dynimplib = "" // satisfy dynimport
		}
		s.Value = int64(sym.value)
		s.Size = int64(sym.size)
		s.Outer = sect.sym
		if sect.sym.Type == obj.STEXT {
			if s.Attr.External() && !s.Attr.DuplicateOK() {
				Errorf(s, "%s: duplicate symbol definition", pn)
			}
			s.Attr |= AttrExternal
		}

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

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

	// load relocations
	for i := 0; uint(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 {
			goto bad
		}
		rela = 0
		if rsect.type_ == ElfSectRela {
			rela = 1
		}
		n = int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
		r = make([]Reloc, n)
		p = rsect.base
		for j = 0; j < n; j++ {
			add = 0
			rp = &r[j]
			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 {
				if err = readelfsym(ctxt, elfobj, int(info>>32), &sym, 0, 0); err != nil {
					goto bad
				}
				sym.sym = symbols[info>>32]
				if sym.sym == nil {
					err = fmt.Errorf("%s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", sect.sym.Name, j, int(info>>32), sym.name, sym.shndx, sym.type_)
					goto bad
				}

				rp.Sym = sym.sym
			}

			rp.Type = 256 + obj.RelocType(info)
			rp.Siz = relSize(ctxt, pn, uint32(info))
			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 {
					Errorf(nil, "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(rbyoff(r[:n]))
		// just in case

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

	return

bad:
	Errorf(nil, "%s: malformed elf file: %v", pn, err)
}

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(ctxt *Link, elfobj *ElfObj, i int, sym *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 {
		Errorf(nil, "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)
		sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
		sym.value = elfobj.e.Uint64(b.Value[:])
		sym.size = elfobj.e.Uint64(b.Size[:])
		sym.shndx = elfobj.e.Uint16(b.Shndx[:])
		sym.bind = b.Info >> 4
		sym.type_ = b.Info & 0xf
		sym.other = b.Other
	} else {
		b := new(ElfSymBytes)
		binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF32SYMSIZE:(i+1)*ELF32SYMSIZE]), elfobj.e, b)
		sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
		sym.value = uint64(elfobj.e.Uint32(b.Value[:]))
		sym.size = uint64(elfobj.e.Uint32(b.Size[:]))
		sym.shndx = elfobj.e.Uint16(b.Shndx[:])
		sym.bind = b.Info >> 4
		sym.type_ = b.Info & 0xf
		sym.other = b.Other
	}

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

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

	case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone, ElfSymTypeCommon:
		switch sym.bind {
		case ElfSymBindGlobal:
			if needSym != 0 {
				s = ctxt.Syms.Lookup(sym.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 http://codereview.appspot.com/5823055/
				// comment #5 for details.
				if s != nil && sym.other == 2 {
					s.Type |= obj.SHIDDEN
					s.Attr |= AttrDuplicateOK
				}
			}

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

			if sym.name == ".TOC." {
				// We need to be able to look this up,
				// so put it in the hash table.
				if needSym != 0 {
					s = ctxt.Syms.Lookup(sym.name, localSymVersion)
					s.Type |= obj.SHIDDEN
				}

				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 = ctxt.Syms.newsym(sym.name, localSymVersion)

				s.Type |= obj.SHIDDEN
			}

		case ElfSymBindWeak:
			if needSym != 0 {
				s = ctxt.Syms.Lookup(sym.name, 0)
				if sym.other == 2 {
					s.Type |= obj.SHIDDEN
				}
			}

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

	if s != nil && s.Type == 0 && sym.type_ != ElfSymTypeSection {
		s.Type = obj.SXREF
	}
	sym.sym = s

	return nil
}

type rbyoff []Reloc

func (x rbyoff) Len() int {
	return len(x)
}

func (x rbyoff) Swap(i, j int) {
	x[i], x[j] = x[j], x[i]
}

func (x rbyoff) Less(i, j int) bool {
	a := &x[i]
	b := &x[j]
	if a.Off < b.Off {
		return true
	}
	if a.Off > b.Off {
		return false
	}
	return false
}

func relSize(ctxt *Link, pn string, elftype uint32) uint8 {
	// 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(SysArch.Family) | elftype<<24 {
	default:
		Errorf(nil, "%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
		fallthrough

	case S390X | R_390_8<<24:
		return 1

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

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

	case AMD64 | R_X86_64_64<<24,
		PPC64 | R_PPC64_ADDR64<<24,
		S390X | R_390_GLOB_DAT<<24,
		S390X | R_390_RELATIVE<<24,
		S390X | R_390_GOTOFF<<24,
		S390X | R_390_GOTPC<<24,
		S390X | R_390_64<<24,
		S390X | R_390_PC64<<24,
		S390X | R_390_GOT64<<24,
		S390X | R_390_PLT64<<24:
		return 8
	}
}
