// Copyright 2012 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 ld

import "cmd/internal/obj"

// Decoding the type.* symbols.	 This has to be in sync with
// ../../runtime/type.go, or more specifically, with what
// ../gc/reflect.c stuffs in these.

func decode_reloc(s *LSym, off int32) *Reloc {
	for i := 0; i < len(s.R); i++ {
		if s.R[i].Off == off {
			return &s.R[i:][0]
		}
	}
	return nil
}

func decode_reloc_sym(s *LSym, off int32) *LSym {
	r := decode_reloc(s, off)
	if r == nil {
		return nil
	}
	return r.Sym
}

func decode_inuxi(p []byte, sz int) uint64 {
	switch sz {
	case 2:
		return uint64(Ctxt.Arch.ByteOrder.Uint16(p))
	case 4:
		return uint64(Ctxt.Arch.ByteOrder.Uint32(p))
	case 8:
		return Ctxt.Arch.ByteOrder.Uint64(p)
	default:
		Exitf("dwarf: decode inuxi %d", sz)
		panic("unreachable")
	}
}

func commonsize() int {
	return 8*Thearch.Ptrsize + 8
}

// Type.commonType.kind
func decodetype_kind(s *LSym) uint8 {
	return uint8(s.P[1*Thearch.Ptrsize+7] & obj.KindMask) //  0x13 / 0x1f
}

// Type.commonType.kind
func decodetype_noptr(s *LSym) uint8 {
	return uint8(s.P[1*Thearch.Ptrsize+7] & obj.KindNoPointers) //  0x13 / 0x1f
}

// Type.commonType.kind
func decodetype_usegcprog(s *LSym) uint8 {
	return uint8(s.P[1*Thearch.Ptrsize+7] & obj.KindGCProg) //  0x13 / 0x1f
}

// Type.commonType.size
func decodetype_size(s *LSym) int64 {
	return int64(decode_inuxi(s.P, Thearch.Ptrsize)) // 0x8 / 0x10
}

// Type.commonType.gc
func decodetype_gcprog(s *LSym) *LSym {
	if s.Type == obj.SDYNIMPORT {
		// The gcprog for "type.$name" is calle "type..gcprog.$name".
		x := "type..gcprog." + s.Name[5:]
		return Linklookup(Ctxt, x, 0)
	}
	return decode_reloc_sym(s, 1*int32(Thearch.Ptrsize)+8+2*int32(Thearch.Ptrsize))
}

func decodetype_gcmask(s *LSym) []byte {
	if s.Type == obj.SDYNIMPORT {
		// ldshlibsyms makes special efforts to read the value
		// of gcmask for types defined in that shared library.
		return s.gcmask
	}
	mask := decode_reloc_sym(s, 1*int32(Thearch.Ptrsize)+8+1*int32(Thearch.Ptrsize))
	return mask.P
}

// Type.ArrayType.elem and Type.SliceType.Elem
func decodetype_arrayelem(s *LSym) *LSym {
	return decode_reloc_sym(s, int32(commonsize())) // 0x1c / 0x30
}

func decodetype_arraylen(s *LSym) int64 {
	return int64(decode_inuxi(s.P[commonsize()+2*Thearch.Ptrsize:], Thearch.Ptrsize))
}

// Type.PtrType.elem
func decodetype_ptrelem(s *LSym) *LSym {
	return decode_reloc_sym(s, int32(commonsize())) // 0x1c / 0x30
}

// Type.MapType.key, elem
func decodetype_mapkey(s *LSym) *LSym {
	return decode_reloc_sym(s, int32(commonsize())) // 0x1c / 0x30
}

func decodetype_mapvalue(s *LSym) *LSym {
	return decode_reloc_sym(s, int32(commonsize())+int32(Thearch.Ptrsize)) // 0x20 / 0x38
}

// Type.ChanType.elem
func decodetype_chanelem(s *LSym) *LSym {
	return decode_reloc_sym(s, int32(commonsize())) // 0x1c / 0x30
}

// Type.FuncType.dotdotdot
func decodetype_funcdotdotdot(s *LSym) int {
	return int(s.P[commonsize()])
}

// Type.FuncType.in.length
func decodetype_funcincount(s *LSym) int {
	return int(decode_inuxi(s.P[commonsize()+2*Thearch.Ptrsize:], Thearch.Intsize))
}

func decodetype_funcoutcount(s *LSym) int {
	return int(decode_inuxi(s.P[commonsize()+3*Thearch.Ptrsize+2*Thearch.Intsize:], Thearch.Intsize))
}

func decodetype_funcintype(s *LSym, i int) *LSym {
	r := decode_reloc(s, int32(commonsize())+int32(Thearch.Ptrsize))
	if r == nil {
		return nil
	}
	return decode_reloc_sym(r.Sym, int32(r.Add+int64(int32(i)*int32(Thearch.Ptrsize))))
}

func decodetype_funcouttype(s *LSym, i int) *LSym {
	r := decode_reloc(s, int32(commonsize())+2*int32(Thearch.Ptrsize)+2*int32(Thearch.Intsize))
	if r == nil {
		return nil
	}
	return decode_reloc_sym(r.Sym, int32(r.Add+int64(int32(i)*int32(Thearch.Ptrsize))))
}

// Type.StructType.fields.Slice::length
func decodetype_structfieldcount(s *LSym) int {
	return int(decode_inuxi(s.P[commonsize()+Thearch.Ptrsize:], Thearch.Intsize))
}

func structfieldsize() int {
	return 5 * Thearch.Ptrsize
}

// Type.StructType.fields[]-> name, typ and offset.
func decodetype_structfieldname(s *LSym, i int) string {
	// go.string."foo"  0x28 / 0x40
	s = decode_reloc_sym(s, int32(commonsize())+int32(Thearch.Ptrsize)+2*int32(Thearch.Intsize)+int32(i)*int32(structfieldsize()))

	if s == nil { // embedded structs have a nil name.
		return ""
	}
	r := decode_reloc(s, 0) // s has a pointer to the string data at offset 0
	if r == nil {           // shouldn't happen.
		return ""
	}
	return cstring(r.Sym.P[r.Add:])
}

func decodetype_structfieldtype(s *LSym, i int) *LSym {
	return decode_reloc_sym(s, int32(commonsize())+int32(Thearch.Ptrsize)+2*int32(Thearch.Intsize)+int32(i)*int32(structfieldsize())+2*int32(Thearch.Ptrsize))
}

func decodetype_structfieldoffs(s *LSym, i int) int64 {
	return int64(decode_inuxi(s.P[commonsize()+Thearch.Ptrsize+2*Thearch.Intsize+i*structfieldsize()+4*Thearch.Ptrsize:], Thearch.Intsize))
}

// InterfaceType.methods.length
func decodetype_ifacemethodcount(s *LSym) int64 {
	return int64(decode_inuxi(s.P[commonsize()+Thearch.Ptrsize:], Thearch.Intsize))
}
