package ebpf

import (
	"bufio"
	"bytes"
	"debug/elf"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"math"
	"os"
	"strings"

	"github.com/cilium/ebpf/asm"
	"github.com/cilium/ebpf/btf"
	"github.com/cilium/ebpf/internal"
	"github.com/cilium/ebpf/internal/unix"
)

type kconfigMetaKey struct{}

type kconfigMeta struct {
	Map    *MapSpec
	Offset uint32
}

type kfuncMeta struct{}

// elfCode is a convenience to reduce the amount of arguments that have to
// be passed around explicitly. You should treat its contents as immutable.
type elfCode struct {
	*internal.SafeELFFile
	sections map[elf.SectionIndex]*elfSection
	license  string
	version  uint32
	btf      *btf.Spec
	extInfo  *btf.ExtInfos
	maps     map[string]*MapSpec
	kfuncs   map[string]*btf.Func
	kconfig  *MapSpec
}

// LoadCollectionSpec parses an ELF file into a CollectionSpec.
func LoadCollectionSpec(file string) (*CollectionSpec, error) {
	f, err := os.Open(file)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	spec, err := LoadCollectionSpecFromReader(f)
	if err != nil {
		return nil, fmt.Errorf("file %s: %w", file, err)
	}
	return spec, nil
}

// LoadCollectionSpecFromReader parses an ELF file into a CollectionSpec.
func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error) {
	f, err := internal.NewSafeELFFile(rd)
	if err != nil {
		return nil, err
	}

	// Checks if the ELF file is for BPF data.
	// Old LLVM versions set e_machine to EM_NONE.
	if f.File.Machine != unix.EM_NONE && f.File.Machine != elf.EM_BPF {
		return nil, fmt.Errorf("unexpected machine type for BPF ELF: %s", f.File.Machine)
	}

	var (
		licenseSection *elf.Section
		versionSection *elf.Section
		sections       = make(map[elf.SectionIndex]*elfSection)
		relSections    = make(map[elf.SectionIndex]*elf.Section)
	)

	// This is the target of relocations generated by inline assembly.
	sections[elf.SHN_UNDEF] = newElfSection(new(elf.Section), undefSection)

	// Collect all the sections we're interested in. This includes relocations
	// which we parse later.
	//
	// Keep the documentation at docs/ebpf/loading/elf-sections.md up-to-date.
	for i, sec := range f.Sections {
		idx := elf.SectionIndex(i)

		switch {
		case strings.HasPrefix(sec.Name, "license"):
			licenseSection = sec
		case strings.HasPrefix(sec.Name, "version"):
			versionSection = sec
		case strings.HasPrefix(sec.Name, "maps"):
			sections[idx] = newElfSection(sec, mapSection)
		case sec.Name == ".maps":
			sections[idx] = newElfSection(sec, btfMapSection)
		case sec.Name == ".bss" || sec.Name == ".data" || strings.HasPrefix(sec.Name, ".rodata"):
			sections[idx] = newElfSection(sec, dataSection)
		case sec.Type == elf.SHT_REL:
			// Store relocations under the section index of the target
			relSections[elf.SectionIndex(sec.Info)] = sec
		case sec.Type == elf.SHT_PROGBITS && (sec.Flags&elf.SHF_EXECINSTR) != 0 && sec.Size > 0:
			sections[idx] = newElfSection(sec, programSection)
		}
	}

	license, err := loadLicense(licenseSection)
	if err != nil {
		return nil, fmt.Errorf("load license: %w", err)
	}

	version, err := loadVersion(versionSection, f.ByteOrder)
	if err != nil {
		return nil, fmt.Errorf("load version: %w", err)
	}

	btfSpec, btfExtInfo, err := btf.LoadSpecAndExtInfosFromReader(rd)
	if err != nil && !errors.Is(err, btf.ErrNotFound) {
		return nil, fmt.Errorf("load BTF: %w", err)
	}

	ec := &elfCode{
		SafeELFFile: f,
		sections:    sections,
		license:     license,
		version:     version,
		btf:         btfSpec,
		extInfo:     btfExtInfo,
		maps:        make(map[string]*MapSpec),
		kfuncs:      make(map[string]*btf.Func),
	}

	symbols, err := f.Symbols()
	if err != nil {
		return nil, fmt.Errorf("load symbols: %v", err)
	}

	ec.assignSymbols(symbols)

	if err := ec.loadRelocations(relSections, symbols); err != nil {
		return nil, fmt.Errorf("load relocations: %w", err)
	}

	if err := ec.loadMaps(); err != nil {
		return nil, fmt.Errorf("load maps: %w", err)
	}

	if err := ec.loadBTFMaps(); err != nil {
		return nil, fmt.Errorf("load BTF maps: %w", err)
	}

	if err := ec.loadDataSections(); err != nil {
		return nil, fmt.Errorf("load data sections: %w", err)
	}

	if err := ec.loadKconfigSection(); err != nil {
		return nil, fmt.Errorf("load virtual .kconfig section: %w", err)
	}

	if err := ec.loadKsymsSection(); err != nil {
		return nil, fmt.Errorf("load virtual .ksyms section: %w", err)
	}

	// Finally, collect programs and link them.
	progs, err := ec.loadProgramSections()
	if err != nil {
		return nil, fmt.Errorf("load programs: %w", err)
	}

	return &CollectionSpec{ec.maps, progs, btfSpec, ec.ByteOrder}, nil
}

func loadLicense(sec *elf.Section) (string, error) {
	if sec == nil {
		return "", nil
	}

	data, err := sec.Data()
	if err != nil {
		return "", fmt.Errorf("section %s: %v", sec.Name, err)
	}
	return string(bytes.TrimRight(data, "\000")), nil
}

func loadVersion(sec *elf.Section, bo binary.ByteOrder) (uint32, error) {
	if sec == nil {
		return 0, nil
	}

	var version uint32
	if err := binary.Read(sec.Open(), bo, &version); err != nil {
		return 0, fmt.Errorf("section %s: %v", sec.Name, err)
	}
	return version, nil
}

type elfSectionKind int

const (
	undefSection elfSectionKind = iota
	mapSection
	btfMapSection
	programSection
	dataSection
)

type elfSection struct {
	*elf.Section
	kind elfSectionKind
	// Offset from the start of the section to a symbol
	symbols map[uint64]elf.Symbol
	// Offset from the start of the section to a relocation, which points at
	// a symbol in another section.
	relocations map[uint64]elf.Symbol
	// The number of relocations pointing at this section.
	references int
}

func newElfSection(section *elf.Section, kind elfSectionKind) *elfSection {
	return &elfSection{
		section,
		kind,
		make(map[uint64]elf.Symbol),
		make(map[uint64]elf.Symbol),
		0,
	}
}

// assignSymbols takes a list of symbols and assigns them to their
// respective sections, indexed by name.
func (ec *elfCode) assignSymbols(symbols []elf.Symbol) {
	for _, symbol := range symbols {
		symType := elf.ST_TYPE(symbol.Info)
		symSection := ec.sections[symbol.Section]
		if symSection == nil {
			continue
		}

		// Anonymous symbols only occur in debug sections which we don't process
		// relocations for. Anonymous symbols are not referenced from other sections.
		if symbol.Name == "" {
			continue
		}

		// Older versions of LLVM don't tag symbols correctly, so keep
		// all NOTYPE ones.
		switch symSection.kind {
		case mapSection, btfMapSection, dataSection:
			if symType != elf.STT_NOTYPE && symType != elf.STT_OBJECT {
				continue
			}
		case programSection:
			if symType != elf.STT_NOTYPE && symType != elf.STT_FUNC {
				continue
			}
			// LLVM emits LBB_ (Local Basic Block) symbols that seem to be jump
			// targets within sections, but BPF has no use for them.
			if symType == elf.STT_NOTYPE && elf.ST_BIND(symbol.Info) == elf.STB_LOCAL &&
				strings.HasPrefix(symbol.Name, "LBB") {
				continue
			}
		// Only collect symbols that occur in program/maps/data sections.
		default:
			continue
		}

		symSection.symbols[symbol.Value] = symbol
	}
}

// loadRelocations iterates .rel* sections and extracts relocation entries for
// sections of interest. Makes sure relocations point at valid sections.
func (ec *elfCode) loadRelocations(relSections map[elf.SectionIndex]*elf.Section, symbols []elf.Symbol) error {
	for idx, relSection := range relSections {
		section := ec.sections[idx]
		if section == nil {
			continue
		}

		rels, err := ec.loadSectionRelocations(relSection, symbols)
		if err != nil {
			return fmt.Errorf("relocation for section %q: %w", section.Name, err)
		}

		for _, rel := range rels {
			target := ec.sections[rel.Section]
			if target == nil {
				return fmt.Errorf("section %q: reference to %q in section %s: %w", section.Name, rel.Name, rel.Section, ErrNotSupported)
			}

			target.references++
		}

		section.relocations = rels
	}

	return nil
}

// loadProgramSections iterates ec's sections and emits a ProgramSpec
// for each function it finds.
//
// The resulting map is indexed by function name.
func (ec *elfCode) loadProgramSections() (map[string]*ProgramSpec, error) {

	progs := make(map[string]*ProgramSpec)

	// Generate a ProgramSpec for each function found in each program section.
	var export []string
	for _, sec := range ec.sections {
		if sec.kind != programSection {
			continue
		}

		if len(sec.symbols) == 0 {
			return nil, fmt.Errorf("section %v: missing symbols", sec.Name)
		}

		funcs, err := ec.loadFunctions(sec)
		if err != nil {
			return nil, fmt.Errorf("section %v: %w", sec.Name, err)
		}

		progType, attachType, progFlags, attachTo := getProgType(sec.Name)

		for name, insns := range funcs {
			spec := &ProgramSpec{
				Name:          name,
				Type:          progType,
				Flags:         progFlags,
				AttachType:    attachType,
				AttachTo:      attachTo,
				SectionName:   sec.Name,
				License:       ec.license,
				KernelVersion: ec.version,
				Instructions:  insns,
				ByteOrder:     ec.ByteOrder,
			}

			// Function names must be unique within a single ELF blob.
			if progs[name] != nil {
				return nil, fmt.Errorf("duplicate program name %s", name)
			}
			progs[name] = spec

			if spec.SectionName != ".text" {
				export = append(export, name)
			}
		}
	}

	flattenPrograms(progs, export)

	// Hide programs (e.g. library functions) that were not explicitly emitted
	// to an ELF section. These could be exposed in a separate CollectionSpec
	// field later to allow them to be modified.
	for n, p := range progs {
		if p.SectionName == ".text" {
			delete(progs, n)
		}
	}

	return progs, nil
}

// loadFunctions extracts instruction streams from the given program section
// starting at each symbol in the section. The section's symbols must already
// be narrowed down to STT_NOTYPE (emitted by clang <8) or STT_FUNC.
//
// The resulting map is indexed by function name.
func (ec *elfCode) loadFunctions(section *elfSection) (map[string]asm.Instructions, error) {
	r := bufio.NewReader(section.Open())

	// Decode the section's instruction stream.
	insns := make(asm.Instructions, 0, section.Size/asm.InstructionSize)
	if err := insns.Unmarshal(r, ec.ByteOrder); err != nil {
		return nil, fmt.Errorf("decoding instructions for section %s: %w", section.Name, err)
	}
	if len(insns) == 0 {
		return nil, fmt.Errorf("no instructions found in section %s", section.Name)
	}

	iter := insns.Iterate()
	for iter.Next() {
		ins := iter.Ins
		offset := iter.Offset.Bytes()

		// Tag Symbol Instructions.
		if sym, ok := section.symbols[offset]; ok {
			*ins = ins.WithSymbol(sym.Name)
		}

		// Apply any relocations for the current instruction.
		// If no relocation is present, resolve any section-relative function calls.
		if rel, ok := section.relocations[offset]; ok {
			if err := ec.relocateInstruction(ins, rel); err != nil {
				return nil, fmt.Errorf("offset %d: relocating instruction: %w", offset, err)
			}
		} else {
			if err := referenceRelativeJump(ins, offset, section.symbols); err != nil {
				return nil, fmt.Errorf("offset %d: resolving relative jump: %w", offset, err)
			}
		}
	}

	if ec.extInfo != nil {
		ec.extInfo.Assign(insns, section.Name)
	}

	return splitSymbols(insns)
}

// referenceRelativeJump turns a relative jump to another bpf subprogram within
// the same ELF section into a Reference Instruction.
//
// Up to LLVM 9, calls to subprograms within the same ELF section are sometimes
// encoded using relative jumps instead of relocation entries. These jumps go
// out of bounds of the current program, so their targets must be memoized
// before the section's instruction stream is split.
//
// The relative jump Constant is blinded to -1 and the target Symbol is set as
// the Instruction's Reference so it can be resolved by the linker.
func referenceRelativeJump(ins *asm.Instruction, offset uint64, symbols map[uint64]elf.Symbol) error {
	if !ins.IsFunctionReference() || ins.Constant == -1 {
		return nil
	}

	tgt := jumpTarget(offset, *ins)
	sym := symbols[tgt].Name
	if sym == "" {
		return fmt.Errorf("no jump target found at offset %d", tgt)
	}

	*ins = ins.WithReference(sym)
	ins.Constant = -1

	return nil
}

// jumpTarget takes ins' offset within an instruction stream (in bytes)
// and returns its absolute jump destination (in bytes) within the
// instruction stream.
func jumpTarget(offset uint64, ins asm.Instruction) uint64 {
	// A relative jump instruction describes the amount of raw BPF instructions
	// to jump, convert the offset into bytes.
	dest := ins.Constant * asm.InstructionSize

	// The starting point of the jump is the end of the current instruction.
	dest += int64(offset + asm.InstructionSize)

	if dest < 0 {
		return 0
	}

	return uint64(dest)
}

func (ec *elfCode) relocateInstruction(ins *asm.Instruction, rel elf.Symbol) error {
	var (
		typ  = elf.ST_TYPE(rel.Info)
		bind = elf.ST_BIND(rel.Info)
		name = rel.Name
	)

	target := ec.sections[rel.Section]

	switch target.kind {
	case mapSection, btfMapSection:
		if bind == elf.STB_LOCAL {
			return fmt.Errorf("possible erroneous static qualifier on map definition: found reference to %q", name)
		}

		if bind != elf.STB_GLOBAL {
			return fmt.Errorf("map %q: unsupported relocation %s", name, bind)
		}

		if typ != elf.STT_OBJECT && typ != elf.STT_NOTYPE {
			// STT_NOTYPE is generated on clang < 8 which doesn't tag
			// relocations appropriately.
			return fmt.Errorf("map load: incorrect relocation type %v", typ)
		}

		ins.Src = asm.PseudoMapFD

	case dataSection:
		var offset uint32
		switch typ {
		case elf.STT_SECTION:
			if bind != elf.STB_LOCAL {
				return fmt.Errorf("direct load: %s: unsupported section relocation %s", name, bind)
			}

			// This is really a reference to a static symbol, which clang doesn't
			// emit a symbol table entry for. Instead it encodes the offset in
			// the instruction itself.
			offset = uint32(uint64(ins.Constant))

		case elf.STT_OBJECT:
			// LLVM 9 emits OBJECT-LOCAL symbols for anonymous constants.
			if bind != elf.STB_GLOBAL && bind != elf.STB_LOCAL {
				return fmt.Errorf("direct load: %s: unsupported object relocation %s", name, bind)
			}

			offset = uint32(rel.Value)

		case elf.STT_NOTYPE:
			// LLVM 7 emits NOTYPE-LOCAL symbols for anonymous constants.
			if bind != elf.STB_LOCAL {
				return fmt.Errorf("direct load: %s: unsupported untyped relocation %s", name, bind)
			}

			offset = uint32(rel.Value)

		default:
			return fmt.Errorf("incorrect relocation type %v for direct map load", typ)
		}

		// We rely on using the name of the data section as the reference. It
		// would be nicer to keep the real name in case of an STT_OBJECT, but
		// it's not clear how to encode that into Instruction.
		name = target.Name

		// The kernel expects the offset in the second basic BPF instruction.
		ins.Constant = int64(uint64(offset) << 32)
		ins.Src = asm.PseudoMapValue

	case programSection:
		switch opCode := ins.OpCode; {
		case opCode.JumpOp() == asm.Call:
			if ins.Src != asm.PseudoCall {
				return fmt.Errorf("call: %s: incorrect source register", name)
			}

			switch typ {
			case elf.STT_NOTYPE, elf.STT_FUNC:
				if bind != elf.STB_GLOBAL {
					return fmt.Errorf("call: %s: unsupported binding: %s", name, bind)
				}

			case elf.STT_SECTION:
				if bind != elf.STB_LOCAL {
					return fmt.Errorf("call: %s: unsupported binding: %s", name, bind)
				}

				// The function we want to call is in the indicated section,
				// at the offset encoded in the instruction itself. Reverse
				// the calculation to find the real function we're looking for.
				// A value of -1 references the first instruction in the section.
				offset := int64(int32(ins.Constant)+1) * asm.InstructionSize
				sym, ok := target.symbols[uint64(offset)]
				if !ok {
					return fmt.Errorf("call: no symbol at offset %d", offset)
				}

				name = sym.Name
				ins.Constant = -1

			default:
				return fmt.Errorf("call: %s: invalid symbol type %s", name, typ)
			}
		case opCode.IsDWordLoad():
			switch typ {
			case elf.STT_FUNC:
				if bind != elf.STB_GLOBAL {
					return fmt.Errorf("load: %s: unsupported binding: %s", name, bind)
				}

			case elf.STT_SECTION:
				if bind != elf.STB_LOCAL {
					return fmt.Errorf("load: %s: unsupported binding: %s", name, bind)
				}

				// ins.Constant already contains the offset in bytes from the
				// start of the section. This is different than a call to a
				// static function.

			default:
				return fmt.Errorf("load: %s: invalid symbol type %s", name, typ)
			}

			sym, ok := target.symbols[uint64(ins.Constant)]
			if !ok {
				return fmt.Errorf("load: no symbol at offset %d", ins.Constant)
			}

			name = sym.Name
			ins.Constant = -1
			ins.Src = asm.PseudoFunc

		default:
			return fmt.Errorf("neither a call nor a load instruction: %v", ins)
		}

	// The Undefined section is used for 'virtual' symbols that aren't backed by
	// an ELF section. This includes symbol references from inline asm, forward
	// function declarations, as well as extern kfunc declarations using __ksym
	// and extern kconfig variables declared using __kconfig.
	case undefSection:
		if bind != elf.STB_GLOBAL {
			return fmt.Errorf("asm relocation: %s: unsupported binding: %s", name, bind)
		}

		if typ != elf.STT_NOTYPE {
			return fmt.Errorf("asm relocation: %s: unsupported type %s", name, typ)
		}

		kf := ec.kfuncs[name]
		switch {
		// If a Call instruction is found and the datasec has a btf.Func with a Name
		// that matches the symbol name we mark the instruction as a call to a kfunc.
		case kf != nil && ins.OpCode.JumpOp() == asm.Call:
			ins.Metadata.Set(kfuncMeta{}, kf)
			ins.Src = asm.PseudoKfuncCall
			ins.Constant = -1

		// If no kconfig map is found, this must be a symbol reference from inline
		// asm (see testdata/loader.c:asm_relocation()) or a call to a forward
		// function declaration (see testdata/fwd_decl.c). Don't interfere, These
		// remain standard symbol references.
		// extern __kconfig reads are represented as dword loads that need to be
		// rewritten to pseudo map loads from .kconfig. If the map is present,
		// require it to contain the symbol to disambiguate between inline asm
		// relos and kconfigs.
		case ec.kconfig != nil && ins.OpCode.IsDWordLoad():
			for _, vsi := range ec.kconfig.Value.(*btf.Datasec).Vars {
				if vsi.Type.(*btf.Var).Name != rel.Name {
					continue
				}

				ins.Src = asm.PseudoMapValue
				ins.Metadata.Set(kconfigMetaKey{}, &kconfigMeta{ec.kconfig, vsi.Offset})
				return nil
			}

			return fmt.Errorf("kconfig %s not found in .kconfig", rel.Name)
		}

	default:
		return fmt.Errorf("relocation to %q: %w", target.Name, ErrNotSupported)
	}

	*ins = ins.WithReference(name)
	return nil
}

func (ec *elfCode) loadMaps() error {
	for _, sec := range ec.sections {
		if sec.kind != mapSection {
			continue
		}

		nSym := len(sec.symbols)
		if nSym == 0 {
			return fmt.Errorf("section %v: no symbols", sec.Name)
		}

		if sec.Size%uint64(nSym) != 0 {
			return fmt.Errorf("section %v: map descriptors are not of equal size", sec.Name)
		}

		var (
			r    = bufio.NewReader(sec.Open())
			size = sec.Size / uint64(nSym)
		)
		for i, offset := 0, uint64(0); i < nSym; i, offset = i+1, offset+size {
			mapSym, ok := sec.symbols[offset]
			if !ok {
				return fmt.Errorf("section %s: missing symbol for map at offset %d", sec.Name, offset)
			}

			mapName := mapSym.Name
			if ec.maps[mapName] != nil {
				return fmt.Errorf("section %v: map %v already exists", sec.Name, mapSym)
			}

			lr := io.LimitReader(r, int64(size))

			spec := MapSpec{
				Name: SanitizeName(mapName, -1),
			}
			switch {
			case binary.Read(lr, ec.ByteOrder, &spec.Type) != nil:
				return fmt.Errorf("map %s: missing type", mapName)
			case binary.Read(lr, ec.ByteOrder, &spec.KeySize) != nil:
				return fmt.Errorf("map %s: missing key size", mapName)
			case binary.Read(lr, ec.ByteOrder, &spec.ValueSize) != nil:
				return fmt.Errorf("map %s: missing value size", mapName)
			case binary.Read(lr, ec.ByteOrder, &spec.MaxEntries) != nil:
				return fmt.Errorf("map %s: missing max entries", mapName)
			case binary.Read(lr, ec.ByteOrder, &spec.Flags) != nil:
				return fmt.Errorf("map %s: missing flags", mapName)
			}

			extra, err := io.ReadAll(lr)
			if err != nil {
				return fmt.Errorf("map %s: reading map tail: %w", mapName, err)
			}
			if len(extra) > 0 {
				spec.Extra = bytes.NewReader(extra)
			}

			ec.maps[mapName] = &spec
		}
	}

	return nil
}

// loadBTFMaps iterates over all ELF sections marked as BTF map sections
// (like .maps) and parses them into MapSpecs. Dump the .maps section and
// any relocations with `readelf -x .maps -r <elf_file>`.
func (ec *elfCode) loadBTFMaps() error {
	for _, sec := range ec.sections {
		if sec.kind != btfMapSection {
			continue
		}

		if ec.btf == nil {
			return fmt.Errorf("missing BTF")
		}

		// Each section must appear as a DataSec in the ELF's BTF blob.
		var ds *btf.Datasec
		if err := ec.btf.TypeByName(sec.Name, &ds); err != nil {
			return fmt.Errorf("cannot find section '%s' in BTF: %w", sec.Name, err)
		}

		// Open a Reader to the ELF's raw section bytes so we can assert that all
		// of them are zero on a per-map (per-Var) basis. For now, the section's
		// sole purpose is to receive relocations, so all must be zero.
		rs := sec.Open()

		for _, vs := range ds.Vars {
			// BPF maps are declared as and assigned to global variables,
			// so iterate over each Var in the DataSec and validate their types.
			v, ok := vs.Type.(*btf.Var)
			if !ok {
				return fmt.Errorf("section %v: unexpected type %s", sec.Name, vs.Type)
			}
			name := string(v.Name)

			// The BTF metadata for each Var contains the full length of the map
			// declaration, so read the corresponding amount of bytes from the ELF.
			// This way, we can pinpoint which map declaration contains unexpected
			// (and therefore unsupported) data.
			_, err := io.Copy(internal.DiscardZeroes{}, io.LimitReader(rs, int64(vs.Size)))
			if err != nil {
				return fmt.Errorf("section %v: map %s: initializing BTF map definitions: %w", sec.Name, name, internal.ErrNotSupported)
			}

			if ec.maps[name] != nil {
				return fmt.Errorf("section %v: map %s already exists", sec.Name, name)
			}

			// Each Var representing a BTF map definition contains a Struct.
			mapStruct, ok := btf.UnderlyingType(v.Type).(*btf.Struct)
			if !ok {
				return fmt.Errorf("expected struct, got %s", v.Type)
			}

			mapSpec, err := mapSpecFromBTF(sec, &vs, mapStruct, ec.btf, name, false)
			if err != nil {
				return fmt.Errorf("map %v: %w", name, err)
			}

			ec.maps[name] = mapSpec
		}

		// Drain the ELF section reader to make sure all bytes are accounted for
		// with BTF metadata.
		i, err := io.Copy(io.Discard, rs)
		if err != nil {
			return fmt.Errorf("section %v: unexpected error reading remainder of ELF section: %w", sec.Name, err)
		}
		if i > 0 {
			return fmt.Errorf("section %v: %d unexpected remaining bytes in ELF section, invalid BTF?", sec.Name, i)
		}
	}

	return nil
}

// mapSpecFromBTF produces a MapSpec based on a btf.Struct def representing
// a BTF map definition. The name and spec arguments will be copied to the
// resulting MapSpec, and inner must be true on any recursive invocations.
func mapSpecFromBTF(es *elfSection, vs *btf.VarSecinfo, def *btf.Struct, spec *btf.Spec, name string, inner bool) (*MapSpec, error) {
	var (
		key, value         btf.Type
		keySize, valueSize uint32
		mapType            MapType
		flags, maxEntries  uint32
		pinType            PinType
		innerMapSpec       *MapSpec
		contents           []MapKV
		err                error
	)

	for i, member := range def.Members {
		switch member.Name {
		case "type":
			mt, err := uintFromBTF(member.Type)
			if err != nil {
				return nil, fmt.Errorf("can't get type: %w", err)
			}
			mapType = MapType(mt)

		case "map_flags":
			flags, err = uintFromBTF(member.Type)
			if err != nil {
				return nil, fmt.Errorf("can't get BTF map flags: %w", err)
			}

		case "max_entries":
			maxEntries, err = uintFromBTF(member.Type)
			if err != nil {
				return nil, fmt.Errorf("can't get BTF map max entries: %w", err)
			}

		case "key":
			if keySize != 0 {
				return nil, errors.New("both key and key_size given")
			}

			pk, ok := member.Type.(*btf.Pointer)
			if !ok {
				return nil, fmt.Errorf("key type is not a pointer: %T", member.Type)
			}

			key = pk.Target

			size, err := btf.Sizeof(pk.Target)
			if err != nil {
				return nil, fmt.Errorf("can't get size of BTF key: %w", err)
			}

			keySize = uint32(size)

		case "value":
			if valueSize != 0 {
				return nil, errors.New("both value and value_size given")
			}

			vk, ok := member.Type.(*btf.Pointer)
			if !ok {
				return nil, fmt.Errorf("value type is not a pointer: %T", member.Type)
			}

			value = vk.Target

			size, err := btf.Sizeof(vk.Target)
			if err != nil {
				return nil, fmt.Errorf("can't get size of BTF value: %w", err)
			}

			valueSize = uint32(size)

		case "key_size":
			// Key needs to be nil and keySize needs to be 0 for key_size to be
			// considered a valid member.
			if key != nil || keySize != 0 {
				return nil, errors.New("both key and key_size given")
			}

			keySize, err = uintFromBTF(member.Type)
			if err != nil {
				return nil, fmt.Errorf("can't get BTF key size: %w", err)
			}

		case "value_size":
			// Value needs to be nil and valueSize needs to be 0 for value_size to be
			// considered a valid member.
			if value != nil || valueSize != 0 {
				return nil, errors.New("both value and value_size given")
			}

			valueSize, err = uintFromBTF(member.Type)
			if err != nil {
				return nil, fmt.Errorf("can't get BTF value size: %w", err)
			}

		case "pinning":
			if inner {
				return nil, errors.New("inner maps can't be pinned")
			}

			pinning, err := uintFromBTF(member.Type)
			if err != nil {
				return nil, fmt.Errorf("can't get pinning: %w", err)
			}

			pinType = PinType(pinning)

		case "values":
			// The 'values' field in BTF map definitions is used for declaring map
			// value types that are references to other BPF objects, like other maps
			// or programs. It is always expected to be an array of pointers.
			if i != len(def.Members)-1 {
				return nil, errors.New("'values' must be the last member in a BTF map definition")
			}

			if valueSize != 0 && valueSize != 4 {
				return nil, errors.New("value_size must be 0 or 4")
			}
			valueSize = 4

			valueType, err := resolveBTFArrayMacro(member.Type)
			if err != nil {
				return nil, fmt.Errorf("can't resolve type of member 'values': %w", err)
			}

			switch t := valueType.(type) {
			case *btf.Struct:
				// The values member pointing to an array of structs means we're expecting
				// a map-in-map declaration.
				if mapType != ArrayOfMaps && mapType != HashOfMaps {
					return nil, errors.New("outer map needs to be an array or a hash of maps")
				}
				if inner {
					return nil, fmt.Errorf("nested inner maps are not supported")
				}

				// This inner map spec is used as a map template, but it needs to be
				// created as a traditional map before it can be used to do so.
				// libbpf names the inner map template '<outer_name>.inner', but we
				// opted for _inner to simplify validation logic. (dots only supported
				// on kernels 5.2 and up)
				// Pass the BTF spec from the parent object, since both parent and
				// child must be created from the same BTF blob (on kernels that support BTF).
				innerMapSpec, err = mapSpecFromBTF(es, vs, t, spec, name+"_inner", true)
				if err != nil {
					return nil, fmt.Errorf("can't parse BTF map definition of inner map: %w", err)
				}

			case *btf.FuncProto:
				// The values member contains an array of function pointers, meaning an
				// autopopulated PROG_ARRAY.
				if mapType != ProgramArray {
					return nil, errors.New("map needs to be a program array")
				}

			default:
				return nil, fmt.Errorf("unsupported value type %q in 'values' field", t)
			}

			contents, err = resolveBTFValuesContents(es, vs, member)
			if err != nil {
				return nil, fmt.Errorf("resolving values contents: %w", err)
			}

		default:
			return nil, fmt.Errorf("unrecognized field %s in BTF map definition", member.Name)
		}
	}

	return &MapSpec{
		Name:       SanitizeName(name, -1),
		Type:       MapType(mapType),
		KeySize:    keySize,
		ValueSize:  valueSize,
		MaxEntries: maxEntries,
		Flags:      flags,
		Key:        key,
		Value:      value,
		Pinning:    pinType,
		InnerMap:   innerMapSpec,
		Contents:   contents,
	}, nil
}

// uintFromBTF resolves the __uint macro, which is a pointer to a sized
// array, e.g. for int (*foo)[10], this function will return 10.
func uintFromBTF(typ btf.Type) (uint32, error) {
	ptr, ok := typ.(*btf.Pointer)
	if !ok {
		return 0, fmt.Errorf("not a pointer: %v", typ)
	}

	arr, ok := ptr.Target.(*btf.Array)
	if !ok {
		return 0, fmt.Errorf("not a pointer to array: %v", typ)
	}

	return arr.Nelems, nil
}

// resolveBTFArrayMacro resolves the __array macro, which declares an array
// of pointers to a given type. This function returns the target Type of
// the pointers in the array.
func resolveBTFArrayMacro(typ btf.Type) (btf.Type, error) {
	arr, ok := typ.(*btf.Array)
	if !ok {
		return nil, fmt.Errorf("not an array: %v", typ)
	}

	ptr, ok := arr.Type.(*btf.Pointer)
	if !ok {
		return nil, fmt.Errorf("not an array of pointers: %v", typ)
	}

	return ptr.Target, nil
}

// resolveBTFValuesContents resolves relocations into ELF sections belonging
// to btf.VarSecinfo's. This can be used on the 'values' member in BTF map
// definitions to extract static declarations of map contents.
func resolveBTFValuesContents(es *elfSection, vs *btf.VarSecinfo, member btf.Member) ([]MapKV, error) {
	// The elements of a .values pointer array are not encoded in BTF.
	// Instead, relocations are generated into each array index.
	// However, it's possible to leave certain array indices empty, so all
	// indices' offsets need to be checked for emitted relocations.

	// The offset of the 'values' member within the _struct_ (in bits)
	// is the starting point of the array. Convert to bytes. Add VarSecinfo
	// offset to get the absolute position in the ELF blob.
	start := member.Offset.Bytes() + vs.Offset
	// 'values' is encoded in BTF as a zero (variable) length struct
	// member, and its contents run until the end of the VarSecinfo.
	// Add VarSecinfo offset to get the absolute position in the ELF blob.
	end := vs.Size + vs.Offset
	// The size of an address in this section. This determines the width of
	// an index in the array.
	align := uint32(es.SectionHeader.Addralign)

	// Check if variable-length section is aligned.
	if (end-start)%align != 0 {
		return nil, errors.New("unaligned static values section")
	}
	elems := (end - start) / align

	if elems == 0 {
		return nil, nil
	}

	contents := make([]MapKV, 0, elems)

	// k is the array index, off is its corresponding ELF section offset.
	for k, off := uint32(0), start; k < elems; k, off = k+1, off+align {
		r, ok := es.relocations[uint64(off)]
		if !ok {
			continue
		}

		// Relocation exists for the current offset in the ELF section.
		// Emit a value stub based on the type of relocation to be replaced by
		// a real fd later in the pipeline before populating the map.
		// Map keys are encoded in MapKV entries, so empty array indices are
		// skipped here.
		switch t := elf.ST_TYPE(r.Info); t {
		case elf.STT_FUNC:
			contents = append(contents, MapKV{uint32(k), r.Name})
		case elf.STT_OBJECT:
			contents = append(contents, MapKV{uint32(k), r.Name})
		default:
			return nil, fmt.Errorf("unknown relocation type %v for symbol %s", t, r.Name)
		}
	}

	return contents, nil
}

func (ec *elfCode) loadDataSections() error {
	for _, sec := range ec.sections {
		if sec.kind != dataSection {
			continue
		}

		if sec.references == 0 {
			// Prune data sections which are not referenced by any
			// instructions.
			continue
		}

		mapSpec := &MapSpec{
			Name:       SanitizeName(sec.Name, -1),
			Type:       Array,
			KeySize:    4,
			ValueSize:  uint32(sec.Size),
			MaxEntries: 1,
		}

		switch sec.Type {
		// Only open the section if we know there's actual data to be read.
		case elf.SHT_PROGBITS:
			data, err := sec.Data()
			if err != nil {
				return fmt.Errorf("data section %s: can't get contents: %w", sec.Name, err)
			}

			if uint64(len(data)) > math.MaxUint32 {
				return fmt.Errorf("data section %s: contents exceed maximum size", sec.Name)
			}
			mapSpec.Contents = []MapKV{{uint32(0), data}}

		case elf.SHT_NOBITS:
			// NOBITS sections like .bss contain only zeroes, and since data sections
			// are Arrays, the kernel already preallocates them. Skip reading zeroes
			// from the ELF.
		default:
			return fmt.Errorf("data section %s: unknown section type %s", sec.Name, sec.Type)
		}

		// It is possible for a data section to exist without a corresponding BTF Datasec
		// if it only contains anonymous values like macro-defined arrays.
		if ec.btf != nil {
			var ds *btf.Datasec
			if ec.btf.TypeByName(sec.Name, &ds) == nil {
				// Assign the spec's key and BTF only if the Datasec lookup was successful.
				mapSpec.Key = &btf.Void{}
				mapSpec.Value = ds
			}
		}

		if strings.HasPrefix(sec.Name, ".rodata") {
			mapSpec.Flags = unix.BPF_F_RDONLY_PROG
			mapSpec.Freeze = true
		}

		ec.maps[sec.Name] = mapSpec
	}

	return nil
}

// loadKconfigSection handles the 'virtual' Datasec .kconfig that doesn't
// have a corresponding ELF section and exist purely in BTF.
func (ec *elfCode) loadKconfigSection() error {
	if ec.btf == nil {
		return nil
	}

	var ds *btf.Datasec
	err := ec.btf.TypeByName(".kconfig", &ds)
	if errors.Is(err, btf.ErrNotFound) {
		return nil
	}
	if err != nil {
		return err
	}

	if ds.Size == 0 {
		return errors.New("zero-length .kconfig")
	}

	ec.kconfig = &MapSpec{
		Name:       ".kconfig",
		Type:       Array,
		KeySize:    uint32(4),
		ValueSize:  ds.Size,
		MaxEntries: 1,
		Flags:      unix.BPF_F_RDONLY_PROG,
		Freeze:     true,
		Key:        &btf.Int{Size: 4},
		Value:      ds,
	}

	return nil
}

// loadKsymsSection handles the 'virtual' Datasec .ksyms that doesn't
// have a corresponding ELF section and exist purely in BTF.
func (ec *elfCode) loadKsymsSection() error {
	if ec.btf == nil {
		return nil
	}

	var ds *btf.Datasec
	err := ec.btf.TypeByName(".ksyms", &ds)
	if errors.Is(err, btf.ErrNotFound) {
		return nil
	}
	if err != nil {
		return err
	}

	for _, v := range ds.Vars {
		// we have already checked the .ksyms Datasec to only contain Func Vars.
		ec.kfuncs[v.Type.TypeName()] = v.Type.(*btf.Func)
	}

	return nil
}

func getProgType(sectionName string) (ProgramType, AttachType, uint32, string) {
	types := []struct {
		prefix     string
		progType   ProgramType
		attachType AttachType
		progFlags  uint32
	}{
		// Please update the types from libbpf.c and follow the order of it.
		// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/lib/bpf/libbpf.c
		{"socket", SocketFilter, AttachNone, 0},
		{"sk_reuseport/migrate", SkReuseport, AttachSkReuseportSelectOrMigrate, 0},
		{"sk_reuseport", SkReuseport, AttachSkReuseportSelect, 0},
		{"kprobe/", Kprobe, AttachNone, 0},
		{"uprobe/", Kprobe, AttachNone, 0},
		{"kretprobe/", Kprobe, AttachNone, 0},
		{"uretprobe/", Kprobe, AttachNone, 0},
		{"tc", SchedCLS, AttachNone, 0},
		{"classifier", SchedCLS, AttachNone, 0},
		{"action", SchedACT, AttachNone, 0},
		{"tracepoint/", TracePoint, AttachNone, 0},
		{"tp/", TracePoint, AttachNone, 0},
		{"raw_tracepoint/", RawTracepoint, AttachNone, 0},
		{"raw_tp/", RawTracepoint, AttachNone, 0},
		{"raw_tracepoint.w/", RawTracepointWritable, AttachNone, 0},
		{"raw_tp.w/", RawTracepointWritable, AttachNone, 0},
		{"tp_btf/", Tracing, AttachTraceRawTp, 0},
		{"fentry/", Tracing, AttachTraceFEntry, 0},
		{"fmod_ret/", Tracing, AttachModifyReturn, 0},
		{"fexit/", Tracing, AttachTraceFExit, 0},
		{"fentry.s/", Tracing, AttachTraceFEntry, unix.BPF_F_SLEEPABLE},
		{"fmod_ret.s/", Tracing, AttachModifyReturn, unix.BPF_F_SLEEPABLE},
		{"fexit.s/", Tracing, AttachTraceFExit, unix.BPF_F_SLEEPABLE},
		{"freplace/", Extension, AttachNone, 0},
		{"lsm/", LSM, AttachLSMMac, 0},
		{"lsm.s/", LSM, AttachLSMMac, unix.BPF_F_SLEEPABLE},
		{"iter/", Tracing, AttachTraceIter, 0},
		{"iter.s/", Tracing, AttachTraceIter, unix.BPF_F_SLEEPABLE},
		{"syscall", Syscall, AttachNone, 0},
		{"xdp.frags_devmap/", XDP, AttachXDPDevMap, unix.BPF_F_XDP_HAS_FRAGS},
		{"xdp_devmap/", XDP, AttachXDPDevMap, 0},
		{"xdp.frags_cpumap/", XDP, AttachXDPCPUMap, unix.BPF_F_XDP_HAS_FRAGS},
		{"xdp_cpumap/", XDP, AttachXDPCPUMap, 0},
		{"xdp.frags", XDP, AttachNone, unix.BPF_F_XDP_HAS_FRAGS},
		{"xdp", XDP, AttachNone, 0},
		{"perf_event", PerfEvent, AttachNone, 0},
		{"lwt_in", LWTIn, AttachNone, 0},
		{"lwt_out", LWTOut, AttachNone, 0},
		{"lwt_xmit", LWTXmit, AttachNone, 0},
		{"lwt_seg6local", LWTSeg6Local, AttachNone, 0},
		{"cgroup_skb/ingress", CGroupSKB, AttachCGroupInetIngress, 0},
		{"cgroup_skb/egress", CGroupSKB, AttachCGroupInetEgress, 0},
		{"cgroup/skb", CGroupSKB, AttachNone, 0},
		{"cgroup/sock_create", CGroupSock, AttachCGroupInetSockCreate, 0},
		{"cgroup/sock_release", CGroupSock, AttachCgroupInetSockRelease, 0},
		{"cgroup/sock", CGroupSock, AttachCGroupInetSockCreate, 0},
		{"cgroup/post_bind4", CGroupSock, AttachCGroupInet4PostBind, 0},
		{"cgroup/post_bind6", CGroupSock, AttachCGroupInet6PostBind, 0},
		{"cgroup/dev", CGroupDevice, AttachCGroupDevice, 0},
		{"sockops", SockOps, AttachCGroupSockOps, 0},
		{"sk_skb/stream_parser", SkSKB, AttachSkSKBStreamParser, 0},
		{"sk_skb/stream_verdict", SkSKB, AttachSkSKBStreamVerdict, 0},
		{"sk_skb", SkSKB, AttachNone, 0},
		{"sk_msg", SkMsg, AttachSkMsgVerdict, 0},
		{"lirc_mode2", LircMode2, AttachLircMode2, 0},
		{"flow_dissector", FlowDissector, AttachFlowDissector, 0},
		{"cgroup/bind4", CGroupSockAddr, AttachCGroupInet4Bind, 0},
		{"cgroup/bind6", CGroupSockAddr, AttachCGroupInet6Bind, 0},
		{"cgroup/connect4", CGroupSockAddr, AttachCGroupInet4Connect, 0},
		{"cgroup/connect6", CGroupSockAddr, AttachCGroupInet6Connect, 0},
		{"cgroup/sendmsg4", CGroupSockAddr, AttachCGroupUDP4Sendmsg, 0},
		{"cgroup/sendmsg6", CGroupSockAddr, AttachCGroupUDP6Sendmsg, 0},
		{"cgroup/recvmsg4", CGroupSockAddr, AttachCGroupUDP4Recvmsg, 0},
		{"cgroup/recvmsg6", CGroupSockAddr, AttachCGroupUDP6Recvmsg, 0},
		{"cgroup/getpeername4", CGroupSockAddr, AttachCgroupInet4GetPeername, 0},
		{"cgroup/getpeername6", CGroupSockAddr, AttachCgroupInet6GetPeername, 0},
		{"cgroup/getsockname4", CGroupSockAddr, AttachCgroupInet4GetSockname, 0},
		{"cgroup/getsockname6", CGroupSockAddr, AttachCgroupInet6GetSockname, 0},
		{"cgroup/sysctl", CGroupSysctl, AttachCGroupSysctl, 0},
		{"cgroup/getsockopt", CGroupSockopt, AttachCGroupGetsockopt, 0},
		{"cgroup/setsockopt", CGroupSockopt, AttachCGroupSetsockopt, 0},
		{"struct_ops+", StructOps, AttachNone, 0},
		{"sk_lookup/", SkLookup, AttachSkLookup, 0},
		{"seccomp", SocketFilter, AttachNone, 0},
		{"kprobe.multi", Kprobe, AttachTraceKprobeMulti, 0},
		{"kretprobe.multi", Kprobe, AttachTraceKprobeMulti, 0},
		// Document all prefixes in docs/ebpf/concepts/elf-sections.md.
	}

	for _, t := range types {
		if !strings.HasPrefix(sectionName, t.prefix) {
			continue
		}

		if !strings.HasSuffix(t.prefix, "/") {
			return t.progType, t.attachType, t.progFlags, ""
		}

		return t.progType, t.attachType, t.progFlags, sectionName[len(t.prefix):]
	}

	return UnspecifiedProgram, AttachNone, 0, ""
}

func (ec *elfCode) loadSectionRelocations(sec *elf.Section, symbols []elf.Symbol) (map[uint64]elf.Symbol, error) {
	rels := make(map[uint64]elf.Symbol)

	if sec.Entsize < 16 {
		return nil, fmt.Errorf("section %s: relocations are less than 16 bytes", sec.Name)
	}

	r := bufio.NewReader(sec.Open())
	for off := uint64(0); off < sec.Size; off += sec.Entsize {
		ent := io.LimitReader(r, int64(sec.Entsize))

		var rel elf.Rel64
		if binary.Read(ent, ec.ByteOrder, &rel) != nil {
			return nil, fmt.Errorf("can't parse relocation at offset %v", off)
		}

		symNo := int(elf.R_SYM64(rel.Info) - 1)
		if symNo >= len(symbols) {
			return nil, fmt.Errorf("offset %d: symbol %d doesn't exist", off, symNo)
		}

		symbol := symbols[symNo]
		rels[rel.Off] = symbol
	}

	return rels, nil
}
