aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2016-05-03 11:43:36 +0200
committerDmitry Vyukov <dvyukov@google.com>2016-05-03 11:43:36 +0200
commit54b31a67e6a9f49fc2cda38a79c5adfe68fe9d21 (patch)
tree65969ad936d46be11da1399b70fcddb01ca6ff8d
parent8813b44c4bb24ec9eb8c3f4d3847d90a8986aba9 (diff)
parented787856f258f495445c2267b9cf40d7d4ce320d (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.go4
-rw-r--r--syz-manager/cover.go39
-rw-r--r--tools/syz-execprog/execprog.go2
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 {