// Copyright 2019 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/loader"
	"cmd/link/internal/sym"
	"debug/elf"
	"encoding/binary"
	"fmt"
	"io"
	"log"
	"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 (
	SHT_ARM_ATTRIBUTES = 0x70000003
)

type ElfSect struct {
	name        string
	nameoff     uint32
	type_       elf.SectionType
	flags       elf.SectionFlag
	addr        uint64
	off         uint64
	size        uint64
	link        uint32
	info        uint32
	align       uint64
	entsize     uint64
	base        []byte
	readOnlyMem bool // Is this section in readonly memory?
	sym         loader.Sym
}

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  elf.SymBind
	type_ elf.SymType
	other uint8
	shndx elf.SectionIndex
	sym   loader.Sym
}

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 == TagNoDefaults: // Tag_nodefaults has no argument

	case attr.tag == TagAlsoCompatibleWith:
		// 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 installed into the loader, 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(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, pkg string, length int64, pn string, initEhdrFlags uint32) (textp []loader.Sym, ehdrFlags uint32, err error) {
	newSym := func(name string, version int) loader.Sym {
		return l.CreateStaticSym(name)
	}
	lookup := l.LookupOrCreateCgoExport
	errorf := func(str string, args ...interface{}) ([]loader.Sym, uint32, error) {
		return nil, 0, fmt.Errorf("loadelf: %s: %v", pn, fmt.Sprintf(str, args...))
	}

	ehdrFlags = initEhdrFlags

	base := f.Offset()

	var hdrbuf [64]byte
	if _, err := io.ReadFull(f, hdrbuf[:]); err != nil {
		return errorf("malformed elf file: %v", err)
	}

	var e binary.ByteOrder
	switch elf.Data(hdrbuf[elf.EI_DATA]) {
	case elf.ELFDATA2LSB:
		e = binary.LittleEndian

	case elf.ELFDATA2MSB:
		e = binary.BigEndian

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

	hdr := new(elf.Header32)
	binary.Read(bytes.NewReader(hdrbuf[:]), e, hdr)

	if string(hdr.Ident[:elf.EI_CLASS]) != elf.ELFMAG {
		return errorf("malformed elf file, bad header")
	}

	// read header
	elfobj := new(ElfObj)

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

	is64 := 0
	class := elf.Class(hdrbuf[elf.EI_CLASS])
	if class == elf.ELFCLASS64 {
		is64 = 1
		hdr := new(elf.Header64)
		binary.Read(bytes.NewReader(hdrbuf[:]), e, hdr)
		elfobj.type_ = uint32(hdr.Type)
		elfobj.machine = uint32(hdr.Machine)
		elfobj.version = hdr.Version
		elfobj.entry = hdr.Entry
		elfobj.phoff = hdr.Phoff
		elfobj.shoff = hdr.Shoff
		elfobj.flags = hdr.Flags
		elfobj.ehsize = uint32(hdr.Ehsize)
		elfobj.phentsize = uint32(hdr.Phentsize)
		elfobj.phnum = uint32(hdr.Phnum)
		elfobj.shentsize = uint32(hdr.Shentsize)
		elfobj.shnum = uint32(hdr.Shnum)
		elfobj.shstrndx = uint32(hdr.Shstrndx)
	} else {
		elfobj.type_ = uint32(hdr.Type)
		elfobj.machine = uint32(hdr.Machine)
		elfobj.version = hdr.Version
		elfobj.entry = uint64(hdr.Entry)
		elfobj.phoff = uint64(hdr.Phoff)
		elfobj.shoff = uint64(hdr.Shoff)
		elfobj.flags = hdr.Flags
		elfobj.ehsize = uint32(hdr.Ehsize)
		elfobj.phentsize = uint32(hdr.Phentsize)
		elfobj.phnum = uint32(hdr.Phnum)
		elfobj.shentsize = uint32(hdr.Shentsize)
		elfobj.shnum = uint32(hdr.Shnum)
		elfobj.shstrndx = uint32(hdr.Shstrndx)
	}

	elfobj.is64 = is64

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

	if elf.Type(elfobj.type_) != elf.ET_REL {
		return errorf("elf but not elf relocatable object")
	}

	mach := elf.Machine(elfobj.machine)
	switch arch.Family {
	default:
		return errorf("elf %s unimplemented", arch.Name)

	case sys.MIPS:
		if mach != elf.EM_MIPS || class != elf.ELFCLASS32 {
			return errorf("elf object but not mips")
		}

	case sys.MIPS64:
		if mach != elf.EM_MIPS || class != elf.ELFCLASS64 {
			return errorf("elf object but not mips64")
		}

	case sys.ARM:
		if e != binary.LittleEndian || mach != elf.EM_ARM || class != elf.ELFCLASS32 {
			return errorf("elf object but not arm")
		}

	case sys.AMD64:
		if e != binary.LittleEndian || mach != elf.EM_X86_64 || class != elf.ELFCLASS64 {
			return errorf("elf object but not amd64")
		}

	case sys.ARM64:
		if e != binary.LittleEndian || mach != elf.EM_AARCH64 || class != elf.ELFCLASS64 {
			return errorf("elf object but not arm64")
		}

	case sys.I386:
		if e != binary.LittleEndian || mach != elf.EM_386 || class != elf.ELFCLASS32 {
			return errorf("elf object but not 386")
		}

	case sys.PPC64:
		if mach != elf.EM_PPC64 || class != elf.ELFCLASS64 {
			return errorf("elf object but not ppc64")
		}

	case sys.RISCV64:
		if mach != elf.EM_RISCV || class != elf.ELFCLASS64 {
			return errorf("elf object but not riscv64")
		}

	case sys.S390X:
		if mach != elf.EM_S390 || class != elf.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++ {
		f.MustSeek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0)
		sect := &elfobj.sect[i]
		if is64 != 0 {
			var b elf.Section64
			if err := binary.Read(f, e, &b); err != nil {
				return errorf("malformed elf file: %v", err)
			}

			sect.nameoff = b.Name
			sect.type_ = elf.SectionType(b.Type)
			sect.flags = elf.SectionFlag(b.Flags)
			sect.addr = b.Addr
			sect.off = b.Off
			sect.size = b.Size
			sect.link = b.Link
			sect.info = b.Info
			sect.align = b.Addralign
			sect.entsize = b.Entsize
		} else {
			var b elf.Section32

			if err := binary.Read(f, e, &b); err != nil {
				return errorf("malformed elf file: %v", err)
			}
			sect.nameoff = b.Name
			sect.type_ = elf.SectionType(b.Type)
			sect.flags = elf.SectionFlag(b.Flags)
			sect.addr = uint64(b.Addr)
			sect.off = uint64(b.Off)
			sect.size = uint64(b.Size)
			sect.link = b.Link
			sect.info = b.Info
			sect.align = uint64(b.Addralign)
			sect.entsize = uint64(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 / elf.Sym64Size)
	} else {
		elfobj.nsymtab = int(elfobj.symtab.size / elf.Sym32Size)
	}

	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
	sectsymNames := make(map[string]bool)
	counter := 0
	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_ != elf.SHT_PROGBITS && sect.type_ != elf.SHT_NOBITS) || sect.flags&elf.SHF_ALLOC == 0 {
			continue
		}
		if sect.type_ != elf.SHT_NOBITS {
			if err := elfmap(elfobj, sect); err != nil {
				return errorf("%s: malformed elf file: %v", pn, err)
			}
		}

		name := fmt.Sprintf("%s(%s)", pkg, sect.name)
		for sectsymNames[name] {
			counter++
			name = fmt.Sprintf("%s(%s%d)", pkg, sect.name, counter)
		}
		sectsymNames[name] = true

		sb := l.MakeSymbolUpdater(lookup(name, localSymVersion))

		switch sect.flags & (elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_EXECINSTR) {
		default:
			return errorf("%s: unexpected flags for ELF section %s", pn, sect.name)

		case elf.SHF_ALLOC:
			sb.SetType(sym.SRODATA)

		case elf.SHF_ALLOC + elf.SHF_WRITE:
			if sect.type_ == elf.SHT_NOBITS {
				sb.SetType(sym.SNOPTRBSS)
			} else {
				sb.SetType(sym.SNOPTRDATA)
			}

		case elf.SHF_ALLOC + elf.SHF_EXECINSTR:
			sb.SetType(sym.STEXT)
		}

		if sect.name == ".got" || sect.name == ".toc" {
			sb.SetType(sym.SELFGOT)
		}
		if sect.type_ == elf.SHT_PROGBITS {
			sb.SetData(sect.base[:sect.size])
		}

		sb.SetSize(int64(sect.size))
		sb.SetAlign(int32(sect.align))
		sb.SetReadOnly(sect.readOnlyMem)

		sect.sym = sb.Sym()
	}

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

	for i := 1; i < elfobj.nsymtab; i++ {
		var elfsym ElfSym
		if err := readelfsym(newSym, lookup, l, arch, elfobj, i, &elfsym, 1, localSymVersion); err != nil {
			return errorf("%s: malformed elf file: %v", pn, err)
		}
		symbols[i] = elfsym.sym
		if elfsym.type_ != elf.STT_FUNC && elfsym.type_ != elf.STT_OBJECT && elfsym.type_ != elf.STT_NOTYPE && elfsym.type_ != elf.STT_COMMON {
			continue
		}
		if elfsym.shndx == elf.SHN_COMMON || elfsym.type_ == elf.STT_COMMON {
			sb := l.MakeSymbolUpdater(elfsym.sym)
			if uint64(sb.Size()) < elfsym.size {
				sb.SetSize(int64(elfsym.size))
			}
			if sb.Type() == 0 || sb.Type() == sym.SXREF {
				sb.SetType(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 == 0 {
			continue
		}
		sect = &elfobj.sect[elfsym.shndx]
		if sect.sym == 0 {
			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, "$d") && elfsym.type_ == 0 && sect.name == ".debug_frame" {
				// "$d" is a marker, not a real symbol.
				// This happens with gcc on ARM64.
				// See https://sourceware.org/bugzilla/show_bug.cgi?id=21809
				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 l.OuterSym(s) != 0 {
			if l.AttrDuplicateOK(s) {
				continue
			}
			return errorf("duplicate symbol reference: %s in both %s and %s",
				l.SymName(s), l.SymName(l.OuterSym(s)), l.SymName(sect.sym))
		}

		sectsb := l.MakeSymbolUpdater(sect.sym)
		sb := l.MakeSymbolUpdater(s)

		sb.SetType(sectsb.Type())
		sectsb.AddInteriorSym(s)
		if !l.AttrCgoExportDynamic(s) {
			sb.SetDynimplib("") // satisfy dynimport
		}
		sb.SetValue(int64(elfsym.value))
		sb.SetSize(int64(elfsym.size))
		if sectsb.Type() == sym.STEXT {
			if l.AttrExternal(s) && !l.AttrDuplicateOK(s) {
				return errorf("%s: duplicate symbol definition", sb.Name())
			}
			l.SetAttrExternal(s, true)
		}

		if elf.Machine(elfobj.machine) == elf.EM_PPC64 {
			flag := int(elfsym.other) >> 5
			if 2 <= flag && flag <= 6 {
				l.SetSymLocalentry(s, 1<<uint(flag-2))
			} else if flag == 7 {
				return errorf("%s: invalid sym.other 0x%x", sb.Name(), 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 == 0 {
			continue
		}
		sb := l.MakeSymbolUpdater(s)
		if l.SubSym(s) != 0 {
			sb.SortSub()
		}
		if sb.Type() == sym.STEXT {
			if l.AttrOnList(s) {
				return errorf("symbol %s listed multiple times",
					l.SymName(s))
			}
			l.SetAttrOnList(s, true)
			textp = append(textp, s)
			for ss := l.SubSym(s); ss != 0; ss = l.SubSym(ss) {
				if l.AttrOnList(ss) {
					return errorf("symbol %s listed multiple times",
						l.SymName(ss))
				}
				l.SetAttrOnList(ss, true)
				textp = append(textp, ss)
			}
		}
	}

	// load relocations
	for i := uint(0); i < elfobj.nsect; i++ {
		rsect := &elfobj.sect[i]
		if rsect.type_ != elf.SHT_RELA && rsect.type_ != elf.SHT_REL {
			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_ == elf.SHT_RELA {
			rela = 1
		}
		n := int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
		p := rsect.base
		sb := l.MakeSymbolUpdater(sect.sym)
		for j := 0; j < n; j++ {
			var add uint64
			var symIdx int
			var relocType uint64
			var rOff int32
			var rAdd int64
			var rSym loader.Sym

			if is64 != 0 {
				// 64-bit rel/rela
				rOff = int32(e.Uint64(p))

				p = p[8:]
				switch arch.Family {
				case sys.MIPS64:
					// https://www.linux-mips.org/pub/linux/mips/doc/ABI/elf64-2.4.pdf
					// The doc shows it's different with general Linux ELF
					symIdx = int(e.Uint32(p))
					relocType = uint64(p[7])
				default:
					info := e.Uint64(p)
					relocType = info & 0xffffffff
					symIdx = int(info >> 32)
				}
				p = p[8:]
				if rela != 0 {
					add = e.Uint64(p)
					p = p[8:]
				}
			} else {
				// 32-bit rel/rela
				rOff = int32(e.Uint32(p))

				p = p[4:]
				info := e.Uint32(p)
				relocType = uint64(info & 0xff)
				symIdx = int(info >> 8)
				p = p[4:]
				if rela != 0 {
					add = uint64(e.Uint32(p))
					p = p[4:]
				}
			}

			if relocType == 0 { // skip R_*_NONE relocation
				j--
				n--
				continue
			}

			if symIdx == 0 { // absolute relocation, don't bother reading the null symbol
				rSym = 0
			} else {
				var elfsym ElfSym
				if err := readelfsym(newSym, lookup, l, arch, elfobj, int(symIdx), &elfsym, 0, 0); err != nil {
					return errorf("malformed elf file: %v", err)
				}
				elfsym.sym = symbols[symIdx]
				if elfsym.sym == 0 {
					return errorf("malformed elf file: %s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", l.SymName(sect.sym), j, int(symIdx), elfsym.name, elfsym.shndx, elfsym.type_)
				}

				rSym = elfsym.sym
			}

			rType := objabi.ElfRelocOffset + objabi.RelocType(relocType)
			rSize, addendSize, err := relSize(arch, pn, uint32(relocType))
			if err != nil {
				return nil, 0, err
			}
			if rela != 0 {
				rAdd = int64(add)
			} else {
				// load addend from image
				if rSize == 4 {
					rAdd = int64(e.Uint32(sect.base[rOff:]))
				} else if rSize == 8 {
					rAdd = int64(e.Uint64(sect.base[rOff:]))
				} else {
					return errorf("invalid rela size %d", rSize)
				}
			}

			if addendSize == 2 {
				rAdd = int64(int16(rAdd))
			}
			if addendSize == 4 {
				rAdd = int64(int32(rAdd))
			}

			r, _ := sb.AddRel(rType)
			r.SetOff(rOff)
			r.SetSiz(rSize)
			r.SetSym(rSym)
			r.SetAdd(rAdd)
		}

		sb.SortRelocs() // just in case
	}

	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
	}

	elfobj.f.MustSeek(int64(uint64(elfobj.base)+sect.off), 0)
	sect.base, sect.readOnlyMem, err = elfobj.f.Slice(uint64(sect.size))
	if err != nil {
		return fmt.Errorf("short read: %v", err)
	}

	return nil
}

func readelfsym(newSym, lookup func(string, int) loader.Sym, l *loader.Loader, arch *sys.Arch, 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(elf.Sym64)
		binary.Read(bytes.NewReader(elfobj.symtab.base[i*elf.Sym64Size:(i+1)*elf.Sym64Size]), elfobj.e, b)
		elfsym.name = cstring(elfobj.symstr.base[b.Name:])
		elfsym.value = b.Value
		elfsym.size = b.Size
		elfsym.shndx = elf.SectionIndex(b.Shndx)
		elfsym.bind = elf.ST_BIND(b.Info)
		elfsym.type_ = elf.ST_TYPE(b.Info)
		elfsym.other = b.Other
	} else {
		b := new(elf.Sym32)
		binary.Read(bytes.NewReader(elfobj.symtab.base[i*elf.Sym32Size:(i+1)*elf.Sym32Size]), elfobj.e, b)
		elfsym.name = cstring(elfobj.symstr.base[b.Name:])
		elfsym.value = uint64(b.Value)
		elfsym.size = uint64(b.Size)
		elfsym.shndx = elf.SectionIndex(b.Shndx)
		elfsym.bind = elf.ST_BIND(b.Info)
		elfsym.type_ = elf.ST_TYPE(b.Info)
		elfsym.other = b.Other
	}

	var s loader.Sym

	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 = elf.STB_LOCAL
	}

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

	case elf.STT_OBJECT, elf.STT_FUNC, elf.STT_NOTYPE, elf.STT_COMMON:
		switch elfsym.bind {
		case elf.STB_GLOBAL:
			if needSym != 0 {
				s = 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 != 0 && elfsym.other == 2 {
					if !l.IsExternal(s) {
						l.MakeSymbolUpdater(s)
					}
					l.SetAttrDuplicateOK(s, true)
					l.SetAttrVisibilityHidden(s, true)
				}
			}

		case elf.STB_LOCAL:
			if (arch.Family == sys.ARM || arch.Family == sys.ARM64) && (strings.HasPrefix(elfsym.name, "$a") || strings.HasPrefix(elfsym.name, "$d") || strings.HasPrefix(elfsym.name, "$x")) {
				// binutils for arm and arm64 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 = lookup(elfsym.name, localSymVersion)
					l.SetAttrVisibilityHidden(s, true)
				}
				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
				// FIXME: pass empty string here for name? This would
				// reduce mem use, but also (possibly) make it harder
				// to debug problems.
				s = newSym(elfsym.name, localSymVersion)
				l.SetAttrVisibilityHidden(s, true)
			}

		case elf.STB_WEAK:
			if needSym != 0 {
				s = lookup(elfsym.name, 0)
				if elfsym.other == 2 {
					l.SetAttrVisibilityHidden(s, true)
				}

				// Allow weak symbols to be duplicated when already defined.
				if l.OuterSym(s) != 0 {
					l.SetAttrDuplicateOK(s, true)
				}
			}

		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 != 0 && l.SymType(s) == 0 && !l.AttrVisibilityHidden(s) && elfsym.type_ != elf.STT_SECTION {
		sb := l.MakeSymbolUpdater(s)
		sb.SetType(sym.SXREF)
	}
	elfsym.sym = s

	return nil
}

// Return the size of the relocated field, and the size of the addend as the first
// and second values. Note, the addend may be larger than the relocation field in
// some cases when a relocated value is split across multiple relocations.
func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, 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)
		ARM64   = uint32(sys.ARM64)
		I386    = uint32(sys.I386)
		MIPS    = uint32(sys.MIPS)
		MIPS64  = uint32(sys.MIPS64)
		PPC64   = uint32(sys.PPC64)
		RISCV64 = uint32(sys.RISCV64)
		S390X   = uint32(sys.S390X)
	)

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

	case MIPS | uint32(elf.R_MIPS_HI16)<<16,
		MIPS | uint32(elf.R_MIPS_LO16)<<16,
		MIPS | uint32(elf.R_MIPS_GOT16)<<16,
		MIPS | uint32(elf.R_MIPS_GOT_HI16)<<16,
		MIPS | uint32(elf.R_MIPS_GOT_LO16)<<16,
		MIPS | uint32(elf.R_MIPS_GPREL16)<<16,
		MIPS | uint32(elf.R_MIPS_GOT_PAGE)<<16,
		MIPS | uint32(elf.R_MIPS_JALR)<<16,
		MIPS | uint32(elf.R_MIPS_GOT_OFST)<<16,
		MIPS64 | uint32(elf.R_MIPS_HI16)<<16,
		MIPS64 | uint32(elf.R_MIPS_LO16)<<16,
		MIPS64 | uint32(elf.R_MIPS_GOT16)<<16,
		MIPS64 | uint32(elf.R_MIPS_GOT_HI16)<<16,
		MIPS64 | uint32(elf.R_MIPS_GOT_LO16)<<16,
		MIPS64 | uint32(elf.R_MIPS_GPREL16)<<16,
		MIPS64 | uint32(elf.R_MIPS_GOT_PAGE)<<16,
		MIPS64 | uint32(elf.R_MIPS_JALR)<<16,
		MIPS64 | uint32(elf.R_MIPS_GOT_OFST)<<16,
		MIPS64 | uint32(elf.R_MIPS_CALL16)<<16,
		MIPS64 | uint32(elf.R_MIPS_GPREL32)<<16,
		MIPS64 | uint32(elf.R_MIPS_64)<<16,
		MIPS64 | uint32(elf.R_MIPS_GOT_DISP)<<16:
		return 4, 4, nil

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

	case PPC64 | uint32(elf.R_PPC64_TOC16)<<16,
		S390X | uint32(elf.R_390_16)<<16,
		S390X | uint32(elf.R_390_GOT16)<<16,
		S390X | uint32(elf.R_390_PC16)<<16,
		S390X | uint32(elf.R_390_PC16DBL)<<16,
		S390X | uint32(elf.R_390_PLT16DBL)<<16:
		return 2, 2, nil

	case ARM | uint32(elf.R_ARM_ABS32)<<16,
		ARM | uint32(elf.R_ARM_GOT32)<<16,
		ARM | uint32(elf.R_ARM_PLT32)<<16,
		ARM | uint32(elf.R_ARM_GOTOFF)<<16,
		ARM | uint32(elf.R_ARM_GOTPC)<<16,
		ARM | uint32(elf.R_ARM_THM_PC22)<<16,
		ARM | uint32(elf.R_ARM_REL32)<<16,
		ARM | uint32(elf.R_ARM_CALL)<<16,
		ARM | uint32(elf.R_ARM_V4BX)<<16,
		ARM | uint32(elf.R_ARM_GOT_PREL)<<16,
		ARM | uint32(elf.R_ARM_PC24)<<16,
		ARM | uint32(elf.R_ARM_JUMP24)<<16,
		ARM64 | uint32(elf.R_AARCH64_CALL26)<<16,
		ARM64 | uint32(elf.R_AARCH64_ADR_GOT_PAGE)<<16,
		ARM64 | uint32(elf.R_AARCH64_LD64_GOT_LO12_NC)<<16,
		ARM64 | uint32(elf.R_AARCH64_ADR_PREL_PG_HI21)<<16,
		ARM64 | uint32(elf.R_AARCH64_ADD_ABS_LO12_NC)<<16,
		ARM64 | uint32(elf.R_AARCH64_LDST8_ABS_LO12_NC)<<16,
		ARM64 | uint32(elf.R_AARCH64_LDST16_ABS_LO12_NC)<<16,
		ARM64 | uint32(elf.R_AARCH64_LDST32_ABS_LO12_NC)<<16,
		ARM64 | uint32(elf.R_AARCH64_LDST64_ABS_LO12_NC)<<16,
		ARM64 | uint32(elf.R_AARCH64_LDST128_ABS_LO12_NC)<<16,
		ARM64 | uint32(elf.R_AARCH64_PREL32)<<16,
		ARM64 | uint32(elf.R_AARCH64_JUMP26)<<16,
		AMD64 | uint32(elf.R_X86_64_PC32)<<16,
		AMD64 | uint32(elf.R_X86_64_PLT32)<<16,
		AMD64 | uint32(elf.R_X86_64_GOTPCREL)<<16,
		AMD64 | uint32(elf.R_X86_64_GOTPCRELX)<<16,
		AMD64 | uint32(elf.R_X86_64_REX_GOTPCRELX)<<16,
		I386 | uint32(elf.R_386_32)<<16,
		I386 | uint32(elf.R_386_PC32)<<16,
		I386 | uint32(elf.R_386_GOT32)<<16,
		I386 | uint32(elf.R_386_PLT32)<<16,
		I386 | uint32(elf.R_386_GOTOFF)<<16,
		I386 | uint32(elf.R_386_GOTPC)<<16,
		I386 | uint32(elf.R_386_GOT32X)<<16,
		PPC64 | uint32(elf.R_PPC64_REL24)<<16,
		PPC64 | uint32(elf.R_PPC_REL32)<<16,
		S390X | uint32(elf.R_390_32)<<16,
		S390X | uint32(elf.R_390_PC32)<<16,
		S390X | uint32(elf.R_390_GOT32)<<16,
		S390X | uint32(elf.R_390_PLT32)<<16,
		S390X | uint32(elf.R_390_PC32DBL)<<16,
		S390X | uint32(elf.R_390_PLT32DBL)<<16,
		S390X | uint32(elf.R_390_GOTPCDBL)<<16,
		S390X | uint32(elf.R_390_GOTENT)<<16:
		return 4, 4, nil

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

	case RISCV64 | uint32(elf.R_RISCV_RVC_BRANCH)<<16,
		RISCV64 | uint32(elf.R_RISCV_RVC_JUMP)<<16:
		return 2, 2, nil

	case RISCV64 | uint32(elf.R_RISCV_32)<<16,
		RISCV64 | uint32(elf.R_RISCV_BRANCH)<<16,
		RISCV64 | uint32(elf.R_RISCV_HI20)<<16,
		RISCV64 | uint32(elf.R_RISCV_LO12_I)<<16,
		RISCV64 | uint32(elf.R_RISCV_LO12_S)<<16,
		RISCV64 | uint32(elf.R_RISCV_GOT_HI20)<<16,
		RISCV64 | uint32(elf.R_RISCV_PCREL_HI20)<<16,
		RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_I)<<16,
		RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_S)<<16,
		RISCV64 | uint32(elf.R_RISCV_RELAX)<<16:
		return 4, 4, nil

	case RISCV64 | uint32(elf.R_RISCV_64)<<16,
		RISCV64 | uint32(elf.R_RISCV_CALL)<<16,
		RISCV64 | uint32(elf.R_RISCV_CALL_PLT)<<16:
		return 8, 8, nil

	case PPC64 | uint32(elf.R_PPC64_TOC16_LO)<<16,
		PPC64 | uint32(elf.R_PPC64_TOC16_HI)<<16,
		PPC64 | uint32(elf.R_PPC64_TOC16_HA)<<16,
		PPC64 | uint32(elf.R_PPC64_TOC16_DS)<<16,
		PPC64 | uint32(elf.R_PPC64_TOC16_LO_DS)<<16,
		PPC64 | uint32(elf.R_PPC64_REL16_LO)<<16,
		PPC64 | uint32(elf.R_PPC64_REL16_HI)<<16,
		PPC64 | uint32(elf.R_PPC64_REL16_HA)<<16:
		return 2, 4, nil
	}
}

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