// 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 goobj

import (
	"cmd/internal/goobj2"
	"cmd/internal/objabi"
	"fmt"
	"strings"
)

// Read object file in new format. For now we still fill
// the data to the current goobj API.
func (r *objReader) readNew() {
	start := uint32(r.offset)

	length := r.limit - r.offset
	objbytes := make([]byte, length)
	r.readFull(objbytes)
	rr := goobj2.NewReaderFromBytes(objbytes, false)
	if rr == nil {
		panic("cannot read object file")
	}

	// Imports
	autolib := rr.Autolib()
	for _, p := range autolib {
		r.p.Imports = append(r.p.Imports, p.Pkg)
		// Ignore fingerprint (for tools like objdump which only reads one object).
	}

	pkglist := rr.Pkglist()

	abiToVer := func(abi uint16) int64 {
		var vers int64
		if abi == goobj2.SymABIstatic {
			// Static symbol
			vers = r.p.MaxVersion
		}
		return vers
	}

	resolveSymRef := func(s goobj2.SymRef) SymID {
		var i uint32
		switch p := s.PkgIdx; p {
		case goobj2.PkgIdxInvalid:
			if s.SymIdx != 0 {
				panic("bad sym ref")
			}
			return SymID{}
		case goobj2.PkgIdxNone:
			i = s.SymIdx + uint32(rr.NSym())
		case goobj2.PkgIdxBuiltin:
			name, abi := goobj2.BuiltinName(int(s.SymIdx))
			return SymID{name, int64(abi)}
		case goobj2.PkgIdxSelf:
			i = s.SymIdx
		default:
			// Symbol from other package, referenced by index.
			// We don't know the name. Use index.
			pkg := pkglist[p]
			return SymID{fmt.Sprintf("%s.#%d", pkg, s.SymIdx), 0}
		}
		sym := rr.Sym(i)
		return SymID{sym.Name(rr), abiToVer(sym.ABI())}
	}

	// Read things for the current goobj API for now.

	// Symbols
	pcdataBase := start + rr.PcdataBase()
	n := uint32(rr.NSym() + rr.NNonpkgdef() + rr.NNonpkgref())
	npkgdef := uint32(rr.NSym())
	ndef := uint32(rr.NSym() + rr.NNonpkgdef())
	for i := uint32(0); i < n; i++ {
		osym := rr.Sym(i)
		if osym.Name(rr) == "" {
			continue // not a real symbol
		}
		// In a symbol name in an object file, "". denotes the
		// prefix for the package in which the object file has been found.
		// Expand it.
		name := strings.ReplaceAll(osym.Name(rr), `"".`, r.pkgprefix)
		if i < npkgdef {
			// Indexed symbol. Attach index to the name.
			name += fmt.Sprintf("#%d", i)
		}
		symID := SymID{Name: name, Version: abiToVer(osym.ABI())}
		r.p.SymRefs = append(r.p.SymRefs, symID)

		if i >= ndef {
			continue // not a defined symbol from here
		}

		// Symbol data
		dataOff := rr.DataOff(i)
		siz := int64(rr.DataSize(i))

		sym := Sym{
			SymID: symID,
			Kind:  objabi.SymKind(osym.Type()),
			DupOK: osym.Dupok(),
			Size:  int64(osym.Siz()),
			Data:  Data{int64(start + dataOff), siz},
		}
		r.p.Syms = append(r.p.Syms, &sym)

		// Reloc
		relocs := rr.Relocs(i)
		sym.Reloc = make([]Reloc, len(relocs))
		for j := range relocs {
			rel := &relocs[j]
			sym.Reloc[j] = Reloc{
				Offset: int64(rel.Off()),
				Size:   int64(rel.Siz()),
				Type:   objabi.RelocType(rel.Type()),
				Add:    rel.Add(),
				Sym:    resolveSymRef(rel.Sym()),
			}
		}

		// Aux symbol info
		isym := ^uint32(0)
		funcdata := make([]goobj2.SymRef, 0, 4)
		auxs := rr.Auxs(i)
		for j := range auxs {
			a := &auxs[j]
			switch a.Type() {
			case goobj2.AuxGotype:
				sym.Type = resolveSymRef(a.Sym())
			case goobj2.AuxFuncInfo:
				if a.Sym().PkgIdx != goobj2.PkgIdxSelf {
					panic("funcinfo symbol not defined in current package")
				}
				isym = a.Sym().SymIdx
			case goobj2.AuxFuncdata:
				funcdata = append(funcdata, a.Sym())
			case goobj2.AuxDwarfInfo, goobj2.AuxDwarfLoc, goobj2.AuxDwarfRanges, goobj2.AuxDwarfLines:
				// nothing to do
			default:
				panic("unknown aux type")
			}
		}

		// Symbol Info
		if isym == ^uint32(0) {
			continue
		}
		b := rr.BytesAt(rr.DataOff(isym), rr.DataSize(isym))
		info := goobj2.FuncInfo{}
		info.Read(b)

		info.Pcdata = append(info.Pcdata, info.PcdataEnd) // for the ease of knowing where it ends
		f := &Func{
			Args:     int64(info.Args),
			Frame:    int64(info.Locals),
			NoSplit:  osym.NoSplit(),
			Leaf:     osym.Leaf(),
			TopFrame: osym.TopFrame(),
			PCSP:     Data{int64(pcdataBase + info.Pcsp), int64(info.Pcfile - info.Pcsp)},
			PCFile:   Data{int64(pcdataBase + info.Pcfile), int64(info.Pcline - info.Pcfile)},
			PCLine:   Data{int64(pcdataBase + info.Pcline), int64(info.Pcinline - info.Pcline)},
			PCInline: Data{int64(pcdataBase + info.Pcinline), int64(info.Pcdata[0] - info.Pcinline)},
			PCData:   make([]Data, len(info.Pcdata)-1), // -1 as we appended one above
			FuncData: make([]FuncData, len(info.Funcdataoff)),
			File:     make([]string, len(info.File)),
			InlTree:  make([]InlinedCall, len(info.InlTree)),
		}
		sym.Func = f
		for k := range f.PCData {
			f.PCData[k] = Data{int64(pcdataBase + info.Pcdata[k]), int64(info.Pcdata[k+1] - info.Pcdata[k])}
		}
		for k := range f.FuncData {
			symID := resolveSymRef(funcdata[k])
			f.FuncData[k] = FuncData{symID, int64(info.Funcdataoff[k])}
		}
		for k := range f.File {
			symID := resolveSymRef(info.File[k])
			f.File[k] = symID.Name
		}
		for k := range f.InlTree {
			inl := &info.InlTree[k]
			f.InlTree[k] = InlinedCall{
				Parent:   int64(inl.Parent),
				File:     resolveSymRef(inl.File).Name,
				Line:     int64(inl.Line),
				Func:     resolveSymRef(inl.Func),
				ParentPC: int64(inl.ParentPC),
			}
		}
	}
}
