diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2020-12-12 10:29:59 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2020-12-13 18:56:36 +0100 |
| commit | 3a7cbae43a7c07056c6f5219bc68613087287333 (patch) | |
| tree | eb4690b3ec68d894da7c15cadb99669299b0a333 /pkg | |
| parent | ff8609bfeb35e2b35cc1057942301cf476e29e3b (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.go | 18 | ||||
| -rw-r--r-- | pkg/cover/backend/elf.go | 36 | ||||
| -rw-r--r-- | pkg/cover/report.go | 31 |
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 |
