예제 #1
0
파일: cover.go 프로젝트: sploving/syzkaller
// 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
}
예제 #2
0
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
}