aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2024-03-15 21:21:01 +0100
committerTaras Madan <tarasmadan@google.com>2024-03-20 10:11:25 +0000
commit2c154a8fc72ca5d6a1a6f519d43e943cf5d2957f (patch)
treea8d54f2831e29aa19c77f18bee2412a945070f7d /pkg
parenta485f2390d41decb9fca41e15902295e293464d2 (diff)
pkg/cover: add full symbolization for /cover?jsonl=1
Diffstat (limited to 'pkg')
-rw-r--r--pkg/cover/backend/backend.go13
-rw-r--r--pkg/cover/backend/dwarf.go5
-rw-r--r--pkg/cover/html.go5
-rw-r--r--pkg/cover/report.go46
4 files changed, 39 insertions, 30 deletions
diff --git a/pkg/cover/backend/backend.go b/pkg/cover/backend/backend.go
index 0091adb4f..a343dfe02 100644
--- a/pkg/cover/backend/backend.go
+++ b/pkg/cover/backend/backend.go
@@ -11,12 +11,13 @@ import (
)
type Impl struct {
- Units []*CompileUnit
- Symbols []*Symbol
- Frames []Frame
- Symbolize func(pcs map[*Module][]uint64) ([]Frame, error)
- RestorePC func(pc uint32) uint64
- CoverPoints map[uint64]bool
+ Units []*CompileUnit
+ Symbols []*Symbol
+ Frames []Frame
+ Symbolize func(pcs map[*Module][]uint64) ([]Frame, error)
+ RestorePC func(pc uint32) uint64
+ CallbackPoints map[uint64]bool
+ CoverageCallbackPoints []uint64
}
type Module struct {
diff --git a/pkg/cover/backend/dwarf.go b/pkg/cover/backend/dwarf.go
index 0142afc7e..35ddd27a6 100644
--- a/pkg/cover/backend/dwarf.go
+++ b/pkg/cover/backend/dwarf.go
@@ -261,8 +261,9 @@ func makeDWARFUnsafe(params *dwarfParams) (*Impl, error) {
Symbolize: func(pcs map[*Module][]uint64) ([]Frame, error) {
return symbolize(target, objDir, srcDir, buildDir, splitBuildDelimiters, pcs)
},
- RestorePC: makeRestorePC(params, pcBase),
- CoverPoints: allCoverPointsMap,
+ RestorePC: makeRestorePC(params, pcBase),
+ CallbackPoints: allCoverPointsMap,
+ CoverageCallbackPoints: allCoverPoints[0],
}
return impl, nil
}
diff --git a/pkg/cover/html.go b/pkg/cover/html.go
index 1411bdf62..bfceca2be 100644
--- a/pkg/cover/html.go
+++ b/pkg/cover/html.go
@@ -186,7 +186,7 @@ func fileLineContents(file *file, lines [][]byte) lineCoverExport {
func (rg *ReportGenerator) DoRawCoverFiles(w io.Writer, params CoverHandlerParams) error {
progs := fixUpPCs(rg.target.Arch, params.Progs, params.CoverFilter)
- if err := rg.lazySymbolize(progs); err != nil {
+ if err := rg.symbolizePCs(uniquePCs(progs)); err != nil {
return err
}
@@ -226,6 +226,9 @@ type coverageInfo struct {
// DoCoverJSONL is a handler for "/cover?jsonl=1".
func (rg *ReportGenerator) DoCoverJSONL(w io.Writer, params CoverHandlerParams) error {
+ if err := rg.symbolizePCs(rg.CoverageCallbackPoints); err != nil {
+ return fmt.Errorf("failed to rg.fullSymbolize(): %w", err)
+ }
var progs = fixUpPCs(rg.target.Arch, params.Progs, params.CoverFilter)
fm, err := rg.prepareFileMap(progs, params.Debug)
if err != nil {
diff --git a/pkg/cover/report.go b/pkg/cover/report.go
index 85478d44c..f52a2bcaa 100644
--- a/pkg/cover/report.go
+++ b/pkg/cover/report.go
@@ -11,6 +11,7 @@ import (
"github.com/google/syzkaller/pkg/host"
"github.com/google/syzkaller/pkg/mgrconfig"
"github.com/google/syzkaller/sys/targets"
+ "golang.org/x/exp/maps"
)
type ReportGenerator struct {
@@ -91,7 +92,7 @@ func coverageCallbackMismatch(debug bool, numPCs int, unmatchedProgPCs map[uint6
type fileMap map[string]*file
func (rg *ReportGenerator) prepareFileMap(progs []Prog, debug bool) (fileMap, error) {
- if err := rg.lazySymbolize(progs); err != nil {
+ if err := rg.symbolizePCs(uniquePCs(progs)); err != nil {
return nil, err
}
files := make(fileMap)
@@ -105,14 +106,14 @@ func (rg *ReportGenerator) prepareFileMap(progs []Prog, debug bool) (fileMap, er
}
progPCs := make(map[uint64]map[int]bool)
unmatchedProgPCs := make(map[uint64]bool)
- verifyCoverPoints := (len(rg.CoverPoints) > 0)
+ verifyCallbackPoints := (len(rg.CallbackPoints) > 0)
for i, prog := range progs {
for _, pc := range prog.PCs {
if progPCs[pc] == nil {
progPCs[pc] = make(map[int]bool)
}
progPCs[pc][i] = true
- if verifyCoverPoints && !rg.CoverPoints[pc] {
+ if verifyCallbackPoints && !rg.CallbackPoints[pc] {
unmatchedProgPCs[pc] = true
}
}
@@ -148,7 +149,7 @@ func (rg *ReportGenerator) prepareFileMap(progs []Prog, debug bool) (fileMap, er
}
// If the backend provided coverage callback locations for the binaries, use them to
// verify data returned by kcov.
- if verifyCoverPoints && (len(unmatchedProgPCs) > 0) {
+ if verifyCallbackPoints && (len(unmatchedProgPCs) > 0) {
return nil, coverageCallbackMismatch(debug, len(progPCs), unmatchedProgPCs)
}
for _, unit := range rg.Units {
@@ -180,29 +181,32 @@ func (rg *ReportGenerator) prepareFileMap(progs []Prog, debug bool) (fileMap, er
return files, nil
}
-func (rg *ReportGenerator) lazySymbolize(progs []Prog) error {
+func uniquePCs(progs []Prog) []uint64 {
+ PCs := make(map[uint64]bool)
+ for _, p := range progs {
+ for _, pc := range p.PCs {
+ PCs[pc] = true
+ }
+ }
+ return maps.Keys(PCs)
+}
+
+func (rg *ReportGenerator) symbolizePCs(PCs []uint64) error {
+ if len(PCs) == 0 {
+ return fmt.Errorf("no coverage collected so far to symbolize")
+ }
if len(rg.Symbols) == 0 {
return nil
}
symbolize := make(map[*backend.Symbol]bool)
- uniquePCs := make(map[uint64]bool)
pcs := make(map[*backend.Module][]uint64)
- for _, prog := range progs {
- for _, pc := range prog.PCs {
- if uniquePCs[pc] {
- continue
- }
- uniquePCs[pc] = true
- sym := rg.findSymbol(pc)
- if sym == nil || (sym.Symbolized || symbolize[sym]) {
- continue
- }
- symbolize[sym] = true
- pcs[sym.Module] = append(pcs[sym.Module], sym.PCs...)
+ for _, pc := range PCs {
+ sym := rg.findSymbol(pc)
+ if sym == nil || sym.Symbolized || symbolize[sym] {
+ continue
}
- }
- if len(uniquePCs) == 0 {
- return fmt.Errorf("no coverage collected so far")
+ symbolize[sym] = true
+ pcs[sym.Module] = append(pcs[sym.Module], sym.PCs...)
}
frames, err := rg.Symbolize(pcs)
if err != nil {