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

package dwarf

// This file provides simple methods to access the symbol table by name and address.

import "fmt"

// lookupEntry returns the Entry for the name. If tag is non-zero, only entries
// with that tag are considered.
func (d *Data) lookupEntry(name string, tag Tag) (*Entry, error) {
	r := d.Reader()
	for {
		entry, err := r.Next()
		if err != nil {
			return nil, err
		}
		if entry == nil {
			// TODO: why don't we get an error here?
			break
		}
		if tag != 0 && tag != entry.Tag {
			continue
		}
		nameAttr := entry.Val(AttrName)
		if nameAttr == nil {
			continue
		}
		if nameAttr.(string) == name {
			return entry, nil
		}
	}
	return nil, fmt.Errorf("DWARF entry for %q not found", name)
}

// LookupEntry returns the Entry for the named symbol.
func (d *Data) LookupEntry(name string) (*Entry, error) {
	return d.lookupEntry(name, 0)
}

// LookupFunction returns the address of the named symbol, a function.
func (d *Data) LookupFunction(name string) (uint64, error) {
	entry, err := d.lookupEntry(name, TagSubprogram)
	if err != nil {
		return 0, err
	}
	addrAttr := entry.Val(AttrLowpc)
	if addrAttr == nil {
		return 0, fmt.Errorf("symbol %q has no LowPC attribute", name)
	}
	addr, ok := addrAttr.(uint64)
	if !ok {
		return 0, fmt.Errorf("symbol %q has non-uint64 LowPC attribute", name)
	}
	return addr, nil
}

// TODO: should LookupVariable handle both globals and locals? Locals don't
// necessarily have a fixed address. They may be in a register, or otherwise
// move around.

// LookupVariable returns the location of a named symbol, a variable.
func (d *Data) LookupVariable(name string) (uint64, error) {
	entry, err := d.lookupEntry(name, TagVariable)
	if err != nil {
		return 0, err
	}
	loc, _ := entry.Val(AttrLocation).([]byte)
	if len(loc) == 0 {
		return 0, fmt.Errorf("name %q has no Location attribute", name)
	}
	// TODO: implement the DWARF Location bytecode. What we have here only
	// recognizes a program with a single literal opAddr bytecode.
	if asize := d.unit[0].asize; loc[0] == opAddr && len(loc) == 1+asize {
		switch asize {
		case 1:
			return uint64(loc[1]), nil
		case 2:
			return uint64(d.order.Uint16(loc[1:])), nil
		case 4:
			return uint64(d.order.Uint32(loc[1:])), nil
		case 8:
			return d.order.Uint64(loc[1:]), nil
		}
	}
	return 0, fmt.Errorf("DWARF: unimplemented Location op")
}

// LookupPC returns the name of a symbol at the specified PC.
func (d *Data) LookupPC(pc uint64) (string, error) {
	entry, _, err := d.EntryForPC(pc)
	if err != nil {
		return "", err
	}
	nameAttr := entry.Val(AttrName)
	if nameAttr == nil {
		// TODO: this shouldn't be possible.
		return "", fmt.Errorf("LookupPC: TODO")
	}
	name, ok := nameAttr.(string)
	if !ok {
		return "", fmt.Errorf("name for PC %#x is not a string", pc)
	}
	return name, nil
}

// EntryForPC returns the entry and address for a symbol at the specified PC.
func (d *Data) EntryForPC(pc uint64) (entry *Entry, lowpc uint64, err error) {
	// TODO: do something better than a linear scan?
	r := d.Reader()
	for {
		entry, err := r.Next()
		if err != nil {
			return nil, 0, err
		}
		if entry == nil {
			// TODO: why don't we get an error here.
			break
		}
		if entry.Tag != TagSubprogram {
			continue
		}
		lowpc, lok := entry.Val(AttrLowpc).(uint64)
		highpc, hok := entry.Val(AttrHighpc).(uint64)
		if !lok || !hok || pc < lowpc || highpc <= pc {
			continue
		}
		return entry, lowpc, nil
	}
	return nil, 0, fmt.Errorf("PC %#x not found", pc)
}
