aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/csource
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-07-07 20:07:30 +0200
committerDmitry Vyukov <dvyukov@google.com>2018-07-08 22:52:24 +0200
commit306ca0571c5d906ce76df97bd1ea54f4e0e50240 (patch)
treea579718e096c53dc5386f4af2fbabb3318eaf1ed /pkg/csource
parent93213ec0d3c4522c8844a51b718eb56ce62f395b (diff)
prog, pkg/compiler: support fmt type
fmt type allows to convert intergers and resources to string representation.
Diffstat (limited to 'pkg/csource')
-rw-r--r--pkg/csource/csource.go94
-rw-r--r--pkg/csource/linux_common.go10
2 files changed, 67 insertions, 37 deletions
diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go
index 992e5ac4f..e7aa2d7f2 100644
--- a/pkg/csource/csource.go
+++ b/pkg/csource/csource.go
@@ -288,33 +288,7 @@ func (ctx *context) generateCalls(p prog.ExecProg) ([]string, []uint64) {
w := new(bytes.Buffer)
// Copyin.
for _, copyin := range call.Copyin {
- switch arg := copyin.Arg.(type) {
- case prog.ExecArgConst:
- if arg.BitfieldOffset == 0 && arg.BitfieldLength == 0 {
- fmt.Fprintf(w, "\tNONFAILING(*(uint%v_t*)0x%x = %v);\n",
- arg.Size*8, copyin.Addr, ctx.constArgToStr(arg))
- } else {
- fmt.Fprintf(w, "\tNONFAILING(STORE_BY_BITMASK(uint%v_t, 0x%x, %v, %v, %v));\n",
- arg.Size*8, copyin.Addr, ctx.constArgToStr(arg),
- arg.BitfieldOffset, arg.BitfieldLength)
- }
- case prog.ExecArgResult:
- fmt.Fprintf(w, "\tNONFAILING(*(uint%v_t*)0x%x = %v);\n",
- arg.Size*8, copyin.Addr, ctx.resultArgToStr(arg))
- case prog.ExecArgData:
- fmt.Fprintf(w, "\tNONFAILING(memcpy((void*)0x%x, \"%s\", %v));\n",
- copyin.Addr, toCString(arg.Data), len(arg.Data))
- case prog.ExecArgCsum:
- switch arg.Kind {
- case prog.ExecArgCsumInet:
- csumSeq++
- ctx.generateCsumInet(w, copyin.Addr, arg, csumSeq)
- default:
- panic(fmt.Sprintf("unknown csum kind %v", arg.Kind))
- }
- default:
- panic(fmt.Sprintf("bad argument type: %+v", arg))
- }
+ ctx.copyin(w, &csumSeq, copyin)
}
// Call itself.
@@ -353,8 +327,14 @@ func (ctx *context) generateCalls(p prog.ExecProg) ([]string, []uint64) {
}
switch arg := arg.(type) {
case prog.ExecArgConst:
+ if arg.Format != prog.FormatNative && arg.Format != prog.FormatBigEndian {
+ panic("sring format in syscall argument")
+ }
fmt.Fprintf(w, "%v", ctx.constArgToStr(arg))
case prog.ExecArgResult:
+ if arg.Format != prog.FormatNative && arg.Format != prog.FormatBigEndian {
+ panic("sring format in syscall argument")
+ }
fmt.Fprintf(w, "%v", ctx.resultArgToStr(arg))
default:
panic(fmt.Sprintf("unknown arg type: %+v", arg))
@@ -419,6 +399,61 @@ func (ctx *context) generateCsumInet(w *bytes.Buffer, addr uint64, arg prog.Exec
addr, csumSeq)
}
+func (ctx *context) copyin(w *bytes.Buffer, csumSeq *int, copyin prog.ExecCopyin) {
+ switch arg := copyin.Arg.(type) {
+ case prog.ExecArgConst:
+ if arg.BitfieldOffset == 0 && arg.BitfieldLength == 0 {
+ ctx.copyinVal(w, copyin.Addr, arg.Size, ctx.constArgToStr(arg), arg.Format)
+ } else {
+ if arg.Format != prog.FormatNative && arg.Format != prog.FormatBigEndian {
+ panic("bitfield+string format")
+ }
+ fmt.Fprintf(w, "\tNONFAILING(STORE_BY_BITMASK(uint%v_t, 0x%x, %v, %v, %v));\n",
+ arg.Size*8, copyin.Addr, ctx.constArgToStr(arg),
+ arg.BitfieldOffset, arg.BitfieldLength)
+ }
+ case prog.ExecArgResult:
+ ctx.copyinVal(w, copyin.Addr, arg.Size, ctx.resultArgToStr(arg), arg.Format)
+ case prog.ExecArgData:
+ fmt.Fprintf(w, "\tNONFAILING(memcpy((void*)0x%x, \"%s\", %v));\n",
+ copyin.Addr, toCString(arg.Data), len(arg.Data))
+ case prog.ExecArgCsum:
+ switch arg.Kind {
+ case prog.ExecArgCsumInet:
+ *csumSeq++
+ ctx.generateCsumInet(w, copyin.Addr, arg, *csumSeq)
+ default:
+ panic(fmt.Sprintf("unknown csum kind %v", arg.Kind))
+ }
+ default:
+ panic(fmt.Sprintf("bad argument type: %+v", arg))
+ }
+}
+
+func (ctx *context) copyinVal(w *bytes.Buffer, addr, size uint64, val string, bf prog.BinaryFormat) {
+ switch bf {
+ case prog.FormatNative, prog.FormatBigEndian:
+ fmt.Fprintf(w, "\tNONFAILING(*(uint%v_t*)0x%x = %v);\n", size*8, addr, val)
+ case prog.FormatStrDec:
+ if size != 20 {
+ panic("bad strdec size")
+ }
+ fmt.Fprintf(w, "\tNONFAILING(sprintf((char*)0x%x, \"%%020llu\", (long long)%v));\n", addr, val)
+ case prog.FormatStrHex:
+ if size != 18 {
+ panic("bad strdec size")
+ }
+ fmt.Fprintf(w, "\tNONFAILING(sprintf((char*)0x%x, \"0x%%016llx\", (long long)%v));\n", addr, val)
+ case prog.FormatStrOct:
+ if size != 23 {
+ panic("bad strdec size")
+ }
+ fmt.Fprintf(w, "\tNONFAILING(sprintf((char*)0x%x, \"%%023llo\", (long long)%v));\n", addr, val)
+ default:
+ panic("unknown binary format")
+ }
+}
+
func (ctx *context) constArgToStr(arg prog.ExecArgConst) string {
mask := (uint64(1) << (arg.Size * 8)) - 1
v := arg.Value & mask
@@ -431,7 +466,7 @@ func (ctx *context) constArgToStr(arg prog.ExecArgConst) string {
if ctx.opts.Procs > 1 && arg.PidStride != 0 {
val += fmt.Sprintf(" + procid*%v", arg.PidStride)
}
- if arg.BigEndian {
+ if arg.Format == prog.FormatBigEndian {
val = fmt.Sprintf("htobe%v(%v)", arg.Size*8, val)
}
return val
@@ -445,6 +480,9 @@ func (ctx *context) resultArgToStr(arg prog.ExecArgResult) string {
if arg.AddOp != 0 {
res = fmt.Sprintf("%v+%v", res, arg.AddOp)
}
+ if arg.Format == prog.FormatBigEndian {
+ res = fmt.Sprintf("htobe%v(%v)", arg.Size*8, res)
+ }
return res
}
diff --git a/pkg/csource/linux_common.go b/pkg/csource/linux_common.go
index c1313c018..b2431c4fe 100644
--- a/pkg/csource/linux_common.go
+++ b/pkg/csource/linux_common.go
@@ -10,6 +10,7 @@ var commonHeaderLinux = `
#endif
#include <endian.h>
+#include <stdio.h>
#include <sys/syscall.h>
#include <unistd.h>
#if defined(SYZ_EXECUTOR) || defined(SYZ_THREADED) || defined(SYZ_COLLIDE)
@@ -21,7 +22,6 @@ var commonHeaderLinux = `
#include <errno.h>
#include <signal.h>
#include <stdarg.h>
-#include <stdio.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <time.h>
@@ -39,7 +39,6 @@ var commonHeaderLinux = `
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
-#include <stdio.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include <sys/time.h>
@@ -72,7 +71,6 @@ var commonHeaderLinux = `
#include <net/if_arp.h>
#include <stdarg.h>
#include <stdbool.h>
-#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
@@ -88,24 +86,20 @@ var commonHeaderLinux = `
#include <fcntl.h>
#include <stdarg.h>
#include <stdbool.h>
-#include <stdio.h>
#include <sys/stat.h>
#endif
#if defined(SYZ_EXECUTOR) || defined(__NR_syz_open_dev) || defined(__NR_syz_open_procfs)
#include <fcntl.h>
-#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#endif
#if defined(SYZ_EXECUTOR) || defined(__NR_syz_fuse_mount) || defined(__NR_syz_fuseblk_mount)
#include <fcntl.h>
-#include <stdio.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#endif
#if defined(SYZ_EXECUTOR) || defined(__NR_syz_open_pts)
#include <fcntl.h>
-#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#endif
@@ -115,7 +109,6 @@ var commonHeaderLinux = `
#include <linux/kvm.h>
#include <stdarg.h>
#include <stddef.h>
-#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#endif
@@ -140,7 +133,6 @@ var commonHeaderLinux = `
#include <errno.h>
#include <fcntl.h>
#include <linux/loop.h>
-#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/stat.h>