aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/csource/csource.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-12-08 19:03:09 +0100
committerDmitry Vyukov <dvyukov@google.com>2018-12-08 19:08:08 +0100
commitc7918378631992d874c99736272ed342d5d77b2c (patch)
tree5e67097471fda876d532c270dc4b7f3db0e850c5 /pkg/csource/csource.go
parent33508266251f6db13ef34741e36b1dce2c9e1b49 (diff)
executor: fix handling of big-endian bitfields
Currently we apply big-endian-ness and bitfield-ness in the wrong order in copyin. This leads to totally bogus result. Fix this.
Diffstat (limited to 'pkg/csource/csource.go')
-rw-r--r--pkg/csource/csource.go16
1 files changed, 10 insertions, 6 deletions
diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go
index 49431f655..aa5f615e1 100644
--- a/pkg/csource/csource.go
+++ b/pkg/csource/csource.go
@@ -229,7 +229,7 @@ func (ctx *context) emitCall(w *bytes.Buffer, call prog.ExecCall, ci int, haveCo
if arg.Format != prog.FormatNative && arg.Format != prog.FormatBigEndian {
panic("sring format in syscall argument")
}
- fmt.Fprintf(w, "%v", ctx.constArgToStr(arg))
+ fmt.Fprintf(w, "%v", ctx.constArgToStr(arg, true))
case prog.ExecArgResult:
if arg.Format != prog.FormatNative && arg.Format != prog.FormatBigEndian {
panic("sring format in syscall argument")
@@ -282,13 +282,17 @@ 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)
+ ctx.copyinVal(w, copyin.Addr, arg.Size, ctx.constArgToStr(arg, true), 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, 0x%x, %v, %v, %v));\n",
- arg.Size*8, copyin.Addr, ctx.constArgToStr(arg),
+ htobe := ""
+ if arg.Format == prog.FormatBigEndian {
+ htobe = fmt.Sprintf("htobe%v", arg.Size*8)
+ }
+ fmt.Fprintf(w, "\tNONFAILING(STORE_BY_BITMASK(uint%v, %v, 0x%x, %v, %v, %v));\n",
+ arg.Size*8, htobe, copyin.Addr, ctx.constArgToStr(arg, false),
arg.BitfieldOffset, arg.BitfieldLength)
}
case prog.ExecArgResult:
@@ -363,7 +367,7 @@ func (ctx *context) copyout(w *bytes.Buffer, call prog.ExecCall, resCopyout bool
}
}
-func (ctx *context) constArgToStr(arg prog.ExecArgConst) string {
+func (ctx *context) constArgToStr(arg prog.ExecArgConst, handleBigEndian bool) string {
mask := (uint64(1) << (arg.Size * 8)) - 1
v := arg.Value & mask
val := fmt.Sprintf("%v", v)
@@ -375,7 +379,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.Format == prog.FormatBigEndian {
+ if handleBigEndian && arg.Format == prog.FormatBigEndian {
val = fmt.Sprintf("htobe%v(%v)", arg.Size*8, val)
}
return val