aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2021-03-16 16:41:19 +0100
committerDmitry Vyukov <dvyukov@google.com>2021-03-18 09:17:51 +0100
commit5c9b22d8987802fb1fc6db94815db77b1d821c73 (patch)
tree2d7a7d56f030a0c84b781ee6134d607e6e694dec /pkg
parentb2e2064c210dded5b1b226df7806224c7d84d413 (diff)
pkg/cover: fix GroupPCsByModule
Both elf.go and gvisor.go are compiled into the same package, so GroupPCsByModule callback gets installed for gvisor as well. Move all modules-related logic into backend. Splitting by modules is the only modules-related part left in the common code. Move it into backend. This make Modules field unnecessary in the backend.Impl. Also move assignment to frame.Module to symbolize, reduces overall code size.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/cover/backend/backend.go9
-rw-r--r--pkg/cover/backend/elf.go90
-rw-r--r--pkg/cover/report.go16
3 files changed, 53 insertions, 62 deletions
diff --git a/pkg/cover/backend/backend.go b/pkg/cover/backend/backend.go
index 29b413943..659a37a60 100644
--- a/pkg/cover/backend/backend.go
+++ b/pkg/cover/backend/backend.go
@@ -17,9 +17,8 @@ type Impl struct {
Units []*CompileUnit
Symbols []*Symbol
Frames []Frame
- Symbolize func(pcs []uint64, obj string) ([]Frame, error)
+ Symbolize func(pcs []uint64) ([]Frame, error)
RestorePC func(pc uint32) uint64
- Modules []*KernelModule
}
type CompileUnit struct {
@@ -66,9 +65,3 @@ func Make(target *targets.Target, vm, srcDir, buildDir string,
}
return makeELF(target, srcDir, buildDir, moduleObj, modules)
}
-
-var GroupPCsByModule = func(pcs []uint64, modules []*KernelModule) map[*KernelModule][]uint64 {
- groupPCs := make(map[*KernelModule][]uint64)
- groupPCs[modules[0]] = pcs
- return groupPCs
-}
diff --git a/pkg/cover/backend/elf.go b/pkg/cover/backend/elf.go
index 96251cc50..516710efe 100644
--- a/pkg/cover/backend/elf.go
+++ b/pkg/cover/backend/elf.go
@@ -25,10 +25,6 @@ import (
"github.com/google/syzkaller/sys/targets"
)
-func init() {
- GroupPCsByModule = groupPCsByModule
-}
-
func makeELF(target *targets.Target, srcDir, buildDir string,
moduleObj []string, modules []*KernelModule) (*Impl, error) {
var allCoverPoints [2][]uint64
@@ -135,14 +131,12 @@ func makeELF(target *targets.Target, srcDir, buildDir string,
impl := &Impl{
Units: allUnits,
Symbols: allSymbols,
- Symbolize: func(pcs []uint64, obj string) ([]Frame, error) {
- objDir := modules[0].Path // TODO: won't work for out-of-tree modules
- return symbolize(target, objDir, srcDir, buildDir, obj, pcs)
+ Symbolize: func(pcs []uint64) ([]Frame, error) {
+ return symbolize(target, srcDir, buildDir, modules, pcs)
},
RestorePC: func(pc uint32) uint64 {
return PreviousInstructionPC(target, RestorePC(pc, uint32(modules[0].Addr>>32)))
},
- Modules: modules,
}
return impl, nil
}
@@ -251,35 +245,6 @@ func searchModuleName(data []byte) string {
return string(data[pos+len(key) : end])
}
-func groupPCsByModule(pcs []uint64, modules []*KernelModule) map[*KernelModule][]uint64 {
- groupPCs := make(map[*KernelModule][]uint64)
- smodules := append([]*KernelModule{}, modules...)
- sort.Slice(smodules, func(i, j int) bool {
- return smodules[i].Addr > smodules[j].Addr
- })
- for _, pc := range pcs {
- if pc > smodules[0].Addr {
- if smodules[0].Name == "" {
- groupPCs[smodules[0]] = append(groupPCs[smodules[0]], pc)
- } else {
- groupPCs[smodules[0]] = append(groupPCs[smodules[0]], pc-smodules[0].Addr)
- }
- } else {
- for i := 0; i < len(modules)-1; i++ {
- if pc < smodules[i].Addr && pc >= smodules[i+1].Addr {
- if smodules[i+1].Name == "" {
- groupPCs[smodules[i+1]] = append(groupPCs[smodules[i+1]], pc)
- } else {
- groupPCs[smodules[i+1]] = append(groupPCs[smodules[i+1]], pc-smodules[i+1].Addr)
- }
- break
- }
- }
- }
- }
- return groupPCs
-}
-
type pcRange struct {
start uint64
end uint64
@@ -461,7 +426,47 @@ func readTextRanges(file *elf.File, module *KernelModule) ([]pcRange, []*Compile
return ranges, units, nil
}
-func symbolize(target *targets.Target, objDir, srcDir, buildDir, obj string, pcs []uint64) ([]Frame, error) {
+func symbolize(target *targets.Target, srcDir, buildDir string, modules []*KernelModule, pcs []uint64) (
+ []Frame, error) {
+ groupPCs := make(map[*KernelModule][]uint64)
+ smodules := append([]*KernelModule{}, modules...)
+ sort.Slice(smodules, func(i, j int) bool {
+ return smodules[i].Addr > smodules[j].Addr
+ })
+ for _, pc := range pcs {
+ if pc > smodules[0].Addr {
+ if smodules[0].Name == "" {
+ groupPCs[smodules[0]] = append(groupPCs[smodules[0]], pc)
+ } else {
+ groupPCs[smodules[0]] = append(groupPCs[smodules[0]], pc-smodules[0].Addr)
+ }
+ } else {
+ for i := 0; i < len(modules)-1; i++ {
+ if pc < smodules[i].Addr && pc >= smodules[i+1].Addr {
+ if smodules[i+1].Name == "" {
+ groupPCs[smodules[i+1]] = append(groupPCs[smodules[i+1]], pc)
+ } else {
+ groupPCs[smodules[i+1]] = append(groupPCs[smodules[i+1]], pc-smodules[i+1].Addr)
+ }
+ break
+ }
+ }
+ }
+ }
+ var frames []Frame
+ for mod, pcs := range groupPCs {
+ objDir := modules[0].Path // TODO: won't work for out-of-tree modules
+ frames1, err := symbolizeModule(target, objDir, srcDir, buildDir, mod, pcs)
+ if err != nil {
+ return nil, err
+ }
+ frames = append(frames, frames1...)
+ }
+ return frames, nil
+}
+
+func symbolizeModule(target *targets.Target, objDir, srcDir, buildDir string, mod *KernelModule, pcs []uint64) (
+ []Frame, error) {
procs := runtime.GOMAXPROCS(0) / 2
if need := len(pcs) / 1000; procs > need {
procs = need
@@ -489,7 +494,7 @@ func symbolize(target *targets.Target, objDir, srcDir, buildDir, obj string, pcs
defer symb.Close()
var res symbolizerResult
for pcs := range pcchan {
- frames, err := symb.SymbolizeArray(obj, pcs)
+ frames, err := symb.SymbolizeArray(mod.Path, pcs)
if err != nil {
res.err = fmt.Errorf("failed to symbolize: %v", err)
}
@@ -517,9 +522,10 @@ func symbolize(target *targets.Target, objDir, srcDir, buildDir, obj string, pcs
for _, frame := range res.frames {
name, path := cleanPath(frame.File, objDir, srcDir, buildDir)
frames = append(frames, Frame{
- PC: frame.PC,
- Name: name,
- Path: path,
+ Module: mod,
+ PC: frame.PC,
+ Name: name,
+ Path: path,
Range: Range{
StartLine: frame.Line,
StartCol: 0,
diff --git a/pkg/cover/report.go b/pkg/cover/report.go
index 222bcdfa6..feb5069cf 100644
--- a/pkg/cover/report.go
+++ b/pkg/cover/report.go
@@ -195,19 +195,11 @@ func (rg *ReportGenerator) lazySymbolize(progs []Prog) error {
if len(pcs) == 0 {
return nil
}
- for mod, pcs := range backend.GroupPCsByModule(pcs, rg.Modules) {
- if len(pcs) == 0 {
- continue
- }
- frames, err := rg.Symbolize(pcs, mod.Path)
- if err != nil {
- return err
- }
- for i := range frames {
- frames[i].Module = mod
- }
- rg.Frames = append(rg.Frames, frames...)
+ frames, err := rg.Symbolize(pcs)
+ if err != nil {
+ return err
}
+ rg.Frames = append(rg.Frames, frames...)
for sym := range symbolize {
sym.Symbolized = true
}