Remark alloc_global_unchanged:
forall (P: block -> Z -> Prop) m id g m',
alloc_global m (id, g) = Some m' ->
Mem.unchanged_on P m m'.
Remark alloc_globals_unchanged:
forall (P: block -> Z -> Prop) gl m m',
alloc_globals m gl = Some m' ->
Mem.unchanged_on P m m'.
Remark load_store_init_data_invariant:
forall m m' b,
(forall chunk ofs, Mem.load chunk m' b ofs = Mem.load chunk m b ofs) ->
forall il p,
load_store_init_data m b p il -> load_store_init_data m' b p il.
Definition globals_initialized (g: t) (m: mem) :=
forall b gd,
find_def g b = Some gd ->
match gd with
| Gfun f =>
Mem.perm m b 0 Cur Nonempty
/\ (forall ofs k p, Mem.perm m b ofs k p -> ofs = 0 /\ p = Nonempty)
| Gvar v =>
Mem.range_perm m b 0 (init_data_list_size v.(gvar_init)) Cur (perm_globvar v)
/\ (forall ofs k p, Mem.perm m b ofs k p ->
0 <= ofs < init_data_list_size v.(gvar_init) /\ perm_order (perm_globvar v) p)
/\ (v.(gvar_volatile) = false -> load_store_init_data m b 0 v.(gvar_init))
/\ (v.(gvar_volatile) = false -> Mem.loadbytes m b 0 (init_data_list_size v.(gvar_init)) = Some (bytes_of_init_data_list v.(gvar_init)))
end.

(* Specifications: *)
Lemma alloc_global_initialized:
forall g m id gd m',
genv_next g = Mem.nextblock m ->
alloc_global m (id, gd) = Some m' ->
globals_initialized g m ->
globals_initialized (add_global g (id, gd)) m'
/\ genv_next (add_global g (id, gd)) = Mem.nextblock m'.
Lemma alloc_globals_initialized:
forall gl ge m m',
alloc_globals m gl = Some m' ->
genv_next ge = Mem.nextblock m ->
globals_initialized ge m ->
globals_initialized (add_globals ge gl) m'.