Definition sbrk_spec :=
(* like malloc without token; and I removed the possibility of failure to streamline the proof of fill_bin *)
DECLARE _sbrk
WITH n:Z
PRE [ 1%positive OF tuint ]
PROP (0 <= n <= Int.max_unsigned)
LOCAL (temp 1%positive (Vint (Int.repr n)))
SEP ()
POST [ tptr tvoid ] EX p:_,
PROP ()
LOCAL (temp ret_temp p)
SEP ( (* if eq_dec p nullval then emp else memory_block Tsh n p) *)
memory_block Tsh n p).
Definition bin2size_spec :=
DECLARE _bin2size
WITH b: Z
PRE [ _b OF tint ]
PROP( 0 <= b <= Int.max_signed )
LOCAL (temp _b (Vint (Int.repr b))) SEP ()
POST [ tuint ]
PROP() LOCAL(temp ret_temp (Vint (Int.repr (bin2sizeZ b)))) SEP ().
Definition size2bin_spec :=
DECLARE _size2bin
WITH s: Z
PRE [ _s OF tuint ]    (* Vlong? *)
PROP( 0 <= s <= Int.max_unsigned )
LOCAL (temp _s (Vint (Int.repr s))) SEP ()
POST [ tint ]
PROP() LOCAL(temp ret_temp (Vint (Int.repr (size2binZ s)))) SEP ().
(* malloc token, which accounts for the size field and padding. * n is the size requested * Unfolding the definition reveals the stored size value and the * actual size of the block. * Note that offset_val is in bytes, not like C pointer arith. *)
Definition malloc_token' (sh: share) (n: Z) (p: val): mpred :=
data_at Tsh tuint (offset_val (- WORD) p) (Vint (Int.repr n))
* memory_block Tsh ((bin2sizeZ(size2binZ(n)) - n)) (offset_val n p).

Lemma malloc_token'_valid_pointer:
forall sh n p, malloc_token' sh n p |-- valid_pointer p.