Library ProofOS.AbsInt.StackTypes

Adding simple stack support to a type system

Require Import Arith List TheoryList ZArith.

Require Import Asm.Util.Specif.
Require Import Asm.Util.Tactics.
Require Import Asm.Util.ListUtil.
Require Import Asm.Util.ArithUtil.
Require Import Asm.Util.Monad.
Require Import Asm.Util.Mod.
Require Import Asm.Util.Maps.

Require Import Asm.Bitvector.Bitvector.
Require Import Asm.X86.X86.

Require Import ProofOS.Trusted.Safety.
Require Import ProofOS.Trusted.Machine.
Require Import ProofOS.Trusted.Arches.

Require Import ProofOS.AbsInt.Bounded.
Require Import ProofOS.AbsInt.Sal.
Require Import ProofOS.AbsInt.FixedCode.
Require Import ProofOS.AbsInt.TypeSystem.

Set Implicit Arguments.

Maps used in abstract state


Module NatIndexed <: INDEXED_TYPE.
  Definition t := nat.

  Definition index := P_of_succ_nat.

  Theorem index_inj: forall (x y: t), index x = index y -> x = y.

  Definition eq := eq_nat_dec.

  Definition invert n := pred (nat_of_P n).

  Theorem invert_index : forall x, invert (index x) = x.
End NatIndexed.

Module NatMap := IMap(NatIndexed).

Definition disjointRegions (start1 : int32) len1 (start2 : int32) len2 :=
  bvec_to_nat start1 + len1 + 4 <= bvec_to_nat start2
  \/ bvec_to_nat start1 >= bvec_to_nat start2 + len2 + 4.

Module Type M86_PARAM_FIXED_CODE_AND_STACK.
  Parameter minitState : state -> Prop.

  Parameter minitMem : mem.
  Parameter codeStart : int32.
  Parameter codeLength : nat.
  Axiom codeHigh : bvec_to_nat codeStart >= 4.
  Axiom codeFits : bvec_to_nat codeStart + codeLength < pow2 32 - 3.

  Axiom pcInRange : forall st, minitState st
    -> bvec_to_nat codeStart
    <= bvec_to_nat (stPc st)
    < bvec_to_nat codeStart + codeLength - longestInstr.
  Axiom codeUniform : forall st, minitState st
    -> agree_range (stMem st) minitMem codeStart codeLength.

  Parameter stackStart : int32.
  Parameter stackLength : nat.
  Axiom stackHigh : bvec_to_nat stackStart >= 4.
  Axiom stackFits : bvec_to_nat stackStart + stackLength < pow2 32 - 3.
  Axiom stackCodeSeparate : disjointRegions codeStart codeLength stackStart stackLength.
End M86_PARAM_FIXED_CODE_AND_STACK.

Metadata types


Section metadata.
   Variable ty : Set.

  Record function_info : Set := {
    fiPc : int32;
First program counter
    fiRet : ty;
Return type
    fiArgs : list ty
How many arguments?
  }.
End metadata.

Section stackTy.
   Variables ty mastate : Set.
  
  Inductive stackTy : Set :=
    | Top
    | Const : int32 -> stackTy
    | Stack : nat -> stackTy
    | OldEbp : stackTy
    | RetPtr : stackTy
    | Cust : ty -> stackTy.

  Parameter print_stackTy : (ty -> unit) -> stackTy -> unit.
  
  Record stackState : Set := {
    aIsRet : bool;
    aStackSize : nat;
    aStackSlots : NatMap.t stackTy;
    aCustom : mastate
  }.
  
  Parameter print_stackState : (ty -> unit) -> (mastate -> unit)
    -> nat -> stackTy -> ((nat * stackTy -> unit) -> unit) -> mastate -> unit.
End stackTy.

Module Make (Param : M86_PARAM_FIXED_CODE_AND_STACK).
  Module TySys := TypeSystem.Make(Param).
  Import TySys.
  Import Param.
  Import Fixed.
  Import MySal.

  Definition stackEnd := nat_to_bvec 32 (bvec_to_nat stackStart + stackLength).

  Definition inStack (a : int32) :=
    bvec_to_nat stackStart <= bvec_to_nat a <= bvec_to_nat stackStart + stackLength.

  Definition apartFromStack (a : int32) :=
    bvec_to_nat a <= bvec_to_nat stackStart - 4
    \/ bvec_to_nat a >= bvec_to_nat stackStart + stackLength + 4.

The language of types used in basic block preconditions for outputs of

this functor
   Section stackTy2.
     Variables ty mastate mcontext : Set.
     Variable hasTy : mcontext -> int32 -> ty -> Prop.
     Variable mconc : mcontext -> M.mstate -> mastate -> Prop.

    Record stackContext : Set := {
      ctxSptr : int32;
      ctxMemIn : mem;
      ctxOldEbp : int32;
      ctxRetPtr : option int32;
      ctxCust : mcontext
    }.

    Definition stack_slot (ctx : stackContext) n :=
      nat_to_bvec 32 (bvec_to_nat (ctxSptr ctx) - n).

    Inductive stackHasTy : stackContext -> int32 -> stackTy ty -> Prop :=
      | HT_Top : forall ctx v, stackHasTy ctx v (Top _)
      | HT_Const : forall ctx v, stackHasTy ctx v (Const _ v)
      | HT_Stack : forall ctx n,
        n <= bvec_to_nat (ctxSptr ctx)
        -> stackHasTy ctx (stack_slot ctx n) (Stack _ n)
      | HT_OldEbp : forall ctx, stackHasTy ctx (ctxOldEbp ctx) (OldEbp _)
      | HT_RetPtr : forall ctx r, ctxRetPtr ctx = Some r
        -> stackHasTy ctx r (RetPtr _)
      | HT_Cust : forall ctx v t, hasTy (ctxCust ctx) v t
        -> stackHasTy ctx v (Cust t).

    Definition conc_slots ctx st (abs : stackState ty mastate) :=
      forall n, 4 <= n < aStackSize abs
        -> stackHasTy ctx (get_mem32 st (stack_slot ctx n)) (NatMap.get n (aStackSlots abs)).

    Definition agree_range' (mem1 mem2 : mem) (addr1 addr2 : int32) :=
      forall addr', bvec_to_nat addr1 <= bvec_to_nat addr' < bvec_to_nat addr2
        -> Int32Map.get addr' mem1 = Int32Map.get addr' mem2.

    Record stackConc (ctx : stackContext) (st : M.mstate) (abs : stackState ty mastate) : Prop := {
      mcPc : aIsRet abs = true -> ctxRetPtr ctx = Some (SstPc st);
      mcSptr : bvec_to_nat (ctxSptr ctx) <= bvec_to_nat stackStart + stackLength - 4;
      mcStackSize : bvec_to_nat stackStart + aStackSize abs < bvec_to_nat (ctxSptr ctx);
      mcStackSlots : conc_slots ctx st abs;
      mcMemIn : agree_range' (SstMem st) (ctxMemIn ctx) (ctxSptr ctx) stackEnd;
      mcCust : mconc (ctxCust ctx) st (aCustom abs)
    }.

    Lemma ntb_cong : forall len n1 n2,
      n1 = n2
      -> nat_to_bvec len n1 = nat_to_bvec len n2.

    Definition stackSlotOf : forall (abs : stateDescription (stackTy ty) (stackState ty mastate)) (e : salExp),
      sig_option (fun ss => forall ctx st,
        typeMconc stackHasTy stackConc ctx st abs
        -> evalExp st e = stack_slot ctx ss).

   End stackTy2.

  Module Type STACK_READY_TYPE_SYSTEM.
    Parameter ty : Set.
    Parameter print_ty : ty -> unit.
A language of types describing machine words

    Parameter mastate : Set.
    Parameter print_mastate : mastate -> unit.
Custom abstract state information

    Parameter mcontext : Set.
A summary of aspects of a machine state that don't need to be represented explicitly at verification time, but are important in soundness proofs

    Parameter mconc : mcontext -> M.mstate -> mastate -> Prop.
Concretization relation

    Parameter subMastate : forall (abs1 abs2 : mastate),
      pred_option (forall ctx st,
        mconc ctx st abs1 -> mconc ctx st abs2).
A way to check compatibility of abstract states
    
    Parameter hasTy : mcontext -> int32 -> ty -> Prop.
What it means for a word to be of a type

    Parameter tyTop : ty.
    Axiom tyTopSound : forall ctx v, hasTy ctx v tyTop.

    Parameter tyConst : int32 -> ty.
    Axiom tyConstSound1 : forall ctx v, hasTy ctx v (tyConst v).
    Axiom tyConstSound2 : forall ctx v1 v2, hasTy ctx v1 (tyConst v2) -> v1 = v2.
    Parameter isTyConst : forall (t : ty), sig_option (fun n => t = tyConst n).

    Parameter subTy : forall (t1 t2 : ty),
      pred_option (forall ctx v,
        hasTy ctx v t1 -> hasTy ctx v t2).
A way to check compatibility of types

    Parameter typeof : forall (abs : mastate) (rs : SalRegMap.t ty) (e : salExp),
      {t : ty
        | forall ctx st,
          mconc ctx st abs
          -> (forall r, hasTy ctx (get_reg st r) (SalRegMap.get r rs))
          -> hasTy ctx (evalExp st e) t}.
A type inference procedure for SAL expressions

    Parameter typeofLoad : forall (abs : mastate) (rs : SalRegMap.t ty) (e : salExp),
      {t : ty
        | forall ctx st,
          mconc ctx st abs
          -> (forall r, hasTy ctx (get_reg st r) (SalRegMap.get r rs))
          -> hasTy ctx (get_mem32 st (evalExp st e)) t}.
Type inference for memory loads

    Parameter checkStore : forall (abs : mastate) (rs : SalRegMap.t ty) (e : salExp),
      pred_option (forall ctx st,
        mconc ctx st abs
        -> (forall r, hasTy ctx (get_reg st r) (SalRegMap.get r rs))
        -> apartFromCode (evalExp st e)
        /\ not_too_high (evalExp st e)
        /\ apartFromStack (evalExp st e)).
Type inference for memory loads

    Parameter effectOfCmd : forall (abs : mastate) (rs : SalRegMap.t ty) (cmd : salCmd),
      sig_option (fun abs' => forall ctx st,
        mconc ctx st abs
        -> (forall r, hasTy ctx (get_reg st r) (SalRegMap.get r rs))
        -> mconc ctx (salExecCmd st cmd) abs').
Update the custom state to reflect the result of a command.

    Parameter doStackWrite : forall (abs : mastate),
      sig_option (fun abs' => forall ctx st dst src,
        mconc ctx st abs
        -> inStack dst
        -> mconc ctx (set_mem32 st dst src) abs').
The custom type system should be unaffected by stack writes.

    Parameter effectOfJump : forall (abs : mastate) (rs : SalRegMap.t ty)
      (jmp : salJump) (nextPc : int32),
      sig_option (fun abs' => forall ctx st,
        mconc ctx st abs
        -> (forall r, hasTy ctx (get_reg st r) (SalRegMap.get r rs))
        -> match salExecJmp jmp nextPc st with
             | None => False
             | Some st' => mconc ctx st' abs'
           end).
Update the custom state to reflect the result of a jump.

    Parameter effectOfConditionalJump : forall (abs : stateDescription (stackTy ty)
      (stackState ty mastate))
      (co : cc) (pc nextPc : int32) (b : bool),
      sig_option (fun abs' => forall ctx st,
        typeMconc (stackHasTy hasTy) (stackConc hasTy mconc) ctx st abs
        -> check_cc st co = b
        -> match salExecJmp (SConditionalJump co pc) nextPc st with
             | None => False
             | Some st' => typeMconc (stackHasTy hasTy) (stackConc hasTy mconc) ctx st' abs'
           end).
Specialized version of effectOfJump that allows different states in different cases of a conditional jump test

    Parameter viewShiftOfJump : forall (hyps : list (stateDescription ty mastate))
      (abs : stateDescription ty mastate)
      (jmp : salJump) (nextPc : int32),
      sig_option (fun vs => forall ctx st,
        typeMconc hasTy mconc ctx st abs
        -> exists ctx', typeMconc hasTy mconc ctx' st (vsAbs vs)
          /\ AllS (fun need => exists have, (In have (vsSuccs vs) \/ In have hyps)
            /\ subsumes (typeMconc hasTy mconc) ctx' need ctx have) (vsHyps vs)).
Massage the form of an abstract state to match what a jump target expects; for instance, at a function call.
   End STACK_READY_TYPE_SYSTEM.

  Module Type TYPE_SYSTEM_WITH_FUNCTIONS.
    Declare Module Sys : STACK_READY_TYPE_SYSTEM.

    Parameter functions : list (function_info (stackTy Sys.ty)).
Information on function types
   End TYPE_SYSTEM_WITH_FUNCTIONS.

Add stack support to a type system

  Module AddStackTypes (SysPlus : TYPE_SYSTEM_WITH_FUNCTIONS) : TYPE_SYSTEM
    with Definition ty := stackTy SysPlus.Sys.ty
      with Definition mastate := stackState SysPlus.Sys.ty SysPlus.Sys.mastate
        with Definition mcontext := stackContext SysPlus.Sys.mcontext
          with Definition hasTy := stackHasTy SysPlus.Sys.hasTy
            with Definition mconc := stackConc SysPlus.Sys.hasTy SysPlus.Sys.mconc.
    Module Mac := M.

    Import SysPlus.
    Import Sys.

    Definition ty := stackTy ty.
    Definition print_ty := print_stackTy print_ty.
    Definition mastate := stackState Sys.ty mastate.
    Definition print_mastate ss :=
      let (default, elems) := NatMap.elements (aStackSlots ss) in
        print_stackState Sys.print_ty print_mastate
        (aStackSize ss) default (fun f => iter f elems) (aCustom ss).

    Definition mcontext := stackContext mcontext.

    Definition hasTy := stackHasTy hasTy.
     Hint Unfold hasTy.
     Hint Constructors stackHasTy.

    Definition mconc := stackConc Sys.hasTy mconc.
     Hint Unfold mconc.
     Hint Constructors stackConc.

     Hint Resolve tyConstSound1 tyConstSound2.

    Lemma HT_Const' : forall ctx v1 v2,
      v1 = v2
      -> hasTy ctx v1 (Const _ v2).

     Hint Resolve HT_Const'.

    Definition subTy : forall (t1 t2 : ty),
      pred_option (forall ctx v,
        hasTy ctx v t1 -> hasTy ctx v t2).

    Definition bool_eq_dec : forall (x y : bool), {x = y} + {x <> y}.

    Definition subMastate : forall (abs1 abs2 : mastate),
      pred_option (forall ctx st,
        mconc ctx st abs1 -> mconc ctx st abs2).

    Lemma mconc_sptr_not_too_high : forall ctx st abs,
      mconc ctx st abs
      -> not_too_high (ctxSptr ctx).

     Hint Resolve mconc_sptr_not_too_high.

    Lemma not_too_high_minus : forall n1 n2,
      not_too_high n1
      -> bvec_to_nat n1 - n2 < pow2 32.

     Hint Resolve not_too_high_minus.

    Lemma stack_slot_rewrite : forall ctx st abs n1 n2,
      mconc ctx st abs
      -> n1 <= bvec_to_nat (ctxSptr ctx)
      -> bvec_to_nat n2 <= n1
      -> badd32 (stack_slot ctx n1) n2
      = stack_slot ctx (n1 - bvec_to_nat n2).

    Lemma stack_slot_rewrite2 : forall ctx st abs n1 n2,
      mconc ctx st abs
      -> n1 <= bvec_to_nat (ctxSptr ctx)
      -> n1 + bvec_to_nat n2 <= aStackSize abs
      -> bsub32 (stack_slot ctx n1) n2
      = stack_slot ctx (n1 + bvec_to_nat n2).

    Lemma stack_slot_rewrite3 : forall (ctx : mcontext) st (abs : mastate) n1 n2,
      mconc ctx st abs
      -> n1 < bvec_to_nat n2
      -> n1 + bvec_to_nat (bneg n2) <= aStackSize abs
      -> n1 <= bvec_to_nat (ctxSptr ctx)
      -> badd32 n2 (stack_slot ctx n1)
      = stack_slot ctx (n1 + bvec_to_nat (bneg n2)).

    Definition lowerTy t :=
      match t with
        | Const n => tyConst n
        | Cust t' => t'
        | _ => tyTop
      end.

     Hint Resolve tyTopSound.

    Lemma lowerTy_sound : forall st r ctx t,
      hasTy ctx (get_reg st r) t
      -> Sys.hasTy (ctxCust ctx) (get_reg st r) (lowerTy t).

     Hint Resolve lowerTy_sound.

    Definition typeofR (abs : mastate) (rs : SalRegMap.t ty) (e : salExp) :=
      {t : ty
        | forall ctx st,
          mconc ctx st abs
          -> (forall r, hasTy ctx (get_reg st r) (SalRegMap.get r rs))
          -> hasTy ctx (evalExp st e) t}.

    Definition raiseTy : forall (t : Sys.ty), {t' : ty |
      forall ctx v, Sys.hasTy (ctxCust ctx) v t -> hasTy ctx v t'}.

    Lemma lowerTy_map_sound : forall ctx st rs,
      (forall r : SalRegIndexed.t,
        hasTy ctx (get_reg st r) (SalRegMap.get r rs))
      -> (forall r : SalRegIndexed.t,
        Sys.hasTy (ctxCust ctx) (get_reg st r)
        (SalRegMap.get r (SalRegMap.map lowerTy rs))).

     Hint Resolve lowerTy_map_sound.

    Definition typeof : forall (abs : mastate) (rs : SalRegMap.t ty) (e : salExp),
      typeofR abs rs e.

    Definition typeofLoadR (abs : mastate) (rs : SalRegMap.t ty) (e : salExp) :=
      {t : ty
        | forall ctx st,
          mconc ctx st abs
          -> (forall r, hasTy ctx (get_reg st r) (SalRegMap.get r rs))
          -> hasTy ctx (get_mem32 st (evalExp st e)) t}.

    Definition typeofLoad : forall (abs : mastate) (rs : SalRegMap.t ty) (e : salExp),
      typeofLoadR abs rs e.

    Lemma apartFromCode_slot : forall (ctx : mcontext) (abs : mastate) n,
      bvec_to_nat (ctxSptr ctx) <= bvec_to_nat stackStart + stackLength - 4
      -> bvec_to_nat stackStart + aStackSize abs < bvec_to_nat (ctxSptr ctx)
      -> n <= bvec_to_nat (ctxSptr ctx)
      -> n < aStackSize abs
      -> apartFromCode (stack_slot ctx n).

     Hint Resolve apartFromCode_slot.

    Lemma not_too_high_slot : forall n (ctx : mcontext),
      bvec_to_nat (ctxSptr ctx) <= bvec_to_nat stackStart + stackLength - 4
      -> n <= bvec_to_nat (ctxSptr ctx)
      -> not_too_high (stack_slot ctx n).

     Hint Resolve not_too_high_slot.

    Definition checkStoreR (abs : mastate) (rs : SalRegMap.t ty) (e : salExp) :=
      pred_option (forall ctx st,
        mconc ctx st abs
        -> (forall r, hasTy ctx (get_reg st r) (SalRegMap.get r rs))
        -> apartFromCode (evalExp st e)
        /\ not_too_high (evalExp st e)).

    Definition checkStore : forall (abs : mastate) (rs : SalRegMap.t ty) (e : salExp),
      checkStoreR abs rs e.

    Definition set_stack32 (m : NatMap.t ty) n t :=
      NatMap.set (n-3) (Top _)
        (NatMap.set (n-2) (Top _)
          (NatMap.set (n-1) (Top _)
            (NatMap.set (n+1) (Top _)
              (NatMap.set (n+2) (Top _)
                (NatMap.set (n+3) (Top _)
                  (NatMap.set n t m)))))).

     Hint Rewrite NatMap.gss : Maps.
     Hint Rewrite NatMap.gso using (trivial; fail) : Maps.

    Lemma set_stack32_sound : forall (ctx : mcontext) st (abs : mastate) src tSrc n (cust : Sys.mastate),
      bvec_to_nat stackStart + aStackSize abs < bvec_to_nat (ctxSptr ctx)
      -> bvec_to_nat (ctxSptr ctx) <= bvec_to_nat stackStart + stackLength - 4
      -> conc_slots Sys.hasTy ctx st abs
      -> hasTy ctx src tSrc
      -> n < aStackSize abs
      -> conc_slots Sys.hasTy ctx (set_mem32 st (stack_slot ctx n) src)
      (Build_stackState (aIsRet abs) (aStackSize abs)
        (set_stack32 (aStackSlots abs) n tSrc) cust).

     Hint Resolve set_stack32_sound.

    Lemma agree_range'_write : forall m1 m2 a1 a2 a v,
      agree_range' m1 m2 a1 a2
      -> bvec_to_nat a + 4 <= bvec_to_nat a1
      -> not_too_high a
      -> agree_range' (set_mem32' m1 a v) m2 a1 a2.

     Hint Resolve agree_range'_write.

     Ltac use_gmap :=
      match goal with
        | [ |- context[SalRegMap.get _ (SalRegMap.map _ _)] ] =>
          rewrite SalRegMap.gmap
      end.
     Hint Extern 1 (Sys.hasTy _ _ _) => use_gmap.

    Lemma apartFromStack_heap_write : forall dst ctx st (abs : mastate) src (cust : Sys.mastate),
      apartFromStack dst
      -> not_too_high dst
      -> bvec_to_nat (ctxSptr ctx) <= bvec_to_nat stackStart + stackLength - 4
      -> bvec_to_nat stackStart + aStackSize abs < bvec_to_nat (ctxSptr ctx)
      -> conc_slots Sys.hasTy ctx st abs
      -> conc_slots Sys.hasTy ctx (set_mem32 st dst src)
      (Build_stackState (aIsRet abs) (aStackSize abs) (aStackSlots abs) cust).

    Lemma apartFromStack_agree_range' : forall dst m1 m2 src sptr ssize,
      not_too_high dst
      -> apartFromStack dst
      -> bvec_to_nat sptr <= bvec_to_nat stackStart + stackLength - 4
      -> bvec_to_nat stackStart + ssize < bvec_to_nat sptr
      -> agree_range' m1 m2 sptr stackEnd
      -> agree_range' (set_mem32' m1 dst src) m2 sptr stackEnd.

    Definition effectOfCmdR (abs : mastate) (rs : SalRegMap.t ty) (cmd : salCmd) :=
      sig_option (fun abs' => forall ctx st,
        mconc ctx st abs
        -> (forall r, hasTy ctx (get_reg st r) (SalRegMap.get r rs))
        -> mconc ctx (salExecCmd st cmd) abs').

    Definition effectOfCmd : forall (abs : mastate) (rs : SalRegMap.t ty) (cmd : salCmd),
      effectOfCmdR abs rs cmd.

    Definition effectOfJumpR (abs : mastate) (rs : SalRegMap.t ty)
      (jmp : salJump) (nextPc : int32) :=
      sig_option (fun abs' => forall ctx st,
        mconc ctx st abs
        -> (forall r, hasTy ctx (get_reg st r) (SalRegMap.get r rs))
        -> match salExecJmp jmp nextPc st with
             | None => False
             | Some st' => mconc ctx st' abs'
           end).

    Definition effectOfJump : forall (abs : mastate) (rs : SalRegMap.t ty)
      (jmp : salJump) (nextPc : int32),
      effectOfJumpR abs rs jmp nextPc.

    Definition effectOfConditionalJump : forall (abs : stateDescription ty mastate)
      (co : cc) (pc nextPc : int32) (b : bool),
      sig_option (fun abs' => forall ctx st,
        typeMconc hasTy mconc ctx st abs
        -> check_cc st co = b
        -> match salExecJmp (SConditionalJump co pc) nextPc st with
             | None => False
             | Some st' => typeMconc hasTy mconc ctx st' abs'
           end).

    Definition tyTop : ty := Top _.
    Theorem tyTopSound : forall ctx v, hasTy ctx v tyTop.

    Definition tyConst (n : int32) : ty := Const _ n.
     Hint Unfold tyConst.
    Theorem tyConstSound1 : forall ctx v, hasTy ctx v (tyConst v).
    Theorem tyConstSound2 : forall ctx v1 v2, hasTy ctx v1 (tyConst v2) -> v1 = v2.
    Definition isTyConst : forall (t : ty), sig_option (fun n => t = tyConst n).

    Lemma agree_range'_refl : forall m a1 a2,
      agree_range' m m a1 a2.

     Hint Resolve agree_range'_refl.

    Definition shiftContext (args : list ty) (ctx : mcontext) (st : salState) ss oldebp retptr :=
      Build_stackContext
      (stack_slot ctx (ss - 4 - 4 * length args))
      (SstMem st)
      oldebp
      retptr
      (ctxCust ctx).

    Fixpoint argsStack (args : list ty) : NatMap.t ty :=
      match args with
        | nil => NatMap.init (Top _)
        | cons t rest => NatMap.set (4 * length args) t (argsStack rest)
      end.

    Lemma undo_rewrite_fourx : forall n,
      n + (n + (n + (n + 0))) = 4 * n.

    Import Datatypes.

    Lemma undo_rewrite_fourx_plus : forall n,
      S (n + (S (n + S (n + (S (n + 0)))))) = 4 * (S n).

     Hint Rewrite undo_rewrite_fourx undo_rewrite_fourx_plus : fixup.
     Ltac mysimpl := simpl; autorewrite with fixup.

     Ltac clear_one :=
      match goal with
        [ H : _ |- _ ] => clear H
      end.
     Ltac clear_all := repeat clear_one.

    Definition robustType : forall (t : ty),
      pred_option (forall ctx v, hasTy ctx v t
        -> forall args st ss oldebp retptr, hasTy (shiftContext args ctx st ss oldebp retptr) v t).

    Lemma checkArgs_add : forall n1 n2 n3 n4 n5,
      n1 <= n2
      -> n3 + n2 <= n4
      -> n2 <= n4 - n3
      -> n5 - (n4 - n3 - n1) = n5 - (n4 - n3 - n2) - (n2 - n1).

    Definition checkArgsR (args args' : list ty) (slots : NatMap.t ty) ssize ss :=
      sig_option (fun slots' => forall ctx st,
        bvec_to_nat (ctxSptr ctx) <= bvec_to_nat stackStart + stackLength
        -> (forall n, 4 <= n < ssize
          -> hasTy ctx (get_mem32 st (stack_slot ctx n)) (NatMap.get n slots))
        -> forall oldebp retptr,
          forall n, 4 <= n < ssize - (ss - 4 - 4 * length args)
            -> hasTy (shiftContext args ctx st ss oldebp retptr) (get_mem32 st
              (stack_slot (shiftContext args ctx st ss oldebp retptr) n)) (NatMap.get n slots')).

    Definition checkArgs' : forall (args args' : list ty) (Hargs : length args' <= length args)
      (slots : NatMap.t ty) ssize ss,
      4 <= ss - 4 * length args' /\ ss < ssize /\ 4 + 4 * length args <= ss
      -> checkArgsR args args' slots ssize ss.

    Definition checkArgs : forall (args : list ty) (slots : NatMap.t ty) ssize ss,
      4 <= ss - 4 * length args /\ ss < ssize /\ 4 + 4 * length args <= ss
      -> checkArgsR args args slots ssize ss.

    Lemma shiftAbs_lt' : forall n1 n2 ss,
      n1 < n2
      -> ss < n1
      -> ss < n2
      -> n1 - ss < n2 - ss.

    Lemma shiftAbs_lt'' : forall n1 n2 n3,
      n3 < n2
      -> n1 + n2 - n3 = n1 + (n2 - n3).

    Lemma shiftAbs_lt : forall start size sptr ss n1 n2,
      start + size < sptr
      -> ss < size
      -> start +
      (size - (ss - n1 - n2)) <
      sptr - (ss - n1 - n2).

    Lemma rewrite_plus_four : forall n,
      S (S (S (S n))) = 4 + n.

    Lemma HT_Stack' : forall ctx n v,
      n <= bvec_to_nat (ctxSptr ctx)
      -> v = stack_slot ctx n
      -> hasTy ctx v (Stack _ n).

    Lemma Some_get_mem32_cong : forall st e e',
      e = e'
      -> Some (get_mem32 st e) = Some (get_mem32 st e').

    Lemma viewShift_eq : forall ss size sptr n1 n2,
      ss <= size
      -> n1 + n2 <= ss
      -> sptr - (ss - n1 - n2) - (n1 + n2) = sptr - ss.

    Definition shiftAbs : forall (fi : function_info ty) ss (abs : mastate),
      sig_option (fun abs' => forall ctx st oldebp,
        mconc ctx st abs
        -> mconc (shiftContext (fiArgs fi) ctx st ss oldebp
          (Some (get_mem32 st (stack_slot ctx ss)))) st abs').

We build up a fast look-up structure to find function information

from program counters.
    Definition pcToFi_map' (fis : list (function_info ty)) m :=
      fold_left (fun m fi => Int32Map.set (fiPc fi) (Some fi) m) fis m.

    Definition pcToFi_map := pcToFi_map' functions (Int32Map.init None).
    Definition pcToFi pc := Int32Map.get pc pcToFi_map.

    Lemma viewShift_boring : forall abs hyps,
      forall (ctx : stackContext Sys.mcontext) (st : salState),
        typeMconc hasTy mconc ctx st abs ->
        exists ctx' : stackContext Sys.mcontext,
          typeMconc hasTy mconc ctx' st abs /\
          AllS
          (fun
            need : stateDescription (stackTy Sys.ty)
            (stackState Sys.ty Sys.mastate) =>
            exists
              have : stateDescription (stackTy Sys.ty)
              (stackState Sys.ty Sys.mastate),
              (False \/ In have hyps) /\
              subsumes (typeMconc hasTy mconc) ctx' need ctx have) hyps.

     Hint Resolve viewShift_boring.

    Fixpoint preserveSlots (sl : nat) (slots : NatMap.t ty) {struct sl} : NatMap.t ty :=
      match sl with
        | O => NatMap.init (Top _)
        | S sl' => NatMap.set sl' (NatMap.get sl' slots) (preserveSlots sl' slots)
      end.

    Definition reverseRobustType : forall (t : ty),
      pred_option (forall ctx v args st ss oldebp retptr, hasTy (shiftContext args ctx st ss oldebp retptr) v t
          -> hasTy ctx v t).

    Lemma viewShift_ret_eq : forall n1 n2 n3 n4,
      n2 <= n1
      -> n3 + n4 <= n2
      -> n1 - (n2 - n3 - n4) - n4 = n1 - (n2 - n3).

    Lemma agree_range'_slot : forall m1 m2 bound finish a,
      belowMax finish 3
      -> agree_range' m1 m2 bound finish
      -> bvec_to_nat bound <= bvec_to_nat a < bvec_to_nat finish - 3
      -> get_mem32' m2 a = get_mem32' m1 a.

    Lemma minus_lt : forall n m o,
      n < m - 0
      -> n - o < m.

    Lemma minus_lt2 : forall n m o p,
      n - m <= o < p
      -> n - S m <= o < p.

    Lemma agree_range'_S : forall m1 m2 (ctx : mcontext) bound finish,
      belowMax (ctxSptr ctx) 0
      -> agree_range' m1 m2 (stack_slot ctx (S bound)) finish
      -> agree_range' m1 m2 (stack_slot ctx bound) finish.

    Lemma belowMax_stackEnd : forall (n : int32),
      bvec_to_nat n < bvec_to_nat stackEnd - 3
      -> belowMax n 0.

     Hint Resolve belowMax_stackEnd.

    Lemma bound_sptr : forall sptr bound,
      sptr < bvec_to_nat stackEnd - 3
      -> sptr - bound < pow2 32.

     Hint Resolve bound_sptr.

    
    Lemma agree_range'_weaken : forall m1 m2 s1 s2 e,
      agree_range' m1 m2 s1 e
      -> bvec_to_nat s1 <= bvec_to_nat s2
      -> agree_range' m1 m2 s2 e.

    Lemma viewShift_concSlots : forall ctx ssize st st' bound slots,
      bvec_to_nat (ctxSptr ctx) < bvec_to_nat stackEnd - 3
      -> agree_range' (SstMem st') (SstMem st) (stack_slot ctx (bound - 1)) stackEnd
      -> (forall n,
        4 <= n < ssize ->
        stackHasTy Sys.hasTy ctx (get_mem32 st (stack_slot ctx n))
        (NatMap.get n slots))
      -> forall n,
        4 <= n < ssize ->
        stackHasTy Sys.hasTy ctx (get_mem32 st' (stack_slot ctx n))
        (NatMap.get n
          (preserveSlots bound slots)).

    Lemma agree_range'_trans : forall m1 m2 m3 s e,
      agree_range' m1 m2 s e
      -> agree_range' m2 m3 s e
      -> agree_range' m1 m3 s e.

    Definition viewShift_ret : forall (fi : function_info ty)
      (abs : stateDescription ty mastate) ss rp,
      ss <= aStackSize (sdCust abs)
      -> 4 + 4 * length (fiArgs fi) <= ss
      -> sig_option (fun retAbss => forall ctx st,
        typeMconc hasTy mconc ctx st abs
        -> subsumes (typeMconc hasTy mconc)
        (shiftContext (fiArgs fi) ctx st ss (get_reg st (SX86 EBP))
          (Some rp)) (fst retAbss)
        ctx (snd retAbss)).

    Definition viewShiftOfJump : forall (hyps : list (stateDescription ty mastate))
      (abs : stateDescription ty mastate)
      (jmp : salJump) (nextPc : int32),
      sig_option (fun vs => forall ctx st,
        typeMconc hasTy mconc ctx st abs
        -> exists ctx', typeMconc hasTy mconc ctx' st (vsAbs vs)
          /\ AllS (fun need => exists have, (In have (vsSuccs vs) \/ In have hyps)
            /\ subsumes (typeMconc hasTy mconc) ctx' need ctx have) (vsHyps vs)).
   End AddStackTypes.

End Make.

Index
This page has been generated by coqdoc