diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2019-05-16 18:05:05 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2019-05-16 18:05:05 +0200 |
| commit | 76fc461b55cfe334e8d4be121f61fa25d079f8ba (patch) | |
| tree | 88cc3472e7352c2cd74f3234acb4bd2083ff61d4 /prog/size.go | |
| parent | f59a9cb554a8dfcbe13c8a0775542ee7a0d8a353 (diff) | |
pkg/compiler: add offsetof type
Similar to C offsetof gives offset of a field
from the beginning of the parent struct.
We have several TODOs in descriptions asking for this.
Diffstat (limited to 'prog/size.go')
| -rw-r--r-- | prog/size.go | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/prog/size.go b/prog/size.go index 23248c722..a134f0d10 100644 --- a/prog/size.go +++ b/prog/size.go @@ -42,8 +42,12 @@ func (target *Target) assignSizes(args []Arg, parentsMap map[Arg]Arg, syscallArg func (target *Target) assignSize(dst *ConstArg, pos Arg, path []string, args []Arg, parentsMap map[Arg]Arg) { elem := path[0] path = path[1:] + var offset uint64 for _, buf := range args { if elem != buf.Type().FieldName() { + if !buf.Type().BitfieldMiddle() { + offset += buf.Size() + } continue } buf = InnerArg(buf) @@ -52,7 +56,7 @@ func (target *Target) assignSize(dst *ConstArg, pos Arg, path []string, args []A return } if len(path) == 0 { - dst.Val = target.computeSize(buf, dst.Type().(*LenType)) + dst.Val = target.computeSize(buf, offset, dst.Type().(*LenType)) } else { target.assignSize(dst, buf, path, buf.(*GroupArg).Inner, parentsMap) } @@ -61,7 +65,7 @@ func (target *Target) assignSize(dst *ConstArg, pos Arg, path []string, args []A if elem == ParentRef { buf := parentsMap[pos] if len(path) == 0 { - dst.Val = target.computeSize(buf, dst.Type().(*LenType)) + dst.Val = target.computeSize(buf, noOffset, dst.Type().(*LenType)) } else { target.assignSize(dst, buf, path, buf.(*GroupArg).Inner, parentsMap) } @@ -77,7 +81,7 @@ func (target *Target) assignSize(dst *ConstArg, pos Arg, path []string, args []A continue } if len(path) == 0 { - dst.Val = target.computeSize(buf, dst.Type().(*LenType)) + dst.Val = target.computeSize(buf, noOffset, dst.Type().(*LenType)) } else { target.assignSize(dst, buf, path, buf.(*GroupArg).Inner, parentsMap) } @@ -91,10 +95,14 @@ func (target *Target) assignSize(dst *ConstArg, pos Arg, path []string, args []A dst.Type().FieldName(), elem, pos.Type().Name(), pos.Type().FieldName(), argNames)) } -func (target *Target) computeSize(arg Arg, lenType *LenType) uint64 { - if arg == nil { - // Arg is an optional pointer, set size to 0. - return 0 +const noOffset = ^uint64(0) + +func (target *Target) computeSize(arg Arg, offset uint64, lenType *LenType) uint64 { + if lenType.Offset { + if offset == noOffset { + panic("offset of a non-field") + } + return offset * 8 / lenType.BitSize } bitSize := lenType.BitSize if bitSize == 0 { |
