// Copyright 2018 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

package report

import (
	"bufio"
	"bytes"
	"fmt"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"

	"github.com/google/syzkaller/pkg/symbolizer"
)

type openbsd struct {
	*config
	kernelObject string
	symbols      map[string][]symbolizer.Symbol
}

var (
	openbsdSymbolizeRe = []*regexp.Regexp{
		// stack
		regexp.MustCompile(` at ([A-Za-z0-9_]+)\+0x([0-9a-f]+)`),
		// witness
		regexp.MustCompile(`#[0-9]+ +([A-Za-z0-9_]+)\+0x([0-9a-f]+)`),
	}
)

func ctorOpenbsd(cfg *config) (Reporter, []string, error) {
	var symbols map[string][]symbolizer.Symbol
	kernelObject := ""
	if cfg.kernelObj != "" {
		kernelObject = filepath.Join(cfg.kernelObj, cfg.target.KernelObject)
		var err error
		symbols, err = symbolizer.ReadSymbols(kernelObject)
		if err != nil {
			return nil, nil, err
		}
	}
	ctx := &openbsd{
		config:       cfg,
		kernelObject: kernelObject,
		symbols:      symbols,
	}
	return ctx, nil, nil
}

func (ctx *openbsd) ContainsCrash(output []byte) bool {
	return containsCrash(output, openbsdOopses, ctx.ignores)
}

func (ctx *openbsd) Parse(output []byte) *Report {
	stripped := bytes.Replace(output, []byte{'\r', '\n'}, []byte{'\n'}, -1)
	stripped = bytes.Replace(stripped, []byte{'\n', '\r'}, []byte{'\n'}, -1)
	for len(stripped) != 0 && stripped[0] == '\r' {
		stripped = stripped[1:]
	}
	rep := simpleLineParser(stripped, openbsdOopses, nil, ctx.ignores)
	if rep == nil {
		return nil
	}
	rep.Output = output
	return rep
}

func (ctx *openbsd) Symbolize(rep *Report) error {
	symb := symbolizer.NewSymbolizer()
	defer symb.Close()
	var symbolized []byte
	s := bufio.NewScanner(bytes.NewReader(rep.Report))
	prefix := rep.reportPrefixLen
	for s.Scan() {
		line := append([]byte{}, s.Bytes()...)
		line = append(line, '\n')
		newLine := ctx.symbolizeLine(symb.Symbolize, line)
		if prefix > len(symbolized) {
			prefix += len(newLine) - len(line)
		}
		symbolized = append(symbolized, newLine...)
	}
	rep.Report = symbolized
	rep.reportPrefixLen = prefix
	return nil
}

func (ctx *openbsd) symbolizeLine(symbFunc func(bin string, pc uint64) ([]symbolizer.Frame, error),
	line []byte) []byte {
	var match []int
	for _, re := range openbsdSymbolizeRe {
		match = re.FindSubmatchIndex(line)
		if match != nil {
			break
		}
	}
	if match == nil {
		return line
	}
	fn := line[match[2]:match[3]]
	off, err := strconv.ParseUint(string(line[match[4]:match[5]]), 16, 64)
	if err != nil {
		return line
	}

	symb := ctx.symbols[string(fn)]
	if len(symb) == 0 {
		return line
	}
	fnStart := (0xffffffff << 32) | symb[0].Addr

	frames, err := symbFunc(ctx.kernelObject, fnStart+off)
	if err != nil || len(frames) == 0 {
		return line
	}
	var symbolized []byte
	for _, frame := range frames {
		file := frame.File
		file = strings.TrimPrefix(file, ctx.kernelBuildSrc)
		file = strings.TrimPrefix(file, "/")
		info := fmt.Sprintf(" %v:%v", file, frame.Line)
		modified := append([]byte{}, line...)
		modified = replace(modified, match[5], match[5], []byte(info))
		if frame.Inline {
			end := match[5] + len(info)
			modified = replace(modified, end, end, []byte(" [inline]"))
			modified = replace(modified, match[5], match[5], []byte(" "+frame.Func))
		}
		symbolized = append(symbolized, modified...)
	}
	return symbolized
}

var openbsdOopses = []*oops{
	{
		[]byte("cleaned vnode"),
		[]oopsFormat{
			{
				title: compile("cleaned vnode: "),
				fmt:   "panic: cleaned vnode isn't",
			},
		},
		[]*regexp.Regexp{},
	},
	{
		[]byte("panic"),
		[]oopsFormat{
			{
				title: compile("panic: kernel diagnostic assertion (.+) failed: file \".*/([^\"]+)"),
				fmt:   "assert %[1]v failed in %[2]v",
			},
			{
				title: compile("panic: Data modified on freelist: .* previous type ([^ ]+)"),
				fmt:   "malloc: free list modified: %[1]v",
			},
			{
				title: compile("panic: pool_cache_item_magic_check: ([^ ]+) cpu free list modified"),
				fmt:   "pool: cpu free list modified: %[1]v",
			},
			{
				title: compile("panic: pool_do_put: ([^:]+): double pool_put"),
				fmt:   "pool: double put: %[1]v",
			},
			{
				title: compile("panic: pool_do_get: ([^:]+) free list modified"),
				fmt:   "pool: free list modified: %[1]v",
			},
			{
				title: compile("panic: timeout_add: to_ticks \\(.+\\) < 0"),
				fmt:   "panic: timeout_add: to_ticks < 0",
			},
			{
				title: compile("panic: attempt to execute user address {{ADDR}} in supervisor mode"),
				fmt:   "panic: attempt to execute user address",
			},
		},
		[]*regexp.Regexp{},
	},
	{
		[]byte("lock order reversal:"),
		[]oopsFormat{
			{
				title: compile("lock order reversal:\\n+.*1st {{ADDR}} ([^\\ ]+).*\\n.*2nd {{ADDR}} ([^\\ ]+)"),
				fmt:   "witness: reversal: %[1]v %[2]v",
			},
		},
		[]*regexp.Regexp{},
	},
	{
		[]byte("witness:"),
		[]oopsFormat{
			{
				title: compile("witness: thread {{ADDR}} exiting with the following locks held:"),
				fmt:   "witness: thread exiting with locks held",
			},
			{
				title: compile("witness: userret: returning with the following locks held:(.*\\n)+?.*sys_([a-z0-9_]+)\\+"),
				fmt:   "witness: userret: %[2]v",
			},
			{
				title: compile("(witness: .*)"),
				fmt:   "%[1]v",
			},
		},
		[]*regexp.Regexp{},
	},
	{
		[]byte("uvm_fault"),
		[]oopsFormat{
			{
				title: compile("uvm_fault\\((?:.*\\n)+?.*Stopped at[ ]+{{ADDR}}"),
				fmt:   "uvm_fault",
			},
			{
				title: compile("uvm_fault\\((?:.*\\n)+?.*Stopped at[ ]+([^\\+]+)"),
				fmt:   "uvm_fault: %[1]v",
			},
		},
		[]*regexp.Regexp{},
	},
	{
		[]byte("kernel:"),
		[]oopsFormat{
			{
				title: compile("kernel: page fault trap, code=0.*\\nStopped at[ ]+([^\\+]+)"),
				fmt:   "uvm_fault: %[1]v",
			},
		},
		[]*regexp.Regexp{
			compile("reorder_kernel"),
		},
	},
}
