github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/pkg/manager/report_generator.go (about)

     1  // Copyright 2015 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  package manager
     5  
     6  import (
     7  	"fmt"
     8  	"sync"
     9  
    10  	"github.com/google/syzkaller/pkg/cover"
    11  	"github.com/google/syzkaller/pkg/cover/backend"
    12  	"github.com/google/syzkaller/pkg/log"
    13  	"github.com/google/syzkaller/pkg/mgrconfig"
    14  	"github.com/google/syzkaller/pkg/vminfo"
    15  )
    16  
    17  type ReportGeneratorWrapper struct {
    18  	cfg     *mgrconfig.Config
    19  	modules []*vminfo.KernelModule
    20  
    21  	mu          sync.Mutex
    22  	initialized bool
    23  	cached      *cover.ReportGenerator
    24  }
    25  
    26  func ReportGeneratorCache(cfg *mgrconfig.Config) *ReportGeneratorWrapper {
    27  	return &ReportGeneratorWrapper{cfg: cfg}
    28  }
    29  
    30  func (w *ReportGeneratorWrapper) Get() (*cover.ReportGenerator, error) {
    31  	w.mu.Lock()
    32  	defer w.mu.Unlock()
    33  	if !w.initialized {
    34  		return nil, fmt.Errorf("report generator creation before Init() is called")
    35  	}
    36  	if w.cached == nil {
    37  		log.Logf(0, "initializing coverage information...")
    38  		rg, err := cover.MakeReportGenerator(w.cfg, w.modules)
    39  		if err != nil {
    40  			return nil, err
    41  		}
    42  		w.cached = rg
    43  	}
    44  	return w.cached, nil
    45  }
    46  
    47  func (w *ReportGeneratorWrapper) Init(modules []*vminfo.KernelModule) {
    48  	w.mu.Lock()
    49  	defer w.mu.Unlock()
    50  	if w.initialized {
    51  		panic("Init() called twice")
    52  	}
    53  	w.initialized = true
    54  	w.modules = modules
    55  }
    56  
    57  func (w *ReportGeneratorWrapper) Reset() {
    58  	w.mu.Lock()
    59  	defer w.mu.Unlock()
    60  	w.cached = nil
    61  }
    62  
    63  func CoverToPCs(cfg *mgrconfig.Config, cov []uint64) []uint64 {
    64  	pcs := make([]uint64, 0, len(cov))
    65  	for _, pc := range cov {
    66  		prev := backend.PreviousInstructionPC(cfg.SysTarget, cfg.Type, pc)
    67  		pcs = append(pcs, prev)
    68  	}
    69  	return pcs
    70  }