// Copyright 2022 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 gosym

import (
	"encoding/binary"
	"io"
	"strings"

	sv "golang.org/x/mod/semver"
	"golang.org/x/vuln/internal/semver"
)

const (
	funcSymNameGo119Lower string = "go.func.*"
	funcSymNameGo120      string = "go:func.*"
)

// FuncSymName returns symbol name for Go functions
// used in binaries based on Go version. Supported
// Go versions are 1.18, 1.19, and 1.20. Otherwise,
// returns an empty string.
func FuncSymName(goVersion string) string {
	// Support devel goX.Y...
	v := strings.TrimPrefix(goVersion, "devel ")
	v = semver.GoTagToSemver(v)
	mm := sv.MajorMinor(v)
	if mm == "v1.18" || mm == "v1.19" {
		return funcSymNameGo119Lower
	} else if mm == "v1.20" {
		return funcSymNameGo120
	} else if v == "" && strings.HasPrefix(goVersion, "devel") {
		// We currently don't have a direct way of mapping
		// Go versions of the form devel <hash> to semver,
		// so we map it to the most recent supported major
		// Go version, which is currently go1.20.
		return funcSymNameGo120
	}
	return ""
}

// Additions to the original package from cmd/internal/objabi/funcdata.go
const (
	pcdata_InlTreeIndex = 2
	funcdata_InlTree    = 3
)

// InlineTree returns the inline tree for Func f as a sequence of InlinedCalls.
// goFuncValue is the value of the gosym.FuncSymName symbol.
// baseAddr is the address of the memory region (ELF Prog) containing goFuncValue.
// progReader is a ReaderAt positioned at the start of that region.
func (t *LineTable) InlineTree(f *Func, goFuncValue, baseAddr uint64, progReader io.ReaderAt) ([]InlinedCall, error) {
	if f.inlineTreeCount == 0 {
		return nil, nil
	}
	if f.inlineTreeOffset == ^uint32(0) {
		return nil, nil
	}
	var offset int64
	if t.version >= ver118 {
		offset = int64(goFuncValue - baseAddr + uint64(f.inlineTreeOffset))
	} else {
		offset = int64(uint64(f.inlineTreeOffset) - baseAddr)
	}

	r := io.NewSectionReader(progReader, offset, 1<<32) // pick a size larger than we need
	var ics []InlinedCall
	for i := 0; i < f.inlineTreeCount; i++ {
		if t.version >= ver120 {
			var ric rawInlinedCall120
			if err := binary.Read(r, t.binary, &ric); err != nil {
				return nil, err
			}
			ics = append(ics, InlinedCall{
				FuncID:   ric.FuncID,
				Name:     t.funcName(uint32(ric.NameOff)),
				ParentPC: ric.ParentPC,
			})
		} else {
			var ric rawInlinedCall112
			if err := binary.Read(r, t.binary, &ric); err != nil {
				return nil, err
			}
			ics = append(ics, InlinedCall{
				FuncID:   ric.FuncID,
				Name:     t.funcName(uint32(ric.Func_)),
				ParentPC: ric.ParentPC,
			})
		}
	}
	return ics, nil
}

// InlinedCall describes a call to an inlined function.
type InlinedCall struct {
	FuncID   uint8  // type of the called function
	Name     string // name of called function
	ParentPC int32  // position of an instruction whose source position is the call site (offset from entry)
}

// rawInlinedCall112 is the encoding of entries in the FUNCDATA_InlTree table
// from Go 1.12 through 1.19. It is equivalent to runtime.inlinedCall.
type rawInlinedCall112 struct {
	Parent   int16 // index of parent in the inltree, or < 0
	FuncID   uint8 // type of the called function
	_        byte
	File     int32 // perCU file index for inlined call. See cmd/link:pcln.go
	Line     int32 // line number of the call site
	Func_    int32 // offset into pclntab for name of called function
	ParentPC int32 // position of an instruction whose source position is the call site (offset from entry)
}

// rawInlinedCall120 is the encoding of entries in the FUNCDATA_InlTree table
// from Go 1.20. It is equivalent to runtime.inlinedCall.
type rawInlinedCall120 struct {
	FuncID    uint8 // type of the called function
	_         [3]byte
	NameOff   int32 // offset into pclntab for name of called function
	ParentPC  int32 // position of an instruction whose source position is the call site (offset from entry)
	StartLine int32 // line number of start of function (func keyword/TEXT directive)
}

func (f funcData) npcdata() uint32 { return f.field(7) }
func (f funcData) nfuncdata(numFuncFields uint32) uint32 {
	return uint32(f.data[f.fieldOffset(numFuncFields-1)+3])
}

func (f funcData) funcdataOffset(i uint8, numFuncFields uint32) uint32 {
	if uint32(i) >= f.nfuncdata(numFuncFields) {
		return ^uint32(0)
	}
	var off uint32
	if f.t.version >= ver118 {
		off = f.fieldOffset(numFuncFields) + // skip fixed part of _func
			f.npcdata()*4 + // skip pcdata
			uint32(i)*4 // index of i'th FUNCDATA
	} else {
		off = f.fieldOffset(numFuncFields) + // skip fixed part of _func
			f.npcdata()*4
		off += uint32(i) * f.t.ptrsize
	}
	return f.t.binary.Uint32(f.data[off:])
}

func (f funcData) fieldOffset(n uint32) uint32 {
	// In Go 1.18, the first field of _func changed
	// from a uintptr entry PC to a uint32 entry offset.
	sz0 := f.t.ptrsize
	if f.t.version >= ver118 {
		sz0 = 4
	}
	return sz0 + (n-1)*4 // subsequent fields are 4 bytes each
}

func (f funcData) pcdataOffset(i uint8, numFuncFields uint32) uint32 {
	if uint32(i) >= f.npcdata() {
		return ^uint32(0)
	}
	off := f.fieldOffset(numFuncFields) + // skip fixed part of _func
		uint32(i)*4 // index of i'th PCDATA
	return f.t.binary.Uint32(f.data[off:])
}

// maxInlineTreeIndexValue returns the maximum value of the inline tree index
// pc-value table in info. This is the only way to determine how many
// IndexedCalls are in an inline tree, since the data of the tree itself is not
// delimited in any way.
func (t *LineTable) maxInlineTreeIndexValue(info funcData, numFuncFields uint32) int {
	if info.npcdata() <= pcdata_InlTreeIndex {
		return -1
	}
	off := info.pcdataOffset(pcdata_InlTreeIndex, numFuncFields)
	p := t.pctab[off:]
	val := int32(-1)
	max := int32(-1)
	var pc uint64
	for t.step(&p, &pc, &val, pc == 0) {
		if val > max {
			max = val
		}
	}
	return int(max)
}

type inlTree struct {
	inlineTreeOffset uint32 // offset from go.func.* symbol
	inlineTreeCount  int    // number of entries in inline tree
}
