/** StackDeltaAnalysis implements FunctionAnalysis interface **/
func (a *StackDeltaAnalysis) AnalyzeFunction(f *artifacts.Function) error {
	ld, e := LD.New(a.ws)
	check(e)

	didSetStackDelta := false
	c, e := ld.RegisterInstructionTraceHandler(func(insn gapstone.Instruction) error {
		if !didSetStackDelta {
			if !disassembly.DoesInstructionHaveGroup(insn, gapstone.X86_GRP_RET) {
				return nil
			}
			if len(insn.X86.Operands) == 0 {
				f.SetStackDelta(0)
				return nil
			}
			if insn.X86.Operands[0].Type != gapstone.X86_OP_IMM {
				return nil
			}
			stackDelta := insn.X86.Operands[0].Imm
			f.SetStackDelta(stackDelta)
			didSetStackDelta = true
		}
		return nil
	})
	check(e)
	defer ld.UnregisterInstructionTraceHandler(c)

	e = ld.ExploreFunction(a.ws, f.Start)
	check(e)

	return nil
}
/** NameAnalysis implements FunctionAnalysis interface **/
func (a *NameAnalysis) AnalyzeFunction(f *artifacts.Function) error {
	sym, e := a.ws.ResolveAddressToSymbol(f.Start)
	if e == nil {
		f.SetName(sym.SymbolName)
	} else {
		f.SetName(fmt.Sprintf("sub_%s", f.Start))
	}
	return nil
}