mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-24 11:59:58 +00:00
3d85f48c14
On FreeBSD getVMOffset() always returned 0 instead of 0xffffffff. This breaks the usage of addr2line. For now, just return always 0xffffffff on FreeBSD, since a more sophisticated logic doesn't seem to be required by now. Thanks to Dmitry for pointing out that this functions provides the prefix address.
92 lines
2.1 KiB
Go
92 lines
2.1 KiB
Go
// Copyright 2015 syzkaller project authors. All rights reserved.
|
|
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
|
|
|
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/google/syzkaller/pkg/cover"
|
|
"github.com/google/syzkaller/pkg/osutil"
|
|
)
|
|
|
|
var (
|
|
initCoverOnce sync.Once
|
|
initCoverError error
|
|
initCoverVMOffset uint32
|
|
reportGenerator *cover.ReportGenerator
|
|
)
|
|
|
|
func initCover(kernelObj, kernelObjName, kernelSrc, arch, OS string) error {
|
|
if kernelObj == "" {
|
|
return fmt.Errorf("kernel_obj is not specified")
|
|
}
|
|
vmlinux := filepath.Join(kernelObj, kernelObjName)
|
|
var err error
|
|
reportGenerator, err = cover.MakeReportGenerator(vmlinux, kernelSrc, arch)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
initCoverVMOffset, err = getVMOffset(vmlinux, OS)
|
|
return err
|
|
}
|
|
|
|
func generateCoverHTML(w io.Writer, kernelObj, kernelObjName, kernelSrc, arch, OS string, cov cover.Cover) error {
|
|
if len(cov) == 0 {
|
|
return fmt.Errorf("no coverage data available")
|
|
}
|
|
initCoverOnce.Do(func() { initCoverError = initCover(kernelObj, kernelObjName, kernelSrc, arch, OS) })
|
|
if initCoverError != nil {
|
|
return initCoverError
|
|
}
|
|
pcs := make([]uint64, 0, len(cov))
|
|
for pc := range cov {
|
|
pcs = append(pcs, cover.RestorePC(pc, initCoverVMOffset))
|
|
}
|
|
return reportGenerator.Do(w, pcs)
|
|
}
|
|
|
|
func getVMOffset(vmlinux, OS string) (uint32, error) {
|
|
if OS == "freebsd" {
|
|
return 0xffffffff, nil
|
|
}
|
|
out, err := osutil.RunCmd(time.Hour, "", "readelf", "-SW", vmlinux)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
s := bufio.NewScanner(bytes.NewReader(out))
|
|
var addr uint32
|
|
for s.Scan() {
|
|
ln := s.Text()
|
|
pieces := strings.Fields(ln)
|
|
for i := 0; i < len(pieces); i++ {
|
|
if pieces[i] != "PROGBITS" {
|
|
continue
|
|
}
|
|
v, err := strconv.ParseUint("0x"+pieces[i+1], 0, 64)
|
|
if err != nil {
|
|
return 0, fmt.Errorf("failed to parse addr in readelf output: %v", err)
|
|
}
|
|
if v == 0 {
|
|
continue
|
|
}
|
|
v32 := (uint32)(v >> 32)
|
|
if addr == 0 {
|
|
addr = v32
|
|
}
|
|
if addr != v32 {
|
|
return 0, fmt.Errorf("different section offsets in a single binary")
|
|
}
|
|
}
|
|
}
|
|
return addr, nil
|
|
}
|