(** Injections that preserve used globals. *)
Record meminj_preserves_globals (f: meminj) : Prop := {
symbols_inject_1: forall id b b' delta,
f b = Some(b', delta) -> Genv.find_symbol ge id = Some b ->
delta = 0 /\ Genv.find_symbol tge id = Some b';
symbols_inject_2: forall id b,
kept id -> Genv.find_symbol ge id = Some b ->
exists b', Genv.find_symbol tge id = Some b' /\ f b = Some(b', 0);
symbols_inject_3: forall id b',
Genv.find_symbol tge id = Some b' ->
exists b, Genv.find_symbol ge id = Some b /\ f b = Some(b', 0);
defs_inject: forall b b' delta gd,
f b = Some(b', delta) -> Genv.find_def ge b = Some gd ->
Genv.find_def tge b' = Some gd /\ delta = 0 /\
(forall id, ref_def gd id -> kept id);
defs_rev_inject: forall b b' delta gd,
f b = Some(b', delta) -> Genv.find_def tge b' = Some gd ->
Genv.find_def ge b = Some gd /\ delta = 0
}.
Definition init_meminj : meminj :=
fun b =>
match Genv.invert_symbol ge b with
| Some id =>
match Genv.find_symbol tge id with
| Some b' => Some (b', 0)
| None => None
end
| None => None
end.
Remark init_meminj_eq:
forall id b b',
Genv.find_symbol ge id = Some b -> Genv.find_symbol tge id = Some b' ->
init_meminj b = Some(b', 0).
Remark init_meminj_invert:
forall b b' delta,
init_meminj b = Some(b', delta) ->
delta = 0 /\ exists id, Genv.find_symbol ge id = Some b /\ Genv.find_symbol tge id = Some b'.

(* Specifications: *)
Lemma init_meminj_preserves_globals:
meminj_preserves_globals init_meminj.
Lemma globals_symbols_inject:
forall j, meminj_preserves_globals j -> symbols_inject j ge tge.
Lemma symbol_address_inject:
forall j id ofs,
meminj_preserves_globals j -> kept id ->
Val.inject j (Genv.symbol_address ge id ofs) (Genv.symbol_address tge id ofs).