Section GENERIC_INJECTION.
Variable f: meminj.
Variables m m': mem.
Hypothesis valid_pointer_inj:
forall b1 ofs b2 delta,
f b1 = Some(b2, delta) ->
Mem.valid_pointer m b1 (Ptrofs.unsigned ofs) = true ->
Mem.valid_pointer m' b2 (Ptrofs.unsigned (Ptrofs.add ofs (Ptrofs.repr delta))) = true.
Hypothesis weak_valid_pointer_inj:
forall b1 ofs b2 delta,
f b1 = Some(b2, delta) ->
Mem.weak_valid_pointer m b1 (Ptrofs.unsigned ofs) = true ->
Mem.weak_valid_pointer m' b2 (Ptrofs.unsigned (Ptrofs.add ofs (Ptrofs.repr delta))) = true.
Hypothesis weak_valid_pointer_no_overflow:
forall b1 ofs b2 delta,
f b1 = Some(b2, delta) ->
Mem.weak_valid_pointer m b1 (Ptrofs.unsigned ofs) = true ->
0 <= Ptrofs.unsigned ofs + Ptrofs.unsigned (Ptrofs.repr delta) <= Ptrofs.max_unsigned.
Hypothesis valid_different_pointers_inj:
forall b1 ofs1 b2 ofs2 b1' delta1 b2' delta2,
b1 <> b2 ->
Mem.valid_pointer m b1 (Ptrofs.unsigned ofs1) = true ->
Mem.valid_pointer m b2 (Ptrofs.unsigned ofs2) = true ->
f b1 = Some (b1', delta1) ->
f b2 = Some (b2', delta2) ->
b1' <> b2' \/
Ptrofs.unsigned (Ptrofs.add ofs1 (Ptrofs.repr delta1)) <> Ptrofs.unsigned (Ptrofs.add ofs2 (Ptrofs.repr delta2)).
Remark val_inject_vtrue: forall f, Val.inject f Vtrue Vtrue.
Remark val_inject_vptrofs: forall n, Val.inject f (Vptrofs n) (Vptrofs n).
Definition optval_self_injects (ov: option val) : Prop :=
match ov with
| Some (Vptr b ofs) => False
| _ => True
end.
Remark sem_binarith_inject:
forall sem_int sem_long sem_float sem_single v1 t1 v2 t2 v v1' v2',
sem_binarith sem_int sem_long sem_float sem_single v1 t1 v2 t2 m = Some v ->
Val.inject f v1 v1' -> Val.inject f v2 v2' ->
(forall sg n1 n2, optval_self_injects (sem_int sg n1 n2)) ->
(forall sg n1 n2, optval_self_injects (sem_long sg n1 n2)) ->
(forall n1 n2, optval_self_injects (sem_float n1 n2)) ->
(forall n1 n2, optval_self_injects (sem_single n1 n2)) ->
exists v', sem_binarith sem_int sem_long sem_float sem_single v1' t1 v2' t2 m' = Some v' /\ Val.inject f v v'.
Remark sem_shift_inject:
forall sem_int sem_long v1 t1 v2 t2 v v1' v2',
sem_shift sem_int sem_long v1 t1 v2 t2 = Some v ->
Val.inject f v1 v1' -> Val.inject f v2 v2' ->
exists v', sem_shift sem_int sem_long v1' t1 v2' t2 = Some v' /\ Val.inject f v v'.
Remark sem_cmp_ptr_inj:
forall c v1 v2 v tv1 tv2,
cmp_ptr m c v1 v2 = Some v ->
Val.inject f v1 tv1 ->
Val.inject f v2 tv2 ->
exists tv, cmp_ptr m' c tv1 tv2 = Some tv /\ Val.inject f v tv.
Remark sem_cmp_inj:
forall cmp v1 tv1 ty1 v2 tv2 ty2 v,
sem_cmp cmp v1 ty1 v2 ty2 m = Some v ->
Val.inject f v1 tv1 ->
Val.inject f v2 tv2 ->
exists tv, sem_cmp cmp tv1 ty1 tv2 ty2 m' = Some tv /\ Val.inject f v tv.
End GENERIC_INJECTION.

Lemma sem_binary_operation_inject:
forall f m m' cenv op v1 ty1 v2 ty2 v tv1 tv2,
sem_binary_operation cenv op v1 ty1 v2 ty2 m = Some v ->
Val.inject f v1 tv1 -> Val.inject f v2 tv2 ->
Mem.inject f m m' ->
exists tv, sem_binary_operation cenv op tv1 ty1 tv2 ty2 m' = Some tv /\ Val.inject f v tv.