From 5c9b22d8987802fb1fc6db94815db77b1d821c73 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Tue, 16 Mar 2021 16:41:19 +0100 Subject: 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. --- pkg/cover/backend/backend.go | 9 +---- pkg/cover/backend/elf.go | 90 +++++++++++++++++++++++--------------------- pkg/cover/report.go | 16 ++------ 3 files changed, 53 insertions(+), 62 deletions(-) (limited to 'pkg') 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 } -- cgit mrf-deployment