// allPcsInFuncs returns all PCs with __sanitizer_cov_trace_pc calls in functions containing pcs. func allPcsInFuncs(vmlinux string, pcs []uint64) ([]uint64, error) { allSymbols, err := symbolizer.ReadSymbols(vmlinux) if err != nil { return nil, fmt.Errorf("failed to run nm on vmlinux: %v", err) } var symbols symbolArray for name, ss := range allSymbols { for _, s := range ss { symbols = append(symbols, symbol{s.Addr, s.Addr + uint64(s.Size), name}) } } sort.Sort(symbols) <-allCoverReady if len(allCoverPCs) == 0 { return nil, nil } var allPcs []uint64 for _, pc := range pcs { idx := sort.Search(len(symbols), func(i int) bool { return pc < symbols[i].end }) if idx == len(symbols) { continue } s := symbols[idx] if pc < s.start || pc > s.end { continue } startPC := sort.Search(len(allCoverPCs), func(i int) bool { return s.start <= allCoverPCs[i] }) endPC := sort.Search(len(allCoverPCs), func(i int) bool { return s.end < allCoverPCs[i] }) allPcs = append(allPcs, allCoverPCs[startPC:endPC]...) } return allPcs, nil }
func Symbolize(vmlinux string, text []byte) ([]byte, error) { var symbolized []byte symbols, err := symbolizer.ReadSymbols(vmlinux) if err != nil { return nil, err } symb := symbolizer.NewSymbolizer() defer symb.Close() symbFunc := func(bin string, pc uint64) ([]symbolizer.Frame, error) { return symb.Symbolize(bin, pc) } // Strip vmlinux location from all paths. strip, _ := filepath.Abs(vmlinux) strip = filepath.Dir(strip) + string(filepath.Separator) // Vmlinux may have been moved, so check if we can find debug info // for __sanitizer_cov_trace_pc. We know where it is located, // so we can infer correct strip prefix from it. if covSymbols := symbols["__sanitizer_cov_trace_pc"]; len(covSymbols) != 0 { for _, covSymb := range covSymbols { frames, _ := symb.Symbolize(vmlinux, covSymb.Addr) if len(frames) > 0 { file := frames[len(frames)-1].File if idx := strings.Index(file, "kernel/kcov.c"); idx != -1 { strip = file[:idx] break } } } } s := bufio.NewScanner(bytes.NewReader(text)) for s.Scan() { line := append([]byte{}, s.Bytes()...) line = append(line, '\n') line = symbolizeLine(symbFunc, symbols, vmlinux, strip, line) symbolized = append(symbolized, line...) } return symbolized, nil }