Section ALLOC.
Variable m1: mem.
Variables lo hi: Z.
Variable m2: mem.
Variable b: block.
Hypothesis ALLOC: alloc m1 lo hi = (m2, b).
Local Hint Resolve valid_block_alloc fresh_block_alloc valid_new_block: mem.
Local Hint Resolve perm_alloc_1 perm_alloc_2 perm_alloc_3 perm_alloc_4: mem.
Local Hint Resolve valid_access_alloc_other valid_access_alloc_same: mem.
End ALLOC.
Local Hint Resolve valid_block_alloc fresh_block_alloc valid_new_block: mem.
Local Hint Resolve valid_access_alloc_other valid_access_alloc_same: mem.
(** ** Properties related to [free]. *)
Local Hint Resolve valid_block_free_1 valid_block_free_2: mem.
End FREE.
Local Hint Resolve valid_block_free_1 valid_block_free_2
perm_free_1 perm_free_2 perm_free_3
valid_access_free_1 valid_access_free_inv_1: mem.
(** ** Properties related to [drop_perm] *)
End DROP.
(** * Generic injections *)
(** A memory state [m1] generically injects into another memory state [m2] via the memory injection [f] if the following conditions hold: - each access in [m2] that corresponds to a valid access in [m1] is itself valid; - the memory value associated in [m1] to an accessible address must inject into [m2]'s memory value at the corersponding address. *)
Record mem_inj (f: meminj) (m1 m2: mem) : Prop :=
mk_mem_inj {
mi_perm:
forall b1 b2 delta ofs k p,
f b1 = Some(b2, delta) ->
perm m1 b1 ofs k p ->
perm m2 b2 (ofs + delta) k p;
mi_align:
forall b1 b2 delta chunk ofs p,
f b1 = Some(b2, delta) ->
range_perm m1 b1 ofs (ofs + size_chunk chunk) Max p ->
(align_chunk chunk | delta);
mi_memval:
forall b1 ofs b2 delta,
f b1 = Some(b2, delta) ->
perm m1 b1 ofs Cur Readable ->
memval_inject f (ZMap.get ofs m1.(mem_contents)#b1) (ZMap.get (ofs+delta) m2.(mem_contents)#b2)
}.
(** Preservation of permissions *)
(** Preservation of loads. *)

Lemma load_inj:
forall f m1 m2 chunk b1 ofs b2 delta v1,
mem_inj f m1 m2 ->
load chunk m1 b1 ofs = Some v1 ->
f b1 = Some (b2, delta) ->
exists v2, load chunk m2 b2 (ofs + delta) = Some v2 /\ Val.inject f v1 v2.