aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/cover/backend/backend.go
blob: 5833a13fb20ab77582dcdf0f08a0af922aadc5f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Copyright 2020 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 backend

import (
	"fmt"

	"github.com/google/syzkaller/pkg/mgrconfig"
	"github.com/google/syzkaller/pkg/vminfo"
	"github.com/google/syzkaller/sys/targets"
)

type Impl struct {
	Units           []*CompileUnit
	Symbols         []*Symbol
	Frames          []*Frame
	Symbolize       func(pcs map[*vminfo.KernelModule][]uint64) ([]*Frame, error)
	CallbackPoints  []uint64
	PreciseCoverage bool
}

type CompileUnit struct {
	ObjectUnit
	Path   string
	Module *vminfo.KernelModule
}

type Symbol struct {
	ObjectUnit
	Module     *vminfo.KernelModule
	Unit       *CompileUnit
	Start      uint64
	End        uint64
	Symbolized bool
}

// ObjectUnit represents either CompileUnit or Symbol.
type ObjectUnit struct {
	Name string
	PCs  []uint64 // PCs we can get in coverage callbacks for this unit.
	CMPs []uint64 // PCs we can get in comparison interception callbacks for this unit.
}

type Frame struct {
	Module   *vminfo.KernelModule
	PC       uint64
	Name     string
	FuncName string
	Path     string
	Inline   bool
	Range
}

type Range struct {
	StartLine int
	StartCol  int
	EndLine   int
	EndCol    int
}

type SecRange struct {
	Start uint64
	End   uint64
}

const LineEnd = 1 << 30

func Make(cfg *mgrconfig.Config, modules []*vminfo.KernelModule) (*Impl, error) {
	kernelDirs := cfg.KernelDirs()
	target := cfg.SysTarget
	moduleObj := cfg.ModuleObj
	vm := cfg.Type
	if kernelDirs.Obj == "" {
		return nil, fmt.Errorf("kernel obj directory is not specified")
	}
	if target.OS == targets.Darwin {
		return makeMachO(target, kernelDirs, moduleObj, modules)
	}
	if vm == targets.GVisor {
		return makeGvisor(target, kernelDirs, modules)
	}
	var delimiters []string
	if cfg.AndroidSplitBuild {
		// Path prefixes used by Android Pixel kernels. See
		// https://source.android.com/docs/setup/build/building-pixel-kernels for more
		// details.
		delimiters = []string{"/aosp/", "/private/"}
	}
	return makeELF(target, kernelDirs, delimiters, moduleObj, modules)
}

func GetPCBase(cfg *mgrconfig.Config) (uint64, error) {
	if cfg.Target.OS == targets.Linux && cfg.Type != targets.GVisor && cfg.Type != targets.Starnix {
		return getLinuxPCBase(cfg)
	}
	return 0, nil
}