diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2016-05-03 11:43:36 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2016-05-03 11:43:36 +0200 |
| commit | 54b31a67e6a9f49fc2cda38a79c5adfe68fe9d21 (patch) | |
| tree | 65969ad936d46be11da1399b70fcddb01ca6ff8d | |
| parent | 8813b44c4bb24ec9eb8c3f4d3847d90a8986aba9 (diff) | |
| parent | ed787856f258f495445c2267b9cf40d7d4ce320d (diff) | |
Merge pull request #39 from ramosian-glider/restore_pc_2
Use readelf to obtain the upper 32 bits of addresses returned by kcov.
| -rw-r--r-- | cover/cover.go | 4 | ||||
| -rw-r--r-- | syz-manager/cover.go | 39 | ||||
| -rw-r--r-- | tools/syz-execprog/execprog.go | 2 |
3 files changed, 41 insertions, 4 deletions
diff --git a/cover/cover.go b/cover/cover.go index 4c07314af..df2c76a79 100644 --- a/cover/cover.go +++ b/cover/cover.go @@ -20,8 +20,8 @@ func Copy(cov Cover) Cover { return append(Cover{}, cov...) } -func RestorePC(pc uint32) uint64 { - return uint64(0xffffffff)<<32 + uint64(pc) +func RestorePC(pc uint32, base uint32) uint64 { + return uint64(base)<<32 + uint64(pc) } /* Canonicalize sorts and removes duplicates. */ diff --git a/syz-manager/cover.go b/syz-manager/cover.go index c55f75264..7badc31f2 100644 --- a/syz-manager/cover.go +++ b/syz-manager/cover.go @@ -112,7 +112,44 @@ func parseFile(fn string) ([][]byte, error) { return lines, nil } +func getVmOffset(vmlinux string) (uint32, error) { + out, err := exec.Command("readelf", "-SW", vmlinux).CombinedOutput() + if err != nil { + return 0, fmt.Errorf("readelf failed: %v\n%s", err, out) + } + 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 +} + func symbolize(vmlinux string, cov []uint32) ([]LineInfo, string, error) { + base, err := getVmOffset(vmlinux) + if err != nil { + return nil, "", err + } cmd := exec.Command("addr2line", "-a", "-i", "-e", vmlinux) stdin, err := cmd.StdinPipe() if err != nil { @@ -130,7 +167,7 @@ func symbolize(vmlinux string, cov []uint32) ([]LineInfo, string, error) { defer cmd.Wait() go func() { for _, pc := range cov { - fmt.Fprintf(stdin, "0x%x\n", cover.RestorePC(pc)-1) + fmt.Fprintf(stdin, "0x%x\n", cover.RestorePC(pc, base)-1) } stdin.Close() }() diff --git a/tools/syz-execprog/execprog.go b/tools/syz-execprog/execprog.go index e9246766b..fdba0f258 100644 --- a/tools/syz-execprog/execprog.go +++ b/tools/syz-execprog/execprog.go @@ -110,7 +110,7 @@ func main() { buf := new(bytes.Buffer) binary.Write(buf, binary.LittleEndian, uint64(0xC0BFFFFFFFFFFF64)) for _, pc := range c { - binary.Write(buf, binary.LittleEndian, cover.RestorePC(pc)) + binary.Write(buf, binary.LittleEndian, cover.RestorePC(pc, 0xffffffff)) } err := ioutil.WriteFile(fmt.Sprintf("%v.%v", *flagCoverFile, i), buf.Bytes(), 0660) if err != nil { |
