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

package sym

import (
	"cmd/internal/objabi"
	"cmd/internal/sys"
	"debug/elf"
	"fmt"
	"log"
)

// Symbol is an entry in the symbol table.
type Symbol struct {
	Name        string
	Extname     string
	Type        SymKind
	Version     int16
	Attr        Attribute
	Localentry  uint8
	Dynid       int32
	Plt         int32
	Got         int32
	Align       int32
	Elfsym      int32
	LocalElfsym int32
	Value       int64
	Size        int64
	// ElfType is set for symbols read from shared libraries by ldshlibsyms. It
	// is not set for symbols defined by the packages being linked or by symbols
	// read by ldelf (and so is left as elf.STT_NOTYPE).
	ElfType     elf.SymType
	Sub         *Symbol
	Outer       *Symbol
	Gotype      *Symbol
	Reachparent *Symbol
	File        string
	Dynimplib   string
	Dynimpvers  string
	Sect        *Section
	FuncInfo    *FuncInfo
	Lib         *Library // Package defining this symbol
	// P contains the raw symbol data.
	P []byte
	R []Reloc
}

func (s *Symbol) String() string {
	if s.Version == 0 {
		return s.Name
	}
	return fmt.Sprintf("%s<%d>", s.Name, s.Version)
}

func (s *Symbol) ElfsymForReloc() int32 {
	// If putelfsym created a local version of this symbol, use that in all
	// relocations.
	if s.LocalElfsym != 0 {
		return s.LocalElfsym
	} else {
		return s.Elfsym
	}
}

func (s *Symbol) Len() int64 {
	return s.Size
}

func (s *Symbol) Grow(siz int64) {
	if int64(int(siz)) != siz {
		log.Fatalf("symgrow size %d too long", siz)
	}
	if int64(len(s.P)) >= siz {
		return
	}
	if cap(s.P) < int(siz) {
		p := make([]byte, 2*(siz+1))
		s.P = append(p[:0], s.P...)
	}
	s.P = s.P[:siz]
}

func (s *Symbol) AddBytes(bytes []byte) int64 {
	if s.Type == 0 {
		s.Type = SDATA
	}
	s.Attr |= AttrReachable
	s.P = append(s.P, bytes...)
	s.Size = int64(len(s.P))

	return s.Size
}

func (s *Symbol) AddUint8(v uint8) int64 {
	off := s.Size
	if s.Type == 0 {
		s.Type = SDATA
	}
	s.Attr |= AttrReachable
	s.Size++
	s.P = append(s.P, v)

	return off
}

func (s *Symbol) AddUint16(arch *sys.Arch, v uint16) int64 {
	return s.AddUintXX(arch, uint64(v), 2)
}

func (s *Symbol) AddUint32(arch *sys.Arch, v uint32) int64 {
	return s.AddUintXX(arch, uint64(v), 4)
}

func (s *Symbol) AddUint64(arch *sys.Arch, v uint64) int64 {
	return s.AddUintXX(arch, v, 8)
}

func (s *Symbol) AddUint(arch *sys.Arch, v uint64) int64 {
	return s.AddUintXX(arch, v, arch.PtrSize)
}

func (s *Symbol) SetUint8(arch *sys.Arch, r int64, v uint8) int64 {
	return s.setUintXX(arch, r, uint64(v), 1)
}

func (s *Symbol) SetUint32(arch *sys.Arch, r int64, v uint32) int64 {
	return s.setUintXX(arch, r, uint64(v), 4)
}

func (s *Symbol) SetUint(arch *sys.Arch, r int64, v uint64) int64 {
	return s.setUintXX(arch, r, v, int64(arch.PtrSize))
}

func (s *Symbol) addAddrPlus(arch *sys.Arch, t *Symbol, add int64, typ objabi.RelocType) int64 {
	if s.Type == 0 {
		s.Type = SDATA
	}
	s.Attr |= AttrReachable
	i := s.Size
	s.Size += int64(arch.PtrSize)
	s.Grow(s.Size)
	r := s.AddRel()
	r.Sym = t
	r.Off = int32(i)
	r.Siz = uint8(arch.PtrSize)
	r.Type = typ
	r.Add = add
	return i + int64(r.Siz)
}

func (s *Symbol) AddAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
	return s.addAddrPlus(arch, t, add, objabi.R_ADDR)
}

func (s *Symbol) AddCURelativeAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
	return s.addAddrPlus(arch, t, add, objabi.R_ADDRCUOFF)
}

func (s *Symbol) AddPCRelPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
	if s.Type == 0 {
		s.Type = SDATA
	}
	s.Attr |= AttrReachable
	i := s.Size
	s.Size += 4
	s.Grow(s.Size)
	r := s.AddRel()
	r.Sym = t
	r.Off = int32(i)
	r.Add = add
	r.Type = objabi.R_PCREL
	r.Siz = 4
	if arch.Family == sys.S390X {
		r.Variant = RV_390_DBL
	}
	return i + int64(r.Siz)
}

func (s *Symbol) AddAddr(arch *sys.Arch, t *Symbol) int64 {
	return s.AddAddrPlus(arch, t, 0)
}

func (s *Symbol) SetAddrPlus(arch *sys.Arch, off int64, t *Symbol, add int64) int64 {
	if s.Type == 0 {
		s.Type = SDATA
	}
	s.Attr |= AttrReachable
	if off+int64(arch.PtrSize) > s.Size {
		s.Size = off + int64(arch.PtrSize)
		s.Grow(s.Size)
	}

	r := s.AddRel()
	r.Sym = t
	r.Off = int32(off)
	r.Siz = uint8(arch.PtrSize)
	r.Type = objabi.R_ADDR
	r.Add = add
	return off + int64(r.Siz)
}

func (s *Symbol) SetAddr(arch *sys.Arch, off int64, t *Symbol) int64 {
	return s.SetAddrPlus(arch, off, t, 0)
}

func (s *Symbol) AddSize(arch *sys.Arch, t *Symbol) int64 {
	if s.Type == 0 {
		s.Type = SDATA
	}
	s.Attr |= AttrReachable
	i := s.Size
	s.Size += int64(arch.PtrSize)
	s.Grow(s.Size)
	r := s.AddRel()
	r.Sym = t
	r.Off = int32(i)
	r.Siz = uint8(arch.PtrSize)
	r.Type = objabi.R_SIZE
	return i + int64(r.Siz)
}

func (s *Symbol) AddAddrPlus4(t *Symbol, add int64) int64 {
	if s.Type == 0 {
		s.Type = SDATA
	}
	s.Attr |= AttrReachable
	i := s.Size
	s.Size += 4
	s.Grow(s.Size)
	r := s.AddRel()
	r.Sym = t
	r.Off = int32(i)
	r.Siz = 4
	r.Type = objabi.R_ADDR
	r.Add = add
	return i + int64(r.Siz)
}

func (s *Symbol) AddRel() *Reloc {
	s.R = append(s.R, Reloc{})
	return &s.R[len(s.R)-1]
}

func (s *Symbol) AddUintXX(arch *sys.Arch, v uint64, wid int) int64 {
	off := s.Size
	s.setUintXX(arch, off, v, int64(wid))
	return off
}

func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64 {
	if s.Type == 0 {
		s.Type = SDATA
	}
	s.Attr |= AttrReachable
	if s.Size < off+wid {
		s.Size = off + wid
		s.Grow(s.Size)
	}

	switch wid {
	case 1:
		s.P[off] = uint8(v)
	case 2:
		arch.ByteOrder.PutUint16(s.P[off:], uint16(v))
	case 4:
		arch.ByteOrder.PutUint32(s.P[off:], uint32(v))
	case 8:
		arch.ByteOrder.PutUint64(s.P[off:], v)
	}

	return off + wid
}

// SortSub sorts a linked-list (by Sub) of *Symbol by Value.
// Used for sub-symbols when loading host objects (see e.g. ldelf.go).
func SortSub(l *Symbol) *Symbol {
	if l == nil || l.Sub == nil {
		return l
	}

	l1 := l
	l2 := l
	for {
		l2 = l2.Sub
		if l2 == nil {
			break
		}
		l2 = l2.Sub
		if l2 == nil {
			break
		}
		l1 = l1.Sub
	}

	l2 = l1.Sub
	l1.Sub = nil
	l1 = SortSub(l)
	l2 = SortSub(l2)

	/* set up lead element */
	if l1.Value < l2.Value {
		l = l1
		l1 = l1.Sub
	} else {
		l = l2
		l2 = l2.Sub
	}

	le := l

	for {
		if l1 == nil {
			for l2 != nil {
				le.Sub = l2
				le = l2
				l2 = l2.Sub
			}

			le.Sub = nil
			break
		}

		if l2 == nil {
			for l1 != nil {
				le.Sub = l1
				le = l1
				l1 = l1.Sub
			}

			break
		}

		if l1.Value < l2.Value {
			le.Sub = l1
			le = l1
			l1 = l1.Sub
		} else {
			le.Sub = l2
			le = l2
			l2 = l2.Sub
		}
	}

	le.Sub = nil
	return l
}

type FuncInfo struct {
	Args        int32
	Locals      int32
	Autom       []Auto
	Pcsp        Pcdata
	Pcfile      Pcdata
	Pcline      Pcdata
	Pcinline    Pcdata
	Pcdata      []Pcdata
	Funcdata    []*Symbol
	Funcdataoff []int64
	File        []*Symbol
	InlTree     []InlinedCall
}

// InlinedCall is a node in a local inlining tree (FuncInfo.InlTree).
type InlinedCall struct {
	Parent int32   // index of parent in InlTree
	File   *Symbol // file of the inlined call
	Line   int32   // line number of the inlined call
	Func   *Symbol // function that was inlined
}

type Pcdata struct {
	P []byte
}

type Auto struct {
	Asym    *Symbol
	Gotype  *Symbol
	Aoffset int32
	Name    int16
}
