// Copyright 2014 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.

// Generation of runtime function information (pclntab).

package main

import (
	"debug/goobj"
	"encoding/binary"
	"os"
	"sort"
)

var zerofunc goobj.Func

// pclntab collects the runtime function data for each function that will
// be listed in the binary and builds a single table describing all functions.
// This table is used at run time for stack traces and to look up PC-specific
// information during garbage collection. The symbol created is named
// "pclntab" for historical reasons; the scope of the table has grown to
// include more than just PC/line number correspondences.
// The table format is documented at http://golang.org/s/go12symtab.
func (p *Prog) pclntab() {
	// Count number of functions going into the binary,
	// so that we can size the initial index correctly.
	nfunc := 0
	for _, sym := range p.SymOrder {
		if sym.Kind != goobj.STEXT {
			continue
		}
		nfunc++
	}

	// Table header.
	buf := new(SymBuffer)
	buf.Init(p)
	buf.SetSize(8 + p.ptrsize)
	off := 0
	off = buf.Uint32(off, 0xfffffffb)
	off = buf.Uint8(off, 0)
	off = buf.Uint8(off, 0)
	off = buf.Uint8(off, uint8(p.pcquantum))
	off = buf.Uint8(off, uint8(p.ptrsize))
	off = buf.Uint(off, uint64(nfunc), p.ptrsize)
	indexOff := off
	off += (nfunc*2 + 1) * p.ptrsize // function index, to be filled in
	off += 4                         // file table start offset, to be filled in
	buf.SetSize(off)

	// One-file cache for reading PCData tables from package files.
	// TODO(rsc): Better I/O strategy.
	var (
		file  *os.File
		fname string
	)

	// Files gives the file numbering for source file names recorded
	// in the binary.
	files := make(map[string]int)

	// Build the table, build the index, and build the file name numbering.
	// The loop here must visit functions in the same order that they will
	// be stored in the binary, or else binary search over the index will fail.
	// The runtime checks that the index is sorted properly at program start time.
	var lastSym *Sym
	for _, sym := range p.SymOrder {
		if sym.Kind != goobj.STEXT {
			continue
		}
		lastSym = sym

		// Treat no recorded function information same as all zeros.
		f := sym.Func
		if f == nil {
			f = &zerofunc
		}

		// Open package file if needed, for reading PC data.
		if fname != sym.Package.File {
			if file != nil {
				file.Close()
			}
			var err error
			file, err = os.Open(sym.Package.File)
			if err != nil {
				p.errorf("%v: %v", sym, err)
				return
			}
			fname = sym.Package.File
		}

		// off is the offset of the table entry where we're going to write
		// the encoded form of Func.
		// indexOff is the current position in the table index;
		// we add an entry in the index pointing at off.
		off = (buf.Size() + p.ptrsize - 1) &^ (p.ptrsize - 1)
		indexOff = buf.Addr(indexOff, sym.SymID, 0)
		indexOff = buf.Uint(indexOff, uint64(off), p.ptrsize)

		// The Func encoding starts with a header giving offsets
		// to data blobs, and then the data blobs themselves.
		// end gives the current write position for the data blobs.
		end := off + p.ptrsize + 3*4 + 5*4 + len(f.PCData)*4 + len(f.FuncData)*p.ptrsize
		if len(f.FuncData) > 0 {
			end += -end & (p.ptrsize - 1)
		}
		buf.SetSize(end)

		// entry uintptr
		// name int32
		// args int32
		// frame int32
		//
		// The frame recorded in the object file is
		// the frame size used in an assembly listing, which does
		// not include the caller PC on the stack.
		// The frame size we want to list here is the delta from
		// this function's SP to its caller's SP, which does include
		// the caller PC. Add p.ptrsize to f.Frame to adjust.
		// TODO(rsc): Record the same frame size in the object file.
		off = buf.Addr(off, sym.SymID, 0)
		off = buf.Uint32(off, uint32(addString(buf, sym.Name)))
		off = buf.Uint32(off, uint32(f.Args))
		off = buf.Uint32(off, uint32(f.Frame+p.ptrsize))

		// pcdata
		off = buf.Uint32(off, uint32(addPCTable(p, buf, file, f.PCSP)))
		off = buf.Uint32(off, uint32(addPCFileTable(p, buf, file, f.PCFile, sym, files)))
		off = buf.Uint32(off, uint32(addPCTable(p, buf, file, f.PCLine)))
		off = buf.Uint32(off, uint32(len(f.PCData)))
		off = buf.Uint32(off, uint32(len(f.FuncData)))
		for _, pcdata := range f.PCData {
			off = buf.Uint32(off, uint32(addPCTable(p, buf, file, pcdata)))
		}

		// funcdata
		if len(f.FuncData) > 0 {
			off += -off & (p.ptrsize - 1) // must be pointer-aligned
			for _, funcdata := range f.FuncData {
				if funcdata.Sym.Name == "" {
					off = buf.Uint(off, uint64(funcdata.Offset), p.ptrsize)
				} else {
					off = buf.Addr(off, funcdata.Sym, funcdata.Offset)
				}
			}
		}

		if off != end {
			p.errorf("internal error: invalid math in pclntab: off=%#x end=%#x", off, end)
			break
		}
	}
	if file != nil {
		file.Close()
	}

	// Final entry of index is end PC of last function.
	indexOff = buf.Addr(indexOff, lastSym.SymID, int64(lastSym.Size))

	// Start file table.
	// Function index is immediately followed by offset to file table.
	off = (buf.Size() + p.ptrsize - 1) &^ (p.ptrsize - 1)
	buf.Uint32(indexOff, uint32(off))

	// File table is an array of uint32s.
	// The first entry gives 1+n, the size of the array.
	// The following n entries hold offsets to string data.
	// File number n uses the string pointed at by entry n.
	// File number 0 is invalid.
	buf.SetSize(off + (1+len(files))*4)
	buf.Uint32(off, uint32(1+len(files)))
	var filestr []string
	for file := range files {
		filestr = append(filestr, file)
	}
	sort.Strings(filestr)
	for _, file := range filestr {
		id := files[file]
		buf.Uint32(off+4*id, uint32(addString(buf, file)))
	}

	pclntab := &Sym{
		Sym: &goobj.Sym{
			SymID: goobj.SymID{Name: "pclntab"},
			Kind:  goobj.SPCLNTAB,
			Size:  buf.Size(),
			Reloc: buf.Reloc(),
		},
		Bytes: buf.Bytes(),
	}
	p.addSym(pclntab)
}

// addString appends the string s to the buffer b.
// It returns the offset of the beginning of the string in the buffer.
func addString(b *SymBuffer, s string) int {
	off := b.Size()
	b.SetSize(off + len(s) + 1)
	copy(b.data[off:], s)
	return off
}

// addPCTable appends the PC-data table stored in the file f at the location loc
// to the symbol buffer b. It returns the offset of the beginning of the table
// in the buffer.
func addPCTable(p *Prog, b *SymBuffer, f *os.File, loc goobj.Data) int {
	if loc.Size == 0 {
		return 0
	}
	off := b.Size()
	b.SetSize(off + int(loc.Size))
	_, err := f.ReadAt(b.data[off:off+int(loc.Size)], loc.Offset)
	if err != nil {
		p.errorf("%v", err)
	}
	return off
}

// addPCFileTable is like addPCTable, but it renumbers the file names referred to by the table
// to use the global numbering maintained in the files map. It adds new files to the
// map as necessary.
func addPCFileTable(p *Prog, b *SymBuffer, f *os.File, loc goobj.Data, sym *Sym, files map[string]int) int {
	if loc.Size == 0 {
		return 0
	}
	off := b.Size()

	src := make([]byte, loc.Size)
	_, err := f.ReadAt(src, loc.Offset)
	if err != nil {
		p.errorf("%v", err)
		return 0
	}

	filenum := make([]int, len(sym.Func.File))
	for i, name := range sym.Func.File {
		num := files[name]
		if num == 0 {
			num = len(files) + 1
			files[name] = num
		}
		filenum[i] = num
	}

	var dst []byte
	newval := int32(-1)
	var it PCIter
	for it.Init(p, src); !it.Done; it.Next() {
		// value delta
		oldval := it.Value
		val := oldval
		if oldval != -1 {
			if oldval < 0 || int(oldval) >= len(filenum) {
				p.errorf("%s: corrupt pc-file table", sym)
				break
			}
			val = int32(filenum[oldval])
		}
		dv := val - newval
		newval = val
		uv := uint32(dv<<1) ^ uint32(dv>>31)
		dst = appendVarint(dst, uv)

		// pc delta
		dst = appendVarint(dst, it.NextPC-it.PC)
	}
	if it.Corrupt {
		p.errorf("%s: corrupt pc-file table", sym)
	}

	// terminating value delta
	dst = appendVarint(dst, 0)

	b.SetSize(off + len(dst))
	copy(b.data[off:], dst)
	return off
}

// A SymBuffer is a buffer for preparing the data image of a
// linker-generated symbol.
type SymBuffer struct {
	data    []byte
	reloc   []goobj.Reloc
	order   binary.ByteOrder
	ptrsize int
}

// Init initializes the buffer for writing.
func (b *SymBuffer) Init(p *Prog) {
	b.data = nil
	b.reloc = nil
	b.order = p.byteorder
	b.ptrsize = p.ptrsize
}

// Bytes returns the buffer data.
func (b *SymBuffer) Bytes() []byte {
	return b.data
}

// SetSize sets the buffer's data size to n bytes.
func (b *SymBuffer) SetSize(n int) {
	for cap(b.data) < n {
		b.data = append(b.data[:cap(b.data)], 0)
	}
	b.data = b.data[:n]
}

// Size returns the buffer's data size.
func (b *SymBuffer) Size() int {
	return len(b.data)
}

// Reloc returns the buffered relocations.
func (b *SymBuffer) Reloc() []goobj.Reloc {
	return b.reloc
}

// Uint8 sets the uint8 at offset off to v.
// It returns the offset just beyond v.
func (b *SymBuffer) Uint8(off int, v uint8) int {
	b.data[off] = v
	return off + 1
}

// Uint16 sets the uint16 at offset off to v.
// It returns the offset just beyond v.
func (b *SymBuffer) Uint16(off int, v uint16) int {
	b.order.PutUint16(b.data[off:], v)
	return off + 2
}

// Uint32 sets the uint32 at offset off to v.
// It returns the offset just beyond v.
func (b *SymBuffer) Uint32(off int, v uint32) int {
	b.order.PutUint32(b.data[off:], v)
	return off + 4
}

// Uint64 sets the uint64 at offset off to v.
// It returns the offset just beyond v.
func (b *SymBuffer) Uint64(off int, v uint64) int {
	b.order.PutUint64(b.data[off:], v)
	return off + 8
}

// Uint sets the size-byte unsigned integer at offset off to v.
// It returns the offset just beyond v.
func (b *SymBuffer) Uint(off int, v uint64, size int) int {
	switch size {
	case 1:
		return b.Uint8(off, uint8(v))
	case 2:
		return b.Uint16(off, uint16(v))
	case 4:
		return b.Uint32(off, uint32(v))
	case 8:
		return b.Uint64(off, v)
	}
	panic("invalid use of SymBuffer.SetUint")
}

// Addr sets the pointer-sized address at offset off to refer
// to symoff bytes past the start of sym. It returns the offset
// just beyond the address.
func (b *SymBuffer) Addr(off int, sym goobj.SymID, symoff int64) int {
	b.reloc = append(b.reloc, goobj.Reloc{
		Offset: off,
		Size:   b.ptrsize,
		Sym:    sym,
		Add:    int(symoff),
		Type:   R_ADDR,
	})
	return off + b.ptrsize
}

// A PCIter implements iteration over PC-data tables.
//
//	var it PCIter
//	for it.Init(p, data); !it.Done; it.Next() {
//		it.Value holds from it.PC up to (but not including) it.NextPC
//	}
//	if it.Corrupt {
//		data was malformed
//	}
//
type PCIter struct {
	PC        uint32
	NextPC    uint32
	Value     int32
	Done      bool
	Corrupt   bool
	p         []byte
	start     bool
	pcquantum uint32
}

// Init initializes the iteration.
// On return, if it.Done is true, the iteration is over.
// Otherwise it.Value applies in the pc range [it.PC, it.NextPC).
func (it *PCIter) Init(p *Prog, buf []byte) {
	it.p = buf
	it.PC = 0
	it.NextPC = 0
	it.Value = -1
	it.start = true
	it.pcquantum = uint32(p.pcquantum)
	it.Done = false
	it.Next()
}

// Next steps forward one entry in the table.
// On return, if it.Done is true, the iteration is over.
// Otherwise it.Value applies in the pc range [it.PC, it.NextPC).
func (it *PCIter) Next() {
	it.PC = it.NextPC
	if it.Done {
		return
	}
	if len(it.p) == 0 {
		it.Done = true
		return
	}

	// value delta
	uv, p, ok := decodeVarint(it.p)
	if !ok {
		it.Done = true
		it.Corrupt = true
		return
	}
	it.p = p
	if uv == 0 && !it.start {
		it.Done = true
		return
	}
	it.start = false
	sv := int32(uv)>>1 ^ int32(uv)<<31>>31
	it.Value += sv

	// pc delta
	uv, it.p, ok = decodeVarint(it.p)
	if !ok {
		it.Done = true
		it.Corrupt = true
		return
	}
	it.NextPC = it.PC + uv*it.pcquantum
}

// decodeVarint decodes an unsigned varint from p,
// reporting the value, the remainder of the data, and
// whether the decoding was successful.
func decodeVarint(p []byte) (v uint32, rest []byte, ok bool) {
	for shift := uint(0); ; shift += 7 {
		if len(p) == 0 {
			return
		}
		c := uint32(p[0])
		p = p[1:]
		v |= (c & 0x7F) << shift
		if c&0x80 == 0 {
			break
		}
	}
	return v, p, true
}

// appendVarint appends an unsigned varint encoding of v to p
// and returns the resulting slice.
func appendVarint(p []byte, v uint32) []byte {
	for ; v >= 0x80; v >>= 7 {
		p = append(p, byte(v)|0x80)
	}
	p = append(p, byte(v))
	return p
}
