// 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. Should this function be renamed LookupGlobal?

// 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.
	// TODO: is d.unit[0] always the right unit to take?
	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)
}
