mirror of
https://github.com/reactos/syzkaller.git
synced 2025-02-07 12:26:40 +00:00
pkg/cover: add test for report generation
Test various combinations of no debug info, no coverage instrumentation, no PCs, bad PCs, good PCs, and what errors we produce for these. Also implement support for cross-arch reports: prefix objdump with cross-compile prefix (e.g. aarch64-linux-gnu-objdump instead of objdump).
This commit is contained in:
parent
9072c1268e
commit
fdf90f622b
@ -19,9 +19,11 @@ import (
|
||||
|
||||
"github.com/google/syzkaller/pkg/osutil"
|
||||
"github.com/google/syzkaller/pkg/symbolizer"
|
||||
"github.com/google/syzkaller/sys/targets"
|
||||
)
|
||||
|
||||
type ReportGenerator struct {
|
||||
target *targets.Target
|
||||
srcDir string
|
||||
buildDir string
|
||||
objDir string
|
||||
@ -39,26 +41,24 @@ type symbol struct {
|
||||
end uint64
|
||||
}
|
||||
|
||||
func MakeReportGenerator(vmlinux, srcDir, buildDir, arch string) (*ReportGenerator, error) {
|
||||
func MakeReportGenerator(target *targets.Target, kernelObject, srcDir, buildDir string) (*ReportGenerator, error) {
|
||||
rg := &ReportGenerator{
|
||||
target: target,
|
||||
srcDir: srcDir,
|
||||
buildDir: buildDir,
|
||||
objDir: filepath.Dir(vmlinux),
|
||||
objDir: filepath.Dir(kernelObject),
|
||||
pcs: make(map[uint64][]symbolizer.Frame),
|
||||
}
|
||||
errc := make(chan error)
|
||||
go func() {
|
||||
var err error
|
||||
rg.symbols, err = readSymbols(vmlinux)
|
||||
rg.symbols, err = readSymbols(kernelObject)
|
||||
errc <- err
|
||||
}()
|
||||
frames, err := objdumpAndSymbolize(vmlinux, arch)
|
||||
frames, err := objdumpAndSymbolize(target, kernelObject)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(frames) == 0 {
|
||||
return nil, fmt.Errorf("%v does not have debug info (set CONFIG_DEBUG_INFO=y)", vmlinux)
|
||||
}
|
||||
if err := <-errc; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -85,10 +85,12 @@ type line struct {
|
||||
|
||||
func (rg *ReportGenerator) Do(w io.Writer, progs []Prog) error {
|
||||
coveredPCs := make(map[uint64]bool)
|
||||
allPCs := make(map[uint64]bool)
|
||||
symbols := make(map[uint64]bool)
|
||||
files := make(map[string]*file)
|
||||
for progIdx, prog := range progs {
|
||||
for _, pc := range prog.PCs {
|
||||
allPCs[pc] = true
|
||||
symbols[rg.findSymbol(pc)] = true
|
||||
frames, ok := rg.pcs[pc]
|
||||
if !ok {
|
||||
@ -110,8 +112,11 @@ func (rg *ReportGenerator) Do(w io.Writer, progs []Prog) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(allPCs) == 0 {
|
||||
return fmt.Errorf("no coverage collected so far")
|
||||
}
|
||||
if len(coveredPCs) == 0 {
|
||||
return fmt.Errorf("no coverage data available")
|
||||
return fmt.Errorf("coverage (%v) doesn't match coverage callbacks", len(allPCs))
|
||||
}
|
||||
for pc, frames := range rg.pcs {
|
||||
covered := coveredPCs[pc]
|
||||
@ -334,8 +339,8 @@ func readSymbols(obj string) ([]symbol, error) {
|
||||
|
||||
// objdumpAndSymbolize collects list of PCs of __sanitizer_cov_trace_pc calls
|
||||
// in the kernel and symbolizes them.
|
||||
func objdumpAndSymbolize(obj, arch string) ([]symbolizer.Frame, error) {
|
||||
errc := make(chan error)
|
||||
func objdumpAndSymbolize(target *targets.Target, obj string) ([]symbolizer.Frame, error) {
|
||||
errc := make(chan error, 1)
|
||||
pcchan := make(chan []uint64, 10)
|
||||
var frames []symbolizer.Frame
|
||||
go func() {
|
||||
@ -354,12 +359,21 @@ func objdumpAndSymbolize(obj, arch string) ([]symbolizer.Frame, error) {
|
||||
}
|
||||
errc <- err
|
||||
}()
|
||||
cmd := osutil.Command("objdump", "-d", "--no-show-raw-insn", obj)
|
||||
objdump := "objdump"
|
||||
if target.Triple != "" {
|
||||
objdump = target.Triple + "-" + objdump
|
||||
}
|
||||
cmd := osutil.Command(objdump, "-d", "--no-show-raw-insn", obj)
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer stdout.Close()
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer stderr.Close()
|
||||
if err := cmd.Start(); err != nil {
|
||||
return nil, fmt.Errorf("failed to run objdump on %v: %v", obj, err)
|
||||
}
|
||||
@ -368,46 +382,76 @@ func objdumpAndSymbolize(obj, arch string) ([]symbolizer.Frame, error) {
|
||||
cmd.Wait()
|
||||
}()
|
||||
s := bufio.NewScanner(stdout)
|
||||
callInsnS, traceFuncS := archCallInsn(arch)
|
||||
callInsn, traceFunc := []byte(callInsnS), []byte(traceFuncS)
|
||||
callInsns, traceFuncs := archCallInsn(target)
|
||||
var pcs []uint64
|
||||
npcs := 0
|
||||
for s.Scan() {
|
||||
ln := s.Bytes()
|
||||
if pos := bytes.Index(ln, callInsn); pos == -1 {
|
||||
continue
|
||||
} else if !bytes.Contains(ln[pos:], traceFunc) {
|
||||
continue
|
||||
}
|
||||
for len(ln) != 0 && ln[0] == ' ' {
|
||||
ln = ln[1:]
|
||||
}
|
||||
colon := bytes.IndexByte(ln, ':')
|
||||
if colon == -1 {
|
||||
continue
|
||||
}
|
||||
pc, err := strconv.ParseUint(string(ln[:colon]), 16, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
pcs = append(pcs, pc)
|
||||
if len(pcs) == 100 {
|
||||
pcchan <- pcs
|
||||
pcs = nil
|
||||
if pc := parseLine(callInsns, traceFuncs, s.Bytes()); pc != 0 {
|
||||
npcs++
|
||||
pcs = append(pcs, pc)
|
||||
if len(pcs) == 100 {
|
||||
pcchan <- pcs
|
||||
pcs = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(pcs) != 0 {
|
||||
pcchan <- pcs
|
||||
}
|
||||
close(pcchan)
|
||||
stderrOut, _ := ioutil.ReadAll(stderr)
|
||||
if err := cmd.Wait(); err != nil {
|
||||
return nil, fmt.Errorf("failed to run objdump on %v: %v\n%s", obj, err, stderrOut)
|
||||
}
|
||||
if err := s.Err(); err != nil {
|
||||
return nil, fmt.Errorf("failed to run objdump output: %v", err)
|
||||
return nil, fmt.Errorf("failed to run objdump on %v: %v\n%s", obj, err, stderrOut)
|
||||
}
|
||||
if npcs == 0 {
|
||||
return nil, fmt.Errorf("%v doesn't contain coverage callbacks '%s%s' (set CONFIG_KCOV=y)",
|
||||
obj, callInsns, traceFuncs)
|
||||
}
|
||||
if err := <-errc; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(frames) == 0 {
|
||||
return nil, fmt.Errorf("%v doesn't have debug info (set CONFIG_DEBUG_INFO=y)", obj)
|
||||
}
|
||||
return frames, nil
|
||||
}
|
||||
|
||||
func parseLine(callInsns, traceFuncs [][]byte, ln []byte) uint64 {
|
||||
pos := -1
|
||||
for _, callInsn := range callInsns {
|
||||
if pos = bytes.Index(ln, callInsn); pos != -1 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if pos == -1 {
|
||||
return 0
|
||||
}
|
||||
hasCall := false
|
||||
for _, traceFunc := range traceFuncs {
|
||||
if hasCall = bytes.Contains(ln[pos:], traceFunc); hasCall {
|
||||
break
|
||||
}
|
||||
}
|
||||
if !hasCall {
|
||||
return 0
|
||||
}
|
||||
for len(ln) != 0 && ln[0] == ' ' {
|
||||
ln = ln[1:]
|
||||
}
|
||||
colon := bytes.IndexByte(ln, ':')
|
||||
if colon == -1 {
|
||||
return 0
|
||||
}
|
||||
pc, err := strconv.ParseUint(string(ln[:colon]), 16, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return pc
|
||||
}
|
||||
|
||||
func parseFile(fn string) ([][]byte, error) {
|
||||
data, err := ioutil.ReadFile(fn)
|
||||
if err != nil {
|
||||
@ -429,8 +473,8 @@ func parseFile(fn string) ([][]byte, error) {
|
||||
return lines, nil
|
||||
}
|
||||
|
||||
func PreviousInstructionPC(arch string, pc uint64) uint64 {
|
||||
switch arch {
|
||||
func PreviousInstructionPC(target *targets.Target, pc uint64) uint64 {
|
||||
switch target.Arch {
|
||||
case "amd64":
|
||||
return pc - 5
|
||||
case "386":
|
||||
@ -446,33 +490,40 @@ func PreviousInstructionPC(arch string, pc uint64) uint64 {
|
||||
case "mips64le":
|
||||
return pc - 8
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown arch %q", arch))
|
||||
panic(fmt.Sprintf("unknown arch %q", target.Arch))
|
||||
}
|
||||
}
|
||||
|
||||
func archCallInsn(arch string) (string, string) {
|
||||
const callName = " <__sanitizer_cov_trace_pc>"
|
||||
switch arch {
|
||||
func archCallInsn(target *targets.Target) ([][]byte, [][]byte) {
|
||||
callName := [][]byte{[]byte(" <__sanitizer_cov_trace_pc>")}
|
||||
switch target.Arch {
|
||||
case "amd64":
|
||||
// ffffffff8100206a: callq ffffffff815cc1d0 <__sanitizer_cov_trace_pc>
|
||||
return "\tcallq ", callName
|
||||
return [][]byte{[]byte("\tcallq ")}, callName
|
||||
case "386":
|
||||
// c1000102: call c10001f0 <__sanitizer_cov_trace_pc>
|
||||
return "\tcall ", callName
|
||||
return [][]byte{[]byte("\tcall ")}, callName
|
||||
case "arm64":
|
||||
// ffff0000080d9cc0: bl ffff00000820f478 <__sanitizer_cov_trace_pc>
|
||||
return "\tbl\t", callName
|
||||
return [][]byte{[]byte("\tbl\t")}, callName
|
||||
case "arm":
|
||||
// 8010252c: bl 801c3280 <__sanitizer_cov_trace_pc>
|
||||
return "\tbl\t", callName
|
||||
return [][]byte{[]byte("\tbl\t")}, callName
|
||||
case "ppc64le":
|
||||
// c00000000006d904: bl c000000000350780 <.__sanitizer_cov_trace_pc>
|
||||
return "\tbl ", " <.__sanitizer_cov_trace_pc>"
|
||||
// This is only known to occur in the test:
|
||||
// 838: bl 824 <__sanitizer_cov_trace_pc+0x8>
|
||||
return [][]byte{[]byte("\tbl ")}, [][]byte{
|
||||
[]byte("<__sanitizer_cov_trace_pc+0x8>"),
|
||||
[]byte(" <.__sanitizer_cov_trace_pc>"),
|
||||
}
|
||||
case "mips64le":
|
||||
// ffffffff80100420: jal ffffffff80205880 <__sanitizer_cov_trace_pc>
|
||||
return "\tjal\t", callName
|
||||
// This is only known to occur in the test:
|
||||
// b58: bal b30 <__sanitizer_cov_trace_pc>
|
||||
return [][]byte{[]byte("\tjal\t"), []byte("\tbal\t")}, callName
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown arch %q", arch))
|
||||
panic(fmt.Sprintf("unknown arch %q", target.Arch))
|
||||
}
|
||||
}
|
||||
|
||||
|
152
pkg/cover/report_test.go
Normal file
152
pkg/cover/report_test.go
Normal file
@ -0,0 +1,152 @@
|
||||
// Copyright 2020 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.
|
||||
|
||||
// It may or may not work on other OSes.
|
||||
// If you test on another OS and it works, enable it.
|
||||
// +build linux
|
||||
|
||||
package cover
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/syzkaller/pkg/osutil"
|
||||
"github.com/google/syzkaller/pkg/symbolizer"
|
||||
_ "github.com/google/syzkaller/sys"
|
||||
"github.com/google/syzkaller/sys/targets"
|
||||
)
|
||||
|
||||
type Test struct {
|
||||
Name string
|
||||
CFlags []string
|
||||
Progs []Prog
|
||||
Result string
|
||||
}
|
||||
|
||||
func TestReportGenerator(t *testing.T) {
|
||||
tests := []Test{
|
||||
{
|
||||
Name: "no-coverage",
|
||||
CFlags: []string{"-g"},
|
||||
Result: `.* doesn't contain coverage callbacks '.*__sanitizer_cov_trace_pc>\]' \(set CONFIG_KCOV=y\)`,
|
||||
},
|
||||
{
|
||||
Name: "no-debug-info",
|
||||
CFlags: []string{"-fsanitize-coverage=trace-pc"},
|
||||
Result: `.* doesn't have debug info \(set CONFIG_DEBUG_INFO=y\)`,
|
||||
},
|
||||
{
|
||||
Name: "no-pcs",
|
||||
CFlags: []string{"-fsanitize-coverage=trace-pc", "-g"},
|
||||
Result: `no coverage collected so far`,
|
||||
},
|
||||
{
|
||||
Name: "bad-pcs",
|
||||
CFlags: []string{"-fsanitize-coverage=trace-pc", "-g"},
|
||||
Progs: []Prog{{Data: "data", PCs: []uint64{0x1, 0x2}}},
|
||||
Result: `coverage \(2\) doesn't match coverage callbacks`,
|
||||
},
|
||||
{
|
||||
Name: "good",
|
||||
CFlags: []string{"-fsanitize-coverage=trace-pc", "-g"},
|
||||
},
|
||||
}
|
||||
t.Parallel()
|
||||
for os, arches := range targets.List {
|
||||
if os == "test" {
|
||||
continue
|
||||
}
|
||||
for _, target := range arches {
|
||||
target := targets.Get(target.OS, target.Arch)
|
||||
if target.BuildOS != runtime.GOOS {
|
||||
continue
|
||||
}
|
||||
t.Run(target.OS+"-"+target.Arch, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
if target.BrokenCompiler != "" {
|
||||
t.Skip("skipping the test due to broken cross-compiler:\n" + target.BrokenCompiler)
|
||||
}
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run("no-coverage", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
testReportGenerator(t, target, test)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testReportGenerator(t *testing.T, target *targets.Target, test Test) {
|
||||
rep, err := generateReport(t, target, test)
|
||||
if err != nil {
|
||||
if test.Result == "" {
|
||||
t.Fatalf("expected no error, but got:\n%v", err)
|
||||
}
|
||||
if !regexp.MustCompile(test.Result).MatchString(err.Error()) {
|
||||
t.Fatalf("expected error %q, but got:\n%v", test.Result, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if test.Result != "" {
|
||||
t.Fatalf("got no error, but expected %q", test.Result)
|
||||
}
|
||||
_ = rep
|
||||
}
|
||||
|
||||
func generateReport(t *testing.T, target *targets.Target, test Test) ([]byte, error) {
|
||||
src, err := osutil.TempFile("syz-cover-test-src")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.Remove(src)
|
||||
if err := osutil.WriteFile(src, []byte(`
|
||||
void __sanitizer_cov_trace_pc() {}
|
||||
int main() {}
|
||||
`)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
bin, err := osutil.TempFile("syz-cover-test-bin")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.Remove(bin)
|
||||
flags := append(append([]string{
|
||||
"-o", bin,
|
||||
"-x", "c", src,
|
||||
}, target.CFlags...), test.CFlags...)
|
||||
if _, err := osutil.RunCmd(time.Hour, "", target.CCompiler, flags...); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rg, err := MakeReportGenerator(target, bin, filepath.Dir(src), filepath.Dir(src))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if test.Result == "" {
|
||||
text, err := symbolizer.ReadTextSymbols(bin)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if nmain := len(text["main"]); nmain != 1 {
|
||||
t.Fatalf("got %v main symbols", nmain)
|
||||
}
|
||||
main := text["main"][0]
|
||||
var pcs []uint64
|
||||
for off := 0; off < main.Size; off++ {
|
||||
pcs = append(pcs, main.Addr+uint64(off))
|
||||
}
|
||||
test.Progs = append(test.Progs, Prog{Data: "main", PCs: pcs})
|
||||
}
|
||||
out := new(bytes.Buffer)
|
||||
if err := rg.Do(out, test.Progs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out.Bytes(), nil
|
||||
}
|
@ -67,6 +67,8 @@ type osCommon struct {
|
||||
CPP string
|
||||
// Common CFLAGS for this OS.
|
||||
cflags []string
|
||||
// If set, this OS uses $SOURCEDIR to locate the toolchain.
|
||||
NeedsSourceDir bool
|
||||
}
|
||||
|
||||
func Get(OS, arch string) *Target {
|
||||
@ -356,6 +358,7 @@ var oses = map[string]osCommon{
|
||||
ExecutorUsesShmem: true,
|
||||
ExecutorUsesForkServer: true,
|
||||
KernelObject: "netbsd.gdb",
|
||||
NeedsSourceDir: true,
|
||||
},
|
||||
"openbsd": {
|
||||
SyscallNumbers: true,
|
||||
@ -373,6 +376,7 @@ var oses = map[string]osCommon{
|
||||
HostFuzzer: true,
|
||||
SyzExecutorCmd: "syz-executor",
|
||||
KernelObject: "zircon.elf",
|
||||
NeedsSourceDir: true,
|
||||
},
|
||||
"windows": {
|
||||
SyscallNumbers: false,
|
||||
@ -389,6 +393,7 @@ var oses = map[string]osCommon{
|
||||
ExecutorUsesForkServer: true,
|
||||
HostFuzzer: true,
|
||||
KernelObject: "akaros-kernel-64b",
|
||||
NeedsSourceDir: true,
|
||||
},
|
||||
"trusty": {
|
||||
SyscallNumbers: true,
|
||||
@ -501,6 +506,9 @@ func (target *Target) lazyInit() {
|
||||
// On CI we want to fail loudly if cross-compilation breaks.
|
||||
if _, err := exec.LookPath(target.CCompiler); err != nil {
|
||||
target.BrokenCompiler = fmt.Sprintf("%v is missing", target.CCompiler)
|
||||
if target.NeedsSourceDir && os.Getenv("SOURCEDIR") == "" {
|
||||
target.BrokenCompiler = "SOURCEDIR is not set"
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
|
||||
"github.com/google/syzkaller/pkg/cover"
|
||||
"github.com/google/syzkaller/pkg/osutil"
|
||||
"github.com/google/syzkaller/sys/targets"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -24,27 +25,27 @@ var (
|
||||
reportGenerator *cover.ReportGenerator
|
||||
)
|
||||
|
||||
func initCover(kernelObj, kernelObjName, kernelSrc, kernelBuildSrc, arch, OS string) error {
|
||||
func initCover(target *targets.Target, kernelObj, kernelSrc, kernelBuildSrc string) error {
|
||||
initCoverOnce.Do(func() {
|
||||
if kernelObj == "" {
|
||||
initCoverError = fmt.Errorf("kernel_obj is not specified")
|
||||
return
|
||||
}
|
||||
vmlinux := filepath.Join(kernelObj, kernelObjName)
|
||||
reportGenerator, initCoverError = cover.MakeReportGenerator(vmlinux, kernelSrc, kernelBuildSrc, arch)
|
||||
vmlinux := filepath.Join(kernelObj, target.KernelObject)
|
||||
reportGenerator, initCoverError = cover.MakeReportGenerator(target, vmlinux, kernelSrc, kernelBuildSrc)
|
||||
if initCoverError != nil {
|
||||
return
|
||||
}
|
||||
initCoverVMOffset, initCoverError = getVMOffset(vmlinux, OS)
|
||||
initCoverVMOffset, initCoverError = getVMOffset(vmlinux, target.OS)
|
||||
})
|
||||
return initCoverError
|
||||
}
|
||||
|
||||
func coverToPCs(cov []uint32, arch string) []uint64 {
|
||||
func coverToPCs(target *targets.Target, cov []uint32) []uint64 {
|
||||
pcs := make([]uint64, 0, len(cov))
|
||||
for _, pc := range cov {
|
||||
fullPC := cover.RestorePC(pc, initCoverVMOffset)
|
||||
prevPC := cover.PreviousInstructionPC(arch, fullPC)
|
||||
prevPC := cover.PreviousInstructionPC(target, fullPC)
|
||||
pcs = append(pcs, prevPC)
|
||||
}
|
||||
return pcs
|
||||
|
@ -218,8 +218,7 @@ func (mgr *Manager) httpCover(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
// Note: initCover is executed without mgr.mu because it takes very long time
|
||||
// (but it only reads config and it protected by initCoverOnce).
|
||||
if err := initCover(mgr.cfg.KernelObj, mgr.sysTarget.KernelObject,
|
||||
mgr.cfg.KernelSrc, mgr.cfg.KernelBuildSrc, mgr.cfg.TargetVMArch, mgr.cfg.TargetOS); err != nil {
|
||||
if err := initCover(mgr.sysTarget, mgr.cfg.KernelObj, mgr.cfg.KernelSrc, mgr.cfg.KernelBuildSrc); err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to generate coverage profile: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@ -234,7 +233,7 @@ func (mgr *Manager) httpCoverCover(w http.ResponseWriter, r *http.Request) {
|
||||
inp := mgr.corpus[sig]
|
||||
progs = append(progs, cover.Prog{
|
||||
Data: string(inp.Prog),
|
||||
PCs: coverToPCs(inp.Cover, mgr.cfg.TargetVMArch),
|
||||
PCs: coverToPCs(mgr.sysTarget, inp.Cover),
|
||||
})
|
||||
} else {
|
||||
call := r.FormValue("call")
|
||||
@ -244,7 +243,7 @@ func (mgr *Manager) httpCoverCover(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
progs = append(progs, cover.Prog{
|
||||
Data: string(inp.Prog),
|
||||
PCs: coverToPCs(inp.Cover, mgr.cfg.TargetVMArch),
|
||||
PCs: coverToPCs(mgr.sysTarget, inp.Cover),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -391,8 +390,7 @@ func (mgr *Manager) httpReport(w http.ResponseWriter, r *http.Request) {
|
||||
func (mgr *Manager) httpRawCover(w http.ResponseWriter, r *http.Request) {
|
||||
// Note: initCover is executed without mgr.mu because it takes very long time
|
||||
// (but it only reads config and it protected by initCoverOnce).
|
||||
if err := initCover(mgr.cfg.KernelObj, mgr.sysTarget.KernelObject, mgr.cfg.KernelSrc,
|
||||
mgr.cfg.KernelBuildSrc, mgr.cfg.TargetArch, mgr.cfg.TargetOS); err != nil {
|
||||
if err := initCover(mgr.sysTarget, mgr.cfg.KernelObj, mgr.cfg.KernelSrc, mgr.cfg.KernelBuildSrc); err != nil {
|
||||
http.Error(w, initCoverError.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@ -407,7 +405,7 @@ func (mgr *Manager) httpRawCover(w http.ResponseWriter, r *http.Request) {
|
||||
for pc := range cov {
|
||||
covArray = append(covArray, pc)
|
||||
}
|
||||
pcs := coverToPCs(covArray, mgr.cfg.TargetVMArch)
|
||||
pcs := coverToPCs(mgr.sysTarget, covArray)
|
||||
sort.Slice(pcs, func(i, j int) bool {
|
||||
return pcs[i] < pcs[j]
|
||||
})
|
||||
|
@ -125,9 +125,9 @@ func main() {
|
||||
if err != nil {
|
||||
log.Fatalf("%v", err)
|
||||
}
|
||||
sysTarget := targets.Get(cfg.TargetOS, cfg.TargetArch)
|
||||
sysTarget := targets.Get(cfg.TargetOS, cfg.TargetVMArch)
|
||||
if sysTarget == nil {
|
||||
log.Fatalf("unsupported OS/arch: %v/%v", cfg.TargetOS, cfg.TargetArch)
|
||||
log.Fatalf("unsupported OS/arch: %v/%v", cfg.TargetOS, cfg.TargetVMArch)
|
||||
}
|
||||
syscalls, err := mgrconfig.ParseEnabledSyscalls(target, cfg.EnabledSyscalls, cfg.DisabledSyscalls)
|
||||
if err != nil {
|
||||
|
@ -66,7 +66,7 @@ func main() {
|
||||
failf("%v", err)
|
||||
}
|
||||
kernelObj := filepath.Join(*flagKernelObj, target.KernelObject)
|
||||
rg, err := cover.MakeReportGenerator(kernelObj, *flagKernelSrc, *flagKernelBuildSrc, *flagArch)
|
||||
rg, err := cover.MakeReportGenerator(target, kernelObj, *flagKernelSrc, *flagKernelBuildSrc)
|
||||
if err != nil {
|
||||
failf("%v", err)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user