diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-08-30 14:17:47 -0700 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-08-30 21:45:03 -0700 |
| commit | e8dd2c6713522707b3b89884eb95601cdf9bc9be (patch) | |
| tree | 9df12a938af90c06794ec9f60920d59330766ed1 /prog/prog.go | |
| parent | 6ba5fe3e62880ddf8aeec68ab44eabaa8bc148b8 (diff) | |
prog: add concept of "special pointers"
Currently we only generate either valid user-space pointers or NULL.
Extend NULL to a set of special pointers that we will use in programs.
All targets now contain 3 special values:
- NULL
- 0xfffffffffffffff (invalid kernel pointer)
- 0x999999999999999 (non-canonical address)
Each target can add additional special pointers on top of this.
Also generate NULL/special pointers for non-opt ptr's.
This restriction was always too restrictive. We may want to generate
them with very low probability, but we do want to generate them.
Also change pointers to NULL/special during mutation
(but still not in the opposite direction).
Diffstat (limited to 'prog/prog.go')
| -rw-r--r-- | prog/prog.go | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/prog/prog.go b/prog/prog.go index 8d0e0f525..b7304ba5d 100644 --- a/prog/prog.go +++ b/prog/prog.go @@ -106,9 +106,13 @@ func MakeVmaPointerArg(t Type, addr, size uint64) *PointerArg { } } -func MakeNullPointerArg(t Type) *PointerArg { +func MakeSpecialPointerArg(t Type, index uint64) *PointerArg { + if index >= maxSpecialPointers { + panic("bad special pointer index") + } return &PointerArg{ ArgCommon: ArgCommon{typ: t}, + Address: -index, } } @@ -116,8 +120,15 @@ func (arg *PointerArg) Size() uint64 { return arg.typ.Size() } -func (arg *PointerArg) IsNull() bool { - return arg.Address == 0 && arg.VmaSize == 0 && arg.Res == nil +func (arg *PointerArg) IsSpecial() bool { + return arg.VmaSize == 0 && arg.Res == nil && -arg.Address < maxSpecialPointers +} + +func (target *Target) PhysicalAddr(arg *PointerArg) uint64 { + if arg.IsSpecial() { + return target.SpecialPointers[-arg.Address] + } + return target.DataOffset + arg.Address } // Used for BufferType. @@ -262,17 +273,12 @@ func (arg *ResultArg) Size() uint64 { // Returns inner arg for pointer args. func InnerArg(arg Arg) Arg { - if t, ok := arg.Type().(*PtrType); ok { - if a, ok := arg.(*PointerArg); ok { - if a.Res == nil { - if !t.Optional() { - panic(fmt.Sprintf("non-optional pointer is nil\narg: %+v\ntype: %+v", a, t)) - } - return nil - } - return InnerArg(a.Res) + if _, ok := arg.Type().(*PtrType); ok { + res := arg.(*PointerArg).Res + if res == nil { + return nil } - return nil // *ConstArg. + return InnerArg(res) } return arg // Not a pointer. } |
