aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-12-12 10:29:59 +0100
committerDmitry Vyukov <dvyukov@google.com>2020-12-13 18:56:36 +0100
commit3a7cbae43a7c07056c6f5219bc68613087287333 (patch)
treeeb4690b3ec68d894da7c15cadb99669299b0a333 /pkg
parentff8609bfeb35e2b35cc1057942301cf476e29e3b (diff)
pkg/cover: move cleanPath into backend
gvisor will need some custom logic there, so make it part of backend.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/cover/backend/backend.go18
-rw-r--r--pkg/cover/backend/elf.go36
-rw-r--r--pkg/cover/report.go31
3 files changed, 46 insertions, 39 deletions
diff --git a/pkg/cover/backend/backend.go b/pkg/cover/backend/backend.go
index 405cbaa3f..6df629d74 100644
--- a/pkg/cover/backend/backend.go
+++ b/pkg/cover/backend/backend.go
@@ -4,6 +4,8 @@
package backend
import (
+ "fmt"
+
"github.com/google/syzkaller/pkg/symbolizer"
"github.com/google/syzkaller/sys/targets"
)
@@ -11,8 +13,8 @@ import (
type Impl struct {
Units []*CompileUnit
Symbols []*Symbol
- Frames []symbolizer.Frame
- Symbolize func(pcs []uint64) ([]symbolizer.Frame, error)
+ Frames []Frame
+ Symbolize func(pcs []uint64) ([]Frame, error)
RestorePC func(pc uint32) uint64
}
@@ -31,6 +33,14 @@ type Symbol struct {
Symbolized bool
}
-func Make(target *targets.Target, vm, objDir string) (*Impl, error) {
- return makeELF(target, objDir)
+type Frame struct {
+ symbolizer.Frame
+ Path string
+}
+
+func Make(target *targets.Target, vm, objDir, srcDir, buildDir string) (*Impl, error) {
+ if objDir == "" {
+ return nil, fmt.Errorf("kernel obj directory is not specified")
+ }
+ return makeELF(target, objDir, srcDir, buildDir)
}
diff --git a/pkg/cover/backend/elf.go b/pkg/cover/backend/elf.go
index c8e0879b0..848422c76 100644
--- a/pkg/cover/backend/elf.go
+++ b/pkg/cover/backend/elf.go
@@ -15,13 +15,14 @@ import (
"runtime"
"sort"
"strconv"
+ "strings"
"github.com/google/syzkaller/pkg/osutil"
"github.com/google/syzkaller/pkg/symbolizer"
"github.com/google/syzkaller/sys/targets"
)
-func makeELF(target *targets.Target, objDir string) (*Impl, error) {
+func makeELF(target *targets.Target, objDir, srcDir, buildDir string) (*Impl, error) {
kernelObject := filepath.Join(objDir, target.KernelObject)
file, err := elf.Open(kernelObject)
if err != nil {
@@ -66,6 +67,7 @@ func makeELF(target *targets.Target, objDir string) (*Impl, error) {
if len(unit.PCs) == 0 {
continue // drop the unit
}
+ unit.Name, unit.Path = cleanPath(unit.Name, objDir, srcDir, buildDir)
units[nunit] = unit
nunit++
}
@@ -76,8 +78,8 @@ func makeELF(target *targets.Target, objDir string) (*Impl, error) {
impl := &Impl{
Units: units,
Symbols: symbols,
- Symbolize: func(pcs []uint64) ([]symbolizer.Frame, error) {
- return symbolize(target, kernelObject, pcs)
+ Symbolize: func(pcs []uint64) ([]Frame, error) {
+ return symbolize(target, objDir, srcDir, buildDir, kernelObject, pcs)
},
RestorePC: func(pc uint32) uint64 {
return PreviousInstructionPC(target, RestorePC(pc, uint32(textAddr>>32)))
@@ -237,7 +239,7 @@ func readTextRanges(file *elf.File) ([]pcRange, []*CompileUnit, error) {
return ranges, units, nil
}
-func symbolize(target *targets.Target, obj string, pcs []uint64) ([]symbolizer.Frame, error) {
+func symbolize(target *targets.Target, objDir, srcDir, buildDir, obj string, pcs []uint64) ([]Frame, error) {
procs := runtime.GOMAXPROCS(0) / 2
if need := len(pcs) / 1000; procs > need {
procs = need
@@ -284,13 +286,17 @@ func symbolize(target *targets.Target, obj string, pcs []uint64) ([]symbolizer.F
}
close(pcchan)
var err0 error
- var frames []symbolizer.Frame
+ var frames []Frame
for p := 0; p < procs; p++ {
res := <-symbolizerC
if res.err != nil {
err0 = res.err
}
- frames = append(frames, res.frames...)
+ for _, frame := range res.frames {
+ wrap := Frame{frame, ""}
+ wrap.File, wrap.Path = cleanPath(frame.File, objDir, srcDir, buildDir)
+ frames = append(frames, wrap)
+ }
}
if err0 != nil {
return nil, err0
@@ -403,6 +409,24 @@ func parseLine(callInsns, traceFuncs [][]byte, ln []byte) uint64 {
return pc
}
+func cleanPath(path, objDir, srcDir, buildDir string) (string, string) {
+ filename := ""
+ switch {
+ case strings.HasPrefix(path, objDir):
+ // Assume the file was built there.
+ path = strings.TrimPrefix(path, objDir)
+ filename = filepath.Join(objDir, path)
+ case strings.HasPrefix(path, buildDir):
+ // Assume the file was moved from buildDir to srcDir.
+ path = strings.TrimPrefix(path, buildDir)
+ filename = filepath.Join(srcDir, path)
+ default:
+ // Assume this is relative path.
+ filename = filepath.Join(srcDir, path)
+ }
+ return strings.TrimLeft(filepath.Clean(path), "/\\"), filename
+}
+
func archCallInsn(target *targets.Target) ([][]byte, [][]byte) {
callName := [][]byte{[]byte(" <__sanitizer_cov_trace_pc>")}
switch target.Arch {
diff --git a/pkg/cover/report.go b/pkg/cover/report.go
index 234c30823..e7cf639fc 100644
--- a/pkg/cover/report.go
+++ b/pkg/cover/report.go
@@ -5,9 +5,7 @@ package cover
import (
"fmt"
- "path/filepath"
"sort"
- "strings"
"github.com/google/syzkaller/pkg/cover/backend"
"github.com/google/syzkaller/sys/targets"
@@ -29,10 +27,7 @@ type Prog struct {
var RestorePC = backend.RestorePC
func MakeReportGenerator(target *targets.Target, vm, objDir, srcDir, buildDir string) (*ReportGenerator, error) {
- if objDir == "" {
- return nil, fmt.Errorf("kernel obj directory is not specified")
- }
- impl, err := backend.Make(target, vm, objDir)
+ impl, err := backend.Make(target, vm, objDir, srcDir, buildDir)
if err != nil {
return nil, err
}
@@ -43,9 +38,6 @@ func MakeReportGenerator(target *targets.Target, vm, objDir, srcDir, buildDir st
buildDir: buildDir,
Impl: impl,
}
- for _, unit := range rg.Units {
- unit.Name, unit.Path = rg.cleanPath(unit.Name)
- }
return rg, nil
}
@@ -92,8 +84,7 @@ func (rg *ReportGenerator) prepareFileMap(progs []Prog) (map[string]*file, error
}
matchedPC := false
for _, frame := range rg.Frames {
- name, path := rg.cleanPath(frame.File)
- f := getFile(files, name, path)
+ f := getFile(files, frame.File, frame.Path)
ln := f.lines[frame.Line]
coveredBy := progPCs[frame.PC]
if len(coveredBy) != 0 {
@@ -204,24 +195,6 @@ func getFile(files map[string]*file, name, path string) *file {
return f
}
-func (rg *ReportGenerator) cleanPath(path string) (string, string) {
- filename := ""
- switch {
- case strings.HasPrefix(path, rg.objDir):
- // Assume the file was built there.
- path = strings.TrimPrefix(path, rg.objDir)
- filename = filepath.Join(rg.objDir, path)
- case strings.HasPrefix(path, rg.buildDir):
- // Assume the file was moved from buildDir to srcDir.
- path = strings.TrimPrefix(path, rg.buildDir)
- filename = filepath.Join(rg.srcDir, path)
- default:
- // Assume this is relative path.
- filename = filepath.Join(rg.srcDir, path)
- }
- return strings.TrimLeft(filepath.Clean(path), "/\\"), filename
-}
-
func (rg *ReportGenerator) findSymbol(pc uint64) *backend.Symbol {
idx := sort.Search(len(rg.Symbols), func(i int) bool {
return pc < rg.Symbols[i].End