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

// Mapping from PC to SP offset (called CFA - Canonical Frame Address - in DWARF).
// This value is the offset from the stack pointer to the virtual frame pointer
// (address of zeroth argument) at each PC value in the program.

package dwarf

import "fmt"

// http://www.dwarfstd.org/doc/DWARF4.pdf Section 6.4 page 126
// We implement only the CFA column of the table, not the location
// information about other registers. In other words, we implement
// only what we need to understand Go programs compiled by gc.

// PCToSPOffset returns the offset, at the specified PC, to add to the
// SP to reach the virtual frame pointer, which corresponds to the
// address of the zeroth argument of the function, the word on the
// stack immediately above the return PC.
func (d *Data) PCToSPOffset(pc uint64) (offset int64, err error) {
	if len(d.frame) == 0 {
		return 0, fmt.Errorf("PCToSPOffset: no frame table")
	}
	var m frameMachine
	// Assume the first info unit is the same as us. Extremely likely. TODO?
	if len(d.unit) == 0 {
		return 0, fmt.Errorf("PCToSPOffset: no info section")
	}
	buf := makeBuf(d, &d.unit[0], "frame", 0, d.frame)
	for len(buf.data) > 0 {
		offset, err := m.evalCompilationUnit(&buf, pc)
		if err != nil {
			return 0, err
		}
		return offset, nil
	}
	return 0, fmt.Errorf("PCToSPOffset: no frame defined for PC %#x", pc)
}

// Call Frame instructions. Figure 40, page 181.
// Structure is high two bits plus low 6 bits specified by + in comment.
// Some take one or two operands.
const (
	frameNop              = 0<<6 + 0x00
	frameAdvanceLoc       = 1<<6 + 0x00 // + delta
	frameOffset           = 2<<6 + 0x00 // + register op: ULEB128 offset
	frameRestore          = 3<<6 + 0x00 // + register
	frameSetLoc           = 0<<6 + 0x01 // op: address
	frameAdvanceLoc1      = 0<<6 + 0x02 // op: 1-byte delta
	frameAdvanceLoc2      = 0<<6 + 0x03 // op: 2-byte delta
	frameAdvanceLoc4      = 0<<6 + 0x04 // op: 4-byte delta
	frameOffsetExtended   = 0<<6 + 0x05 // ops: ULEB128 register ULEB128 offset
	frameRestoreExtended  = 0<<6 + 0x06 // op: ULEB128 register
	frameUndefined        = 0<<6 + 0x07 // op: ULEB128 register
	frameSameValue        = 0<<6 + 0x08 // op: ULEB128 register
	frameRegister         = 0<<6 + 0x09 // op: ULEB128 register ULEB128 register
	frameRememberState    = 0<<6 + 0x0a
	frameRestoreState     = 0<<6 + 0x0b
	frameDefCFA           = 0<<6 + 0x0c // op: ULEB128 register ULEB128 offset
	frameDefCFARegister   = 0<<6 + 0x0d // op: ULEB128 register
	frameDefCFAOffset     = 0<<6 + 0x0e // op: ULEB128 offset
	frameDefCFAExpression = 0<<6 + 0x0f // op: BLOCK
	frameExpression       = 0<<6 + 0x10 // op: ULEB128 register BLOCK
	frameOffsetExtendedSf = 0<<6 + 0x11 // op: ULEB128 register SLEB128 offset
	frameDefCFASf         = 0<<6 + 0x12 // op: ULEB128 register SLEB128 offset
	frameDefCFAOffsetSf   = 0<<6 + 0x13 // op: SLEB128 offset
	frameValOffset        = 0<<6 + 0x14 // op: ULEB128 ULEB128
	frameValOffsetSf      = 0<<6 + 0x15 // op: ULEB128 SLEB128
	frameValExpression    = 0<<6 + 0x16 // op: ULEB128 BLOCK
	frameLoUser           = 0<<6 + 0x1c
	frameHiUser           = 0<<6 + 0x3f
)

// frameMachine represents the PC/SP engine.
// Section 6.4, page 129.
type frameMachine struct {
	// Initial values from CIE.
	version               uint8  // Version number, "independent of DWARF version"
	augmentation          string // Augmentation; treated as unexpected for now. TODO.
	addressSize           uint8  // In DWARF v4 and above. Size of a target address.
	segmentSize           uint8  // In DWARF v4 and above. Size of a segment selector.
	codeAlignmentFactor   uint64 // Unit of code size in advance instructions.
	dataAlignmentFactor   int64  // Unit of data size in certain offset instructions.
	returnAddressRegister int    // Pseudo-register (actually data column) representing return address.
	returnRegisterOffset  int64  // Offset to saved PC from CFA in bytes.
	// CFA definition.
	cfaRegister int   // Which register represents the SP.
	cfaOffset   int64 // CFA offset value.
	// Running machine.
	location uint64
}

// evalCompilationUnit scans the frame data for one compilation unit to retrieve
// the offset information for the specified pc.
func (m *frameMachine) evalCompilationUnit(b *buf, pc uint64) (int64, error) {
	err := m.parseCIE(b)
	if err != nil {
		return 0, err
	}
	for {
		offset, found, err := m.scanFDE(b, pc)
		if err != nil {
			return 0, err
		}
		if found {
			return offset, nil
		}
	}
}

// parseCIE assumes the incoming buffer starts with a CIE block and parses it
// to initialize a frameMachine.
func (m *frameMachine) parseCIE(allBuf *buf) error {
	length := int(allBuf.uint32())
	if len(allBuf.data) < length {
		return fmt.Errorf("CIE parse error: too short")
	}
	// Create buffer for just this section.
	b := allBuf.slice(length)
	cie := b.uint32()
	if cie != 0xFFFFFFFF {
		return fmt.Errorf("CIE parse error: not CIE: %x", cie)
	}
	m.version = b.uint8()
	if m.version != 3 && m.version != 4 {
		return fmt.Errorf("CIE parse error: unsupported version %d", m.version)
	}
	m.augmentation = b.string()
	if len(m.augmentation) > 0 {
		return fmt.Errorf("CIE: can't handled augmentation string %q", m.augmentation)
	}
	if m.version >= 4 {
		m.addressSize = b.uint8()
		m.segmentSize = b.uint8()
	} else {
		// Unused. Gc generates version 3, so these values will not be
		// set, but they are also not used so it's OK.
	}
	m.codeAlignmentFactor = b.uint()
	m.dataAlignmentFactor = b.int()
	m.returnAddressRegister = int(b.uint())

	// Initial instructions. At least for Go, establishes SP register number
	// and initial value of CFA offset at start of function.
	_, err := m.run(&b, ^uint64(0))
	if err != nil {
		return err
	}

	// There's padding, but we can ignore it.
	return nil
}

// scanFDE assumes the incoming buffer starts with a FDE block and parses it
// to run a frameMachine and, if the PC is represented in its range, return
// the CFA offset for that PC. The boolean returned reports whether the
// PC is in range for this FDE.
func (m *frameMachine) scanFDE(allBuf *buf, pc uint64) (int64, bool, error) {
	length := int(allBuf.uint32())
	if len(allBuf.data) < length {
		return 0, false, fmt.Errorf("FDE parse error: too short")
	}
	if length <= 0 {
		if length == 0 {
			// EOF.
			return 0, false, fmt.Errorf("PC %#x not found in PC/SP table", pc)
		}
		return 0, false, fmt.Errorf("bad FDE length %d", length)
	}
	// Create buffer for just this section.
	b := allBuf.slice(length)
	cieOffset := b.uint32() // TODO assumes 32 bits.
	// Expect 0: first CIE in this segment. TODO.
	if cieOffset != 0 {
		return 0, false, fmt.Errorf("FDE parse error: bad CIE offset: %.2x", cieOffset)
	}
	// Initial location.
	m.location = b.addr()
	addressRange := b.addr()
	// If the PC is not in this function, there's no point in executing the instructions.
	if pc < m.location || m.location+addressRange <= pc {
		return 0, false, nil
	}
	// The PC appears in this FDE. Scan to find the location.
	offset, err := m.run(&b, pc)
	if err != nil {
		return 0, false, err
	}

	// There's padding, but we can ignore it.
	return offset, true, nil
}

// run executes the instructions in the buffer, which has been sliced to contain
// only the data for this block. When we run out of data, we return.
// Since we are only called when we know the PC is in this block, reaching
// EOF is not an error, it just means the final CFA definition matches the
// tail of the block that holds the PC.
// The return value is the CFA at the end of the block or the PC, whichever
// comes first.
func (m *frameMachine) run(b *buf, pc uint64) (int64, error) {
	// We run the machine at location == PC because if the PC is at the first
	// instruction of a block, the definition of its offset arrives as an
	// offset-defining operand after the PC is set to that location.
	for m.location <= pc && len(b.data) > 0 {
		op := b.uint8()
		// Ops with embedded operands
		switch op & 0xC0 {
		case frameAdvanceLoc: // (6.4.2.1)
			// delta in low bits
			m.location += uint64(op & 0x3F)
			continue
		case frameOffset: // (6.4.2.3)
			// Register in low bits; ULEB128 offset.
			// For Go binaries we only see this in the CIE for the return address register.
			if int(op&0x3F) != m.returnAddressRegister {
				return 0, fmt.Errorf("invalid frameOffset register R%d should be R%d", op&0x3f, m.returnAddressRegister)
			}
			m.returnRegisterOffset = int64(b.uint()) * m.dataAlignmentFactor
			continue
		case frameRestore: // (6.4.2.3)
			// register in low bits
			return 0, fmt.Errorf("unimplemented frameRestore(R%d)\n", op&0x3F)
		}

		// The remaining ops do not have embedded operands.

		switch op {
		// Row creation instructions (6.4.2.1)
		case frameNop:
		case frameSetLoc: // op: address
			return 0, fmt.Errorf("unimplemented setloc") // what size is operand?
		case frameAdvanceLoc1: // op: 1-byte delta
			m.location += uint64(b.uint8())
		case frameAdvanceLoc2: // op: 2-byte delta
			m.location += uint64(b.uint16())
		case frameAdvanceLoc4: // op: 4-byte delta
			m.location += uint64(b.uint32())

		// CFA definition instructions (6.4.2.2)
		case frameDefCFA: // op: ULEB128 register ULEB128 offset
			m.cfaRegister = int(b.int())
			m.cfaOffset = int64(b.uint())
		case frameDefCFASf: // op: ULEB128 register SLEB128 offset
			return 0, fmt.Errorf("unimplemented frameDefCFASf")
		case frameDefCFARegister: // op: ULEB128 register
			return 0, fmt.Errorf("unimplemented frameDefCFARegister")
		case frameDefCFAOffset: // op: ULEB128 offset
			return 0, fmt.Errorf("unimplemented frameDefCFAOffset")
		case frameDefCFAOffsetSf: // op: SLEB128 offset
			offset := b.int()
			m.cfaOffset = offset * m.dataAlignmentFactor
			// TODO: Verify we are using a factored offset.
		case frameDefCFAExpression: // op: BLOCK
			return 0, fmt.Errorf("unimplemented frameDefCFAExpression")

		// Register Rule instructions (6.4.2.3)
		case frameOffsetExtended: // ops: ULEB128 register ULEB128 offset
			return 0, fmt.Errorf("unimplemented frameOffsetExtended")
		case frameRestoreExtended: // op: ULEB128 register
			return 0, fmt.Errorf("unimplemented frameRestoreExtended")
		case frameUndefined: // op: ULEB128 register; unimplemented
			return 0, fmt.Errorf("unimplemented frameUndefined")
		case frameSameValue: // op: ULEB128 register
			return 0, fmt.Errorf("unimplemented frameSameValue")
		case frameRegister: // op: ULEB128 register ULEB128 register
			return 0, fmt.Errorf("unimplemented frameRegister")
		case frameRememberState:
			return 0, fmt.Errorf("unimplemented frameRememberState")
		case frameRestoreState:
			return 0, fmt.Errorf("unimplemented frameRestoreState")
		case frameExpression: // op: ULEB128 register BLOCK
			return 0, fmt.Errorf("unimplemented frameExpression")
		case frameOffsetExtendedSf: // op: ULEB128 register SLEB128 offset
			return 0, fmt.Errorf("unimplemented frameOffsetExtended_sf")
		case frameValOffset: // op: ULEB128 ULEB128
			return 0, fmt.Errorf("unimplemented frameValOffset")
		case frameValOffsetSf: // op: ULEB128 SLEB128
			return 0, fmt.Errorf("unimplemented frameValOffsetSf")
		case frameValExpression: // op: ULEB128 BLOCK
			return 0, fmt.Errorf("unimplemented frameValExpression")

		default:
			if frameLoUser <= op && op <= frameHiUser {
				return 0, fmt.Errorf("unknown user-defined frame op %#x", op)
			}
			return 0, fmt.Errorf("unknown frame op %#x", op)
		}
	}
	return m.cfaOffset, nil
}
