diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2021-03-16 16:41:19 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2021-03-18 09:17:51 +0100 |
| commit | 5c9b22d8987802fb1fc6db94815db77b1d821c73 (patch) | |
| tree | 2d7a7d56f030a0c84b781ee6134d607e6e694dec /pkg | |
| parent | b2e2064c210dded5b1b226df7806224c7d84d413 (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.go | 9 | ||||
| -rw-r--r-- | pkg/cover/backend/elf.go | 90 | ||||
| -rw-r--r-- | pkg/cover/report.go | 16 |
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 } |
