aboutsummaryrefslogtreecommitdiffstats
path: root/prog/prog.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-08-30 14:17:47 -0700
committerDmitry Vyukov <dvyukov@google.com>2018-08-30 21:45:03 -0700
commite8dd2c6713522707b3b89884eb95601cdf9bc9be (patch)
tree9df12a938af90c06794ec9f60920d59330766ed1 /prog/prog.go
parent6ba5fe3e62880ddf8aeec68ab44eabaa8bc148b8 (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.go32
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.
}