(** * Correspondence between global environments *)
(** Global environments match if the memory injection [f] leaves unchanged the references to global symbols and functions. *)
Inductive match_globalenvs (f: meminj) (bound: block): Prop :=
| mk_match_globalenvs
(DOMAIN: forall b, Plt b bound -> f b = Some(b, 0))
(IMAGE: forall b1 b2 delta, f b1 = Some(b2, delta) -> Plt b2 bound -> b1 = b2)
(SYMBOLS: forall id b, Genv.find_symbol ge id = Some b -> Plt b bound)
(FUNCTIONS: forall b fd, Genv.find_funct_ptr ge b = Some fd -> Plt b bound)
(VARINFOS: forall b gv, Genv.find_var_info ge b = Some gv -> Plt b bound).
Remark inj_preserves_globals:
forall f hi,
match_globalenvs f hi ->
meminj_preserves_globals ge f.
(** * Invariant on abstract call stacks  *)
(** Call stacks represent abstractly the execution state of the current C#minor and Cminor functions, as well as the states of the calling functions.  A call stack is a list of frames, each frame collecting information on the current execution state of a C#minor function and its Cminor translation. *)
Inductive frame : Type :=
Frame(cenv: compilenv)
(tf: Cminor.function)
(e: Csharpminor.env)
(le: Csharpminor.temp_env)
(te: Cminor.env)
(sp: block)
(lo hi: block).
Definition callstack : Type := list frame.
(** Matching of call stacks imply: - matching of environments for each of the frames - matching of the global environments - separation conditions over the memory blocks allocated for C#minor local variables; - separation conditions over the memory blocks allocated for Cminor stack data; - freeable permissions on the parts of the Cminor stack data blocks that are not images of C#minor local variable blocks. *)
Inductive match_callstack (f: meminj) (m: mem) (tm: mem):
callstack -> block -> block -> Prop :=
| mcs_nil:
forall hi bound tbound,
match_globalenvs f hi ->
Ple hi bound -> Ple hi tbound ->
match_callstack f m tm nil bound tbound
| mcs_cons:
forall cenv tf e le te sp lo hi cs bound tbound
(BOUND: Ple hi bound)
(TBOUND: Plt sp tbound)
(MTMP: match_temps f le te)
(MENV: match_env f cenv e sp lo hi)
(BOUND: match_bounds e m)
(PERM: padding_freeable f e tm sp tf.(fn_stackspace))
(MCS: match_callstack f m tm cs lo sp),
match_callstack f m tm (Frame cenv tf e le te sp lo hi :: cs) bound tbound.
(** [match_callstack] implies [match_globalenvs]. *)

Lemma match_callstack_match_globalenvs:
forall f m tm cs bound tbound,
match_callstack f m tm cs bound tbound ->
exists hi, match_globalenvs f hi.