(** Special case of [external_call_mem_inject_gen] (for backward compatibility) *)
Definition meminj_preserves_globals (F V: Type) (ge: Genv.t F V) (f: block -> option (block * Z)) : Prop :=
(forall id b, Genv.find_symbol ge id = Some b -> f b = Some(b, 0))
/\ (forall b gv, Genv.find_var_info ge b = Some gv -> f b = Some(b, 0))
/\ (forall b1 b2 delta gv, Genv.find_var_info ge b2 = Some gv -> f b1 = Some(b2, delta) -> b2 = b1).

(* Specifications: *)
Lemma external_call_mem_inject:
forall ef F V (ge: Genv.t F V) vargs m1 t vres m2 f m1' vargs',
meminj_preserves_globals ge f ->
external_call ef ge vargs m1 t vres m2 ->
Mem.inject f m1 m1' ->
Val.inject_list f vargs vargs' ->
exists f', exists vres', exists m2',
external_call ef ge vargs' m1' t vres' m2'
/\ Val.inject f' vres vres'
/\ Mem.inject f' m2 m2'
/\ Mem.unchanged_on (loc_unmapped f) m1 m2
/\ Mem.unchanged_on (loc_out_of_reach f m1) m1' m2'
/\ inject_incr f f'
/\ inject_separated f f' m1 m1'.
Lemma external_call_mem_inject:
forall ef F V (ge: Genv.t F V) vargs m1 t vres m2 f m1' vargs',
meminj_preserves_globals ge f ->
external_call ef ge vargs m1 t vres m2 ->
Mem.inject f m1 m1' ->
injection_full f m1 ->
Val.inject_list f vargs vargs' ->
exists f', exists vres', exists m2', exists t',
external_call ef ge vargs' m1' t' vres' m2'
/\ Val.inject f' vres vres'
/\ Mem.inject f' m2 m2'
/\ Mem.unchanged_on (loc_unmapped f) m1 m2
/\ Mem.unchanged_on (loc_out_of_reach f m1) m1' m2'
/\ inject_incr f f'
/\ inject_separated f f' m1 m1'
/\ inject_trace f' t t' /\ injection_full f' m2.
Lemma external_call_mem_inject':
forall ef F V (ge: Genv.t F V) vargs m1 t vres m2 f m1' vargs',
meminj_preserves_globals ge f ->
external_call ef ge vargs m1 t vres m2 ->
Mem.inject f m1 m1' ->
Val.inject_list f vargs vargs' ->
exists f', exists vres', exists m2', exists t',
external_call ef ge vargs' m1' t' vres' m2'
/\ Val.inject f' vres vres'
/\ Mem.inject f' m2 m2'
/\ Mem.unchanged_on (loc_unmapped f) m1 m2
/\ Mem.unchanged_on (loc_out_of_reach f m1) m1' m2'
/\ inject_incr f f'
/\ inject_separated f f' m1 m1'
/\ inject_trace f' t t'.