diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-07-07 20:07:30 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-07-08 22:52:24 +0200 |
| commit | 306ca0571c5d906ce76df97bd1ea54f4e0e50240 (patch) | |
| tree | a579718e096c53dc5386f4af2fbabb3318eaf1ed /pkg/csource | |
| parent | 93213ec0d3c4522c8844a51b718eb56ce62f395b (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.go | 94 | ||||
| -rw-r--r-- | pkg/csource/linux_common.go | 10 |
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> |
