aboutsummaryrefslogtreecommitdiffstats
path: root/prog/encodingexec.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2015-12-11 15:42:14 +0100
committerDmitry Vyukov <dvyukov@google.com>2015-12-17 14:38:46 +0100
commit9980a72713f95bdef6bbd649fd0525bfe1da64d5 (patch)
tree2f28c2926f72cf4bb1926a58e20a42c44d6a7f36 /prog/encodingexec.go
parent48d0a3662ef7971ad56214c73623a30cee996415 (diff)
sys: automatically add padding to structs
Diffstat (limited to 'prog/encodingexec.go')
-rw-r--r--prog/encodingexec.go32
1 files changed, 26 insertions, 6 deletions
diff --git a/prog/encodingexec.go b/prog/encodingexec.go
index 90b8ef7ea..f23d98c5d 100644
--- a/prog/encodingexec.go
+++ b/prog/encodingexec.go
@@ -10,6 +10,8 @@ const (
instrEOF = ^uintptr(iota)
instrCopyin
instrCopyout
+ instrSetPad
+ instrCheckPad
)
const (
@@ -53,13 +55,22 @@ func (p *Prog) SerializeForExec() []byte {
}
return
}
- if arg1.Dir == DirOut || arg1.Kind == ArgData && len(arg1.Data) == 0 {
+ if arg1.Kind == ArgData && len(arg1.Data) == 0 {
return
}
- w.write(instrCopyin)
- w.write(physicalAddr(arg) + w.args[arg1].Offset)
- w.writeArg(arg1)
- instrSeq++
+ pad, padSize := arg1.IsPad()
+ if (arg1.Dir == DirIn && !pad) || (arg1.Dir == DirOut && pad) || arg1.Dir == DirInOut {
+ if pad {
+ w.write(instrSetPad)
+ w.write(physicalAddr(arg) + w.args[arg1].Offset)
+ w.write(padSize)
+ } else {
+ w.write(instrCopyin)
+ w.write(physicalAddr(arg) + w.args[arg1].Offset)
+ w.writeArg(arg1)
+ }
+ instrSeq++
+ }
}
rec(arg.Res)
}
@@ -74,7 +85,16 @@ func (p *Prog) SerializeForExec() []byte {
instrSeq++
// Generate copyout instructions that persist interesting return values.
foreachArg(c, func(arg, base *Arg, _ *[]*Arg) {
- if len(arg.Uses) == 0 {
+ pad, padSize := arg.IsPad()
+ if pad && arg.Dir != DirIn {
+ instrSeq++
+ info := w.args[arg]
+ w.write(instrCheckPad)
+ w.write(physicalAddr(base) + info.Offset)
+ w.write(padSize)
+ return
+ }
+ if pad || len(arg.Uses) == 0 {
return
}
switch arg.Kind {