blob: b995ee6b803c458a291c177ea4be093a1f2f3e0c [file]
(*
* Copyright 2016, NICTA
*
* This software may be distributed and modified according to the terms of
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
* See "LICENSE_GPLv2.txt" for details.
*
* @TAG(NICTA_GPL)
*)
theory SerialS
imports
PleSle
begin
type_synonym U8 = "8 word"
type_synonym U16 = "16 word"
type_synonym U32 = "32 word"
type_synonym U64 = "64 word"
lemma sle32_length:
"length (sle32 x) = 4"
by (simp add: sle32_def length_word_rsplit_exp_size' word_size)
lemma ple32_word_rcat_eq1:
"ple32 (sle32 x @ xs) 0 = x"
apply (simp only: ple32_def unat_0)
apply (subst drop_0)
apply (cut_tac x=x in sle32_length)
apply (simp add: sle32_def word_rcat_rsplit)
done
lemma ple32_word_rcat_eq2:
"length ys = (unat n) \<Longrightarrow> ple32 (ys @ sle32 x @ xs) n = x"
by (simp add: ple32_def ple32_word_rcat_eq1[simplified ple32_def, simplified])
lemmas ple32_word_rcat_eq = ple32_word_rcat_eq1 ple32_word_rcat_eq2
lemma sle64_length:
"length (sle64 x) = 8"
by (simp add: sle64_def length_word_rsplit_exp_size' word_size)
lemma ple64_word_rcat_eq1:
"ple64 (sle64 x @ xs) 0 = x"
apply (simp only: ple64_def unat_0)
apply (subst drop_0)
apply (cut_tac x=x in sle64_length)
apply (simp add: sle64_def word_rcat_rsplit)
done
lemma ple64_word_rcat_eq2:
"length ys = (unat n) \<Longrightarrow> ple64 (ys @ sle64 x @ xs) n = x"
by (simp add: ple64_def ple64_word_rcat_eq1[simplified ple64_def, simplified])
lemmas ple64_word_rcat_eq = ple64_word_rcat_eq1 ple64_word_rcat_eq2
definition pObjDel :: "U8 list \<Rightarrow> U32 \<Rightarrow> U64 ObjDel"
where
"pObjDel data' offs' \<equiv> ObjDel.make (ple64 data' offs') \<comment> \<open>id\<close>
\<comment> \<open>End 4 bytes\<close>"
definition sObjDel :: "ObjDel\<^sub>T \<Rightarrow> U8 list"
where
"sObjDel odel \<equiv> (sle64 $ ObjDel.id\<^sub>f odel) (* id *) (* End 8 bytes *)"
lemma objDel_inverse:
"pObjDel (sObjDel odel) 0 = odel"
apply(simp add: pObjDel_def sObjDel_def)
apply(simp add: ObjDel.defs)
using ple64_word_rcat_eq[where xs=Nil]
by simp
definition pObjData :: "U8 list \<Rightarrow> U32 \<Rightarrow> U32 \<Rightarrow> ObjData\<^sub>T"
where
"pObjData data offs olen \<equiv>
ObjData.make (ple64 data offs) (* id *)
(WordArrayT.make $ slice (unat (offs + 8)) (unat (offs + 8) + unat (olen - bilbyFsObjHeaderSize - bilbyFsObjDataHeaderSize)) data)"
definition sObjData :: "ObjData\<^sub>T \<Rightarrow> U32 \<Rightarrow> U8 list"
where
"sObjData odata len \<equiv> (sle64 $ ObjData.id\<^sub>f odata) @ take (unat len) (\<alpha>wa (ObjData.odata\<^sub>f odata))"
lemma length_sle32:
"length ((sle32 (x::U32))::U8 list) = 4"
by (simp add: Word.length_word_rsplit_exp_size' Word.word_size sle32_def )
lemma length_sle64:
"length ((sle64 (x::U64))::U8 list) = 8"
by (simp add: Word.length_word_rsplit_exp_size' Word.word_size sle64_def )
lemma objData_inverse:
"unat (len - bilbyFsObjHeaderSize - bilbyFsObjDataHeaderSize) = length (\<alpha>wa (odata\<^sub>f odata)) \<Longrightarrow>
len - bilbyFsObjHeaderSize - bilbyFsObjDataHeaderSize < len \<Longrightarrow>
pObjData (sObjData odata len) 0 len = odata"
apply(simp add: pObjData_def)
apply(simp add: sObjData_def)
apply(simp add: ObjData.defs)
apply(simp add: ple64_word_rcat_eq length_sle64 slice_def)
apply (subgoal_tac "unat len \<ge> length (\<alpha>wa (odata\<^sub>f odata)) ")
apply (simp add: wordarray_make')
apply unat_arith
done
definition
pu8 :: "U8 list \<Rightarrow> U32 \<Rightarrow> U8"
where
"pu8 xs offs = word_rcat (slice (unat offs) (unat offs+1) xs)"
definition pObjDentry :: "U8 list \<Rightarrow> U32 \<Rightarrow> ObjDentry\<^sub>T"
where
"pObjDentry data offs \<equiv>
let nlen = ple16 data (offs+6)
in ObjDentry.make
(ple32 data (offs+0)) (* ino *)
(pu8 data (offs+4)) (* dtype *)
(* 1 byte padding *)
nlen (* nlen *)
(WordArrayT.make $ slice (unat (offs+ 8)) (unat (offs + 8) + unat nlen) data) (* name *)"
definition pArrObjDentry :: "U8 list \<Rightarrow> U32 \<Rightarrow> U32 \<Rightarrow> (ObjDentry\<^sub>T Array \<times> 32 word \<times> 32 word list)"
where
"pArrObjDentry data offs nb_dentry =
(case (fold
(\<lambda>_ (xs,doffs,offslist).
let dentry = pObjDentry data doffs ;
newoffs = doffs + 8 + wordarray_length (ObjDentry.name\<^sub>f dentry)
in (xs@[Option.Some dentry], newoffs, offslist@ [newoffs])) [0..<unat nb_dentry] ([], offs, []))
of (xs, doffs, offslist) \<Rightarrow> (ArrayT.make (xs@ [Option.None ()]), doffs, offslist))"
definition pObjDentarr :: "U8 list \<Rightarrow> U32 \<Rightarrow> U32 \<Rightarrow> ObjDentarr\<^sub>T"
where
"pObjDentarr data offs olen \<equiv>
let nb_dentry = ple32 data (offs+8)
in ObjDentarr.make
(ple64 data offs) (* id *)
(nb_dentry) (* nb_dentry *)
(prod.fst (pArrObjDentry (take (unat (offs+olen-bilbyFsObjHeaderSize)) data) (offs+bilbyFsObjDentarrHeaderSize) nb_dentry))
"
definition pObjDentarrSize :: "U8 list \<Rightarrow> U32 \<Rightarrow> U32 \<Rightarrow> U32"
where
"pObjDentarrSize data offs olen \<equiv>
let nb_dentry = ple32 data (offs+8)
in (prod.fst (prod.snd (pArrObjDentry (take (unat (offs+olen-bilbyFsObjHeaderSize)) data) (offs+bilbyFsObjDentarrHeaderSize) nb_dentry)))
"
definition pObjSuper :: "U8 list \<Rightarrow> U32 \<Rightarrow> ObjSuper\<^sub>T"
where
"pObjSuper data offs \<equiv>
ObjSuper.make
(ple32 data offs) (* nb_eb *)
(ple32 data (offs+4)) (* eb_size *)
(ple32 data (offs+8)) (* io_size *)
(ple32 data (offs+12)) (* nb_reserved_gc *)
(ple32 data (offs+16)) (* nb_reserved_del *)
(ple32 data (offs+20)) (* cur_eb *)
(ple32 data (offs+24)) (* cur_offs *)
(ple32 data (offs+28)) (* last_inum *)
(ple64 data (offs+32)) (* next_sqnum *)
"
(* TODO: we do not have pObjSumEntry . Probably we need it.*)
definition sObjSumEntry :: "ObjSumEntry\<^sub>T \<Rightarrow> U8 list"
where
"sObjSumEntry ose \<equiv>
(sle64 $ ObjSumEntry.id\<^sub>f ose)
@ (sle64 $ ObjSumEntry.sqnum\<^sub>f ose)
@ (sle32 $ ObjSumEntry.len\<^sub>f ose)
@ (sle32 $ ObjSumEntry.del_flags_and_offs\<^sub>f ose)
@ (sle16 $ ObjSumEntry.count\<^sub>f ose)"
consts sObjSuper :: "ObjSuper\<^sub>T \<Rightarrow> U8 list"
type_synonym Buffer\<^sub>T = "(U8 WordArray, U32) Buffer"
definition bounded :: "Buffer\<^sub>T \<Rightarrow> U8 list"
where
"bounded buf = take (unat (bound\<^sub>f buf)) (WordArrayT.\<alpha>wa (data\<^sub>f buf))"
definition wellformed_buf :: "Buffer\<^sub>T \<Rightarrow> bool"
where
"wellformed_buf buf \<equiv> unat (bound\<^sub>f buf) \<le> List.length (\<alpha>wa (Buffer.data\<^sub>f buf))"
lemma elem_take_n:
"i<n \<Longrightarrow> (take n xs ! i) = xs ! i"
by simp
lemma deserialise_le32_bounded_ret:
assumes bounded:
"bbuf = bounded buf"
assumes valid_offs:
"unat offs + 3 < length (bounded buf)"
shows
"deserialise_le32 (buf, offs) = ple32 bbuf offs"
apply (simp add: bounded)
using valid_offs
apply (subgoal_tac "(\<forall>i\<in>{0..3}. unat (offs+i) < length (bounded buf))")
prefer 2
apply unat_arith
apply (simp add: bounded_def)
apply (clarsimp simp: wordarray_get_ret[where arr="data\<^sub>f buf"] ple32_def
deserialise_le32_def)
apply (subgoal_tac "\<forall>j\<in>{1..3}. (unat (offs + j) > 0)")
prefer 2
apply clarsimp
apply (drule_tac x=j in bspec, simp)
apply unat_arith
apply (subst take_drop_decomp, (simp+))+
apply (subst unatSuc[symmetric], (simp add: unat_gt_0[symmetric] add.commute[where b=offs]))+
apply simp
apply (rule trans, rule word_rcat_rsplit[symmetric])
apply (rule arg_cong[where f=word_rcat])
apply (subst word_rsplit_upt[where n=4], simp add: word_size)
apply simp
apply (simp add: upt_rec shiftr_over_or_dist shiftl_shiftr1 shiftl_shiftr2 word_size)
apply (safe intro!: word_eqI, simp_all add: word_size word_ops_nth_size nth_ucast
nth_shiftr nth_shiftl add.commute[where b=offs] test_bit_out_of_bounds)
done
lemma deserialise_le64_bounded_ret:
assumes bounded:
"bbuf = bounded buf"
assumes valid_offs:
"unat offs + 7 < length (bounded buf)"
shows
"deserialise_le64 (buf, offs) = ple64 bbuf offs"
apply (simp add: bounded)
using valid_offs
apply (subgoal_tac "(\<forall>i\<in>{0..7}. unat (offs+i) < length (bounded buf))")
prefer 2
apply unat_arith
apply (simp add: bounded_def)
apply (clarsimp simp: wordarray_get_ret[where arr="data\<^sub>f buf"] ple64_def
deserialise_le64_def)
apply (subgoal_tac "\<forall>j\<in>{1..7}. (unat (offs + j) > 0)")
prefer 2
apply clarsimp
apply (drule_tac x=j in bspec, simp)
apply unat_arith
(* feel free to improve this apply script..*)
apply (subst take_drop_decomp, (simp+))+
apply (subst unatSuc[symmetric], (simp add: unat_gt_0[symmetric] add.commute[where b=offs]))+
apply simp
apply (rule trans, rule word_rcat_rsplit[symmetric])
apply (rule arg_cong[where f=word_rcat])
apply (subst word_rsplit_upt[where n=8], simp add: word_size)
apply simp
apply (simp add: upt_rec shiftr_over_or_dist shiftl_shiftr1 shiftl_shiftr2 word_size)
apply (safe intro!: word_eqI, simp_all add: word_size word_ops_nth_size nth_ucast
nth_shiftr nth_shiftl add.commute[where b=offs] test_bit_out_of_bounds)
done
definition buf_unchanged :: "Buffer\<^sub>T \<Rightarrow> Buffer\<^sub>T \<Rightarrow> U32 \<Rightarrow> U32 \<Rightarrow> bool"
where
"buf_unchanged newbuf oldbuf offs' l \<equiv> take (unat offs') (\<alpha>wa (data\<^sub>f newbuf)) = take (unat offs') (\<alpha>wa (data\<^sub>f oldbuf)) \<and>
drop (unat offs' + unat l) (\<alpha>wa (data\<^sub>f newbuf)) = drop (unat offs' + unat l) (\<alpha>wa (data\<^sub>f oldbuf)) \<and>
bound\<^sub>f newbuf = bound\<^sub>f oldbuf"
lemma bounded_le_length:
"(length $ bounded x) \<le> length (\<alpha>wa $ data\<^sub>f x)"
by (simp add: bounded_def)
lemmas serialise_le64_simps = ArrA.make_def ElemA.make_def ElemAO.make_def ArrayUseValueP.defs
setu8_def[unfolded sanitizers] wordarray_make bounded_def
serialise_u8_def[unfolded tuple_simps sanitizers]
(*
lemma serialise_le64_ret:
assumes valid_offs:
"unat offs + 7 < length (bounded buf)"
assumes ret:
"P (buf\<lparr>data\<^sub>f := WordArrayT.make (\<alpha>wa (data\<^sub>f buf)[
unat offs := u64_to_u8 v,
unat (offs+1) := u64_to_u8 (v >> 8),
unat (offs+2) := u64_to_u8 (v >> 16),
unat (offs+3) := u64_to_u8 (v >> 24),
unat (offs+4) := u64_to_u8 (v >> 32),
unat (offs+5) := u64_to_u8 (v >> 40),
unat (offs+6) := u64_to_u8 (v >> 48),
unat (offs+7) := u64_to_u8 (v >> 56)])\<rparr>)"
notes wa_modify_ret = wordarray_modify_ret[rotated - 1, simplified Let_def ArrayUseValueP.defs ArrA.defs]
shows
"P (serialise_le64 (buf, offs, v))"
unfolding serialise_le64_def[unfolded tuple_simps sanitizers]
apply (simp add: serialise_le64_simps Let_def)
apply (rule wa_modify_ret[where index="offs"], simp add: serialise_le64_simps)
apply (rule wa_modify_ret[where index="offs+1"], simp add: serialise_le64_simps)
apply (rule wa_modify_ret[where index="offs+2"], simp add: serialise_le64_simps)
apply (rule wa_modify_ret[where index="offs+3"], simp add: serialise_le64_simps)
apply (rule wa_modify_ret[where index="offs+4"], simp add: serialise_le64_simps)
apply (rule wa_modify_ret[where index="offs+5"], simp add: serialise_le64_simps)
apply (rule wa_modify_ret[where index="offs+6"], simp add: serialise_le64_simps)
apply (rule wa_modify_ret[where index="offs+7"], simp add: serialise_le64_simps)
using ret apply simp
using valid_offs
apply ((simp add: serialise_le64_simps) , unat_arith?)+
done
*)
lemma take_irrelevance:
"P (xs!(unat (x + y))) \<Longrightarrow> unat (x + y) < unat z \<Longrightarrow>
P ((take (unat z) xs)!(unat (x + y)))"
by auto
lemma unat_space:
assumes "unat (x + y) < z"
and "unat (x + y) > unat x"
and "y' \<le> y"
shows "unat (x + y') < z"
proof -
have "\<And>x\<^sub>1. unat (x + y) \<le> x\<^sub>1 \<or> \<not> z \<le> x\<^sub>1"
using assms(1) by fastforce
thus ?thesis using assms
by (metis antisym_conv leI less_not_sym word_le_nat_alt word_plus_mono_right)
qed
lemma ple32_ret:
assumes 1:"unat offs < unat (offs + 3)"
assumes 2:"unat (offs + 3) < (length $ bounded buf)"
assumes 3:"P(ple32 (bounded buf) offs)"
shows "P (deserialise_le32 (buf, offs))"
proof -
from 1 2 have 4:"unat offs + 3 < (length $ bounded buf)" by (unat_arith, auto?)
show ?thesis
apply(subst deserialise_le32_bounded_ret)
apply simp
using 1 2 apply unat_arith
apply auto[1]
using 1 2 apply unat_arith
using 3 apply auto
done
qed
lemma ple64_ret:
assumes 1:"unat offs < unat (offs + 7)"
assumes 2:"unat (offs + 7) < (length $ bounded buf)"
assumes 3:"P (ple64 (bounded buf) offs)"
shows "P (deserialise_le64 (buf, offs))"
proof -
from 1 2 have 4:"unat offs + 7 < (length $ bounded buf)" by (unat_arith, auto?)
show ?thesis
apply(subst deserialise_le64_bounded_ret)
apply simp
using 1 2 apply unat_arith
apply auto[1]
using 1 2 apply unat_arith
using 3 apply auto
done
qed
lemma offs_le:
assumes "offs < offs+n"
assumes "unat (offs + n) \<le> ntake"
shows "unat offs < ntake"
using assms by unat_arith
lemma word_add_eq_unat:
assumes "(offs::('a::len word)) < offs + n"
assumes "i < n"
shows "unat (offs + i) = unat offs + unat i"
using assms by unat_arith
lemma ple16_eq_slice2:
assumes "offs < offs + 2"
assumes "unat offs + 2 \<le> length xs"
shows "ple16 xs offs = ple16 (slice (unat offs) (unat offs + 2) xs) 0"
using assms by (simp add: slice_def ple16_def drop_take word_add_eq_unat)
lemma ple32_eq_slice4:
assumes "offs < offs + 4"
assumes "unat offs + 4 \<le> length xs"
shows "ple32 xs offs = ple32 (slice (unat offs) (unat offs + 4) xs) 0"
using assms by (simp add: slice_def ple32_def drop_take word_add_eq_unat)
lemma ple64_eq_slice8:
assumes "offs < offs + 8"
assumes "unat offs + 8 \<le> length xs"
shows "ple64 xs offs = ple64 (slice (unat offs) (unat offs + 8) xs) 0"
using assms by (simp add: slice_def ple64_def drop_take word_add_eq_unat)
definition pObjInode :: "U8 list \<Rightarrow> U32 \<Rightarrow> ObjInode\<^sub>T"
where
"pObjInode data offs \<equiv>
ObjInode.make
(((ple64 data offs) AND (NOT (bilbyFsOidMaskAll OR ucast word32Max))) OR bilbyFsOidMaskInode) (* id *)
(ple64 data (offs+8)) (* size *)
(ple64 data (offs+16)) (* atime *)
(ple64 data (offs+24)) (* ctime *)
(ple64 data (offs+32)) (* mtime *)
(ple32 data (offs+40)) (* nlink *)
(ple32 data (offs+44)) (* uid *)
(ple32 data (offs+48)) (* gid *)
(ple32 data (offs+52)) (* mode *)
(ple32 data (offs+56)) (* flags *)
(* End 60 bytes *)"
definition sObjInode :: "ObjInode\<^sub>T \<Rightarrow> U8 list"
where
"sObjInode odata \<equiv>
(sle64 $ ObjInode.id\<^sub>f odata)
@ (sle64 $ ObjInode.size\<^sub>f odata)
@ (sle64 $ ObjInode.atime_sec\<^sub>f odata)
@ (sle64 $ ObjInode.ctime_sec\<^sub>f odata)
@ (sle64 $ ObjInode.mtime_sec\<^sub>f odata)
@ (sle32 $ ObjInode.nlink\<^sub>f odata)
@ (sle32 $ ObjInode.uid\<^sub>f odata)
@ (sle32 $ ObjInode.gid\<^sub>f odata)
@ (sle32 $ ObjInode.mode\<^sub>f odata)
@ (sle32 $ ObjInode.flags\<^sub>f odata) (* End 60 bytes *)"
definition pObjHeader :: "U8 list \<Rightarrow> U32 \<Rightarrow> Obj\<^sub>T"
where
"pObjHeader data offs \<equiv>
Obj.make
(ple32 data offs) (* magic *)
(ple32 data (offs+4)) (* crc *)
(ple64 data (offs+8)) (* sqnum *)
(offs) (* offs not stored on medium *) (* changed back to offs, otherwise this doesnt correspond to the code*)
(ple32 data (offs+16)) (* len *)
(* 2 padding bytes *)
(data!unat (offs+22)) (* trans *)
(data!unat (offs+23)) (* otype *)
undefined (* ounion *)
(* End 24 bytes *)"
definition sObjHeader :: "Obj\<^sub>T \<Rightarrow> U8 list"
where
"sObjHeader obj \<equiv>
(sle32 $ Obj.magic\<^sub>f obj)
@ (sle32 $ Obj.crc\<^sub>f obj)
@ (sle64 $ Obj.sqnum\<^sub>f obj)
@ (sle32 $ Obj.len\<^sub>f obj)
@ [bilbyFsPadByte]
@ [bilbyFsPadByte]
@ [Obj.trans\<^sub>f obj]
@ [Obj.otype\<^sub>f obj] (* End 24 bytes *)"
lemma ObjHeader_inverse:
"pObjHeader (sObjHeader obj@xs) 0 = (obj\<lparr> Obj.ounion\<^sub>f := undefined, Obj.offs\<^sub>f := 0\<rparr>) "
apply(clarsimp simp: pObjHeader_def sObjHeader_def)
apply(clarsimp simp: Obj.defs)
apply(clarsimp simp: ple32_word_rcat_eq length_sle32 length_sle64)
apply(clarsimp simp: bilbyFsObjHeaderSize_def bilbyFsPadByte_def)
proof -
let ?magic = "sle32 (magic\<^sub>f obj)"
let ?crc = "sle32 (crc\<^sub>f obj)"
let ?sqnum = "sle64 (Obj.sqnum\<^sub>f obj)"
let ?len = "sle32 (Obj.len\<^sub>f obj)"
let ?tail = "0x42 # 0x42 # trans\<^sub>f obj # otype\<^sub>f obj # xs"
have append_assoc_intro : "\<And>P ys1 ys2 xs.
P ((ys1 @ ys2) @ xs) \<Longrightarrow> P (ys1 @ (ys2 @ xs))" by auto
have sqnum: "ple64 (?magic @ ?crc @ ?sqnum @ ?len @ ?tail) 8 = (Obj.sqnum\<^sub>f obj)"
apply(rule append_assoc_intro)
apply(rule ple64_word_rcat_eq)
apply(subst List.length_append)
using length_sle32 by auto
have len: "ple32 (?magic @ ?crc @ ?sqnum @ ?len @ ?tail) 16 = Obj.len\<^sub>f obj"
apply(rule append_assoc_intro[of _ "?magic"])
apply(rule append_assoc_intro[of _ "?magic @ ?crc"])
apply(rule append_assoc_intro[of _ "?magic @ ?crc @ ?sqnum"])
apply(rule ple32_word_rcat_eq)
using length_sle32 length_sle64 by auto
have trans:"(?magic @ ?crc @ ?sqnum @ ?len @ ?tail) ! 22 = Obj.trans\<^sub>f obj"
proof -
have "length (?magic @ ?crc @ ?sqnum @ ?len @ (66::8 word) # [66::8 word]) = 22"
using length_sle32 length_sle64 by simp
from this show ?thesis
by (metis (erased, hide_lams) append_Cons append_Nil append_assoc nth_append_length)
qed
have otype:"(?magic @ ?crc @ ?sqnum @ ?len @ ?tail) ! 23 = Obj.otype\<^sub>f obj"
proof -
have "length (?magic @ ?crc @ ?sqnum @ ?len @ (66::8 word) # (66::8 word) # [trans\<^sub>f obj]) = 23"
using length_sle32 length_sle64 by simp
from this show ?thesis
by (metis (erased, hide_lams) append_Cons append_Nil append_assoc nth_append_length)
qed
from sqnum len trans otype
show
"\<lparr>magic\<^sub>f = magic\<^sub>f obj, crc\<^sub>f = crc\<^sub>f obj,
sqnum\<^sub>f = ple64 (?magic @ ?crc @ ?sqnum @ ?len @ ?tail) 8,
offs\<^sub>f = 0,
len\<^sub>f = ple32 (?magic @ ?crc @ ?sqnum @ ?len @ ?tail) 16,
trans\<^sub>f = (?magic @ ?crc @ ?sqnum @ ?len @ ?tail) ! 22,
otype\<^sub>f = (?magic @ ?crc @ ?sqnum @ ?len @ ?tail) ! 23,
ounion\<^sub>f = undefined\<rparr> = obj\<lparr>ounion\<^sub>f := undefined, Obj.offs\<^sub>f := 0\<rparr>"
by auto
qed
lemmas pObjHeader_simp =
pObjHeader_def Let_def Obj.make_def bilbyFsObjHeaderSize_def
definition is_valid_ObjHeader :: "Obj\<^sub>T \<Rightarrow> U8 list \<Rightarrow> bool"
where
"is_valid_ObjHeader obj data \<equiv>
magic\<^sub>f obj = bilbyFsMagic \<and>
(unat $ Obj.len\<^sub>f obj) \<le> length data \<and>
trans\<^sub>f obj \<in> {bilbyFsTransIn, bilbyFsTransCommit} \<and>
is_len_and_type_ok (otype\<^sub>f obj, Obj.len\<^sub>f obj)"
lemma is_len_and_type_ok_hdr_szD:
"is_len_and_type_ok (otype, olen) \<Longrightarrow> bilbyFsObjHeaderSize \<le> olen"
by (auto simp add:
is_len_and_type_ok_def[unfolded sanitizers tuple_simps]
bilbyFsObjHeaderSize_def
prod.case_eq_if split: if_splits)
unat_arith+
lemma is_valid_ObjHeader_len_facts:
"is_valid_ObjHeader obj data \<Longrightarrow> unat bilbyFsObjHeaderSize \<le> length data \<and>
bilbyFsObjHeaderSize \<le> Obj.len\<^sub>f obj"
apply (clarsimp simp: is_valid_ObjHeader_def)
apply (drule is_len_and_type_ok_hdr_szD)
apply unat_arith
done
lemmas otype_simps =
bilbyFsObjTypeInode_def
bilbyFsObjTypeData_def
bilbyFsObjTypeDentarr_def
bilbyFsObjTypeDel_def
bilbyFsObjTypePad_def
bilbyFsObjTypeSuper_def
bilbyFsObjTypeSum_def
lemma is_len_and_type_ok_otype_valD:
"is_len_and_type_ok (otype, olen) \<Longrightarrow> otype \<in> {bilbyFsObjTypeInode,bilbyFsObjTypeData,bilbyFsObjTypeDentarr,bilbyFsObjTypeDel,bilbyFsObjTypePad,bilbyFsObjTypeSuper,bilbyFsObjTypeSum} "
by (auto simp add:
is_len_and_type_ok_def[unfolded sanitizers tuple_simps]
otype_simps split: if_splits)
definition is_valid_Obj :: "Obj\<^sub>T \<Rightarrow> bool"
where
"is_valid_Obj obj \<equiv>
if otype\<^sub>f obj = bilbyFsObjTypePad then \<exists>v. ounion\<^sub>f obj = TObjPad v else
if otype\<^sub>f obj = bilbyFsObjTypeInode then \<exists>v. ounion\<^sub>f obj = TObjInode v else
if otype\<^sub>f obj = bilbyFsObjTypeData then \<exists>v. ounion\<^sub>f obj = TObjData v else
if otype\<^sub>f obj = bilbyFsObjTypeDentarr then \<exists>v. ounion\<^sub>f obj = TObjDentarr v else
if otype\<^sub>f obj = bilbyFsObjTypeDel then \<exists>v. ounion\<^sub>f obj = TObjDel v else
True"
lemma is_valid_ObjHeader_len:
"is_valid_ObjHeader obj data \<Longrightarrow> bilbyFsObjHeaderSize \<le> Obj.len\<^sub>f obj"
apply (clarsimp simp add: is_valid_ObjHeader_def)
apply (erule is_len_and_type_ok_hdr_szD)
done
lemma is_valid_ObjHeader_len_unat:
"is_valid_ObjHeader obj data \<Longrightarrow> unat bilbyFsObjHeaderSize \<le> unat (Obj.len\<^sub>f obj)"
by (drule is_valid_ObjHeader_len) unat_arith
lemma is_valid_ObjHeader_buf_len:
"is_valid_ObjHeader obj data \<Longrightarrow>
(unat $ Obj.len\<^sub>f obj) \<le> length data \<and>
unat bilbyFsObjHeaderSize \<le> length data"
apply (clarsimp simp add: is_valid_ObjHeader_def)
apply (drule is_len_and_type_ok_hdr_szD)
apply unat_arith
done
definition sObjPad :: "U32 \<Rightarrow> U8 list"
where
"sObjPad olen \<equiv> replicate (unat (olen - bilbyFsObjHeaderSize)) bilbyFsPadByte"
consts pObjSummary :: "U8 list \<Rightarrow> U32 \<Rightarrow> ObjSummary\<^sub>T"
consts pObjPad :: "U8 list \<Rightarrow> U32 \<Rightarrow> unit"
definition pObjUnion :: "U8 list \<Rightarrow> U8 \<Rightarrow> U32 \<Rightarrow> U32 \<Rightarrow> ObjUnion\<^sub>T"
where
"pObjUnion data otype olen offs \<equiv>
if otype = bilbyFsObjTypePad then
TObjPad ()
else if otype = bilbyFsObjTypeData then
TObjData (pObjData data offs olen)
else if otype = bilbyFsObjTypeInode then
TObjInode (pObjInode data offs)
else if otype = bilbyFsObjTypeDentarr then
TObjDentarr (pObjDentarr data offs olen)
else if otype = bilbyFsObjTypeDel then
TObjDel (pObjDel data offs)
else if otype = bilbyFsObjTypeSuper then
TObjSuper (pObjSuper data offs)
else (*if otype = bilbyFsObjTypeSum then
TObjSummary (pObjSummary data offs) *) (* see comments in: serial.cogent for deserialise_ObjUnion:*)
TObjPad ()"
definition pObj :: "U8 list \<Rightarrow> U32 \<Rightarrow> Obj\<^sub>T"
where
"pObj data offs \<equiv>
let obj = pObjHeader data offs
in obj \<lparr>ounion\<^sub>f:= pObjUnion (take (unat offs + unat (Obj.len\<^sub>f obj)) data) (otype\<^sub>f obj) (Obj.len\<^sub>f obj) (offs+bilbyFsObjHeaderSize)\<rparr>"
text {* This could be implemented in Cogent instead *}
definition serialise_size_summary_Obj :: "ObjSummary\<^sub>T \<Rightarrow> U32"
where
"serialise_size_summary_Obj summary \<equiv>
bilbyFsObjHeaderSize + serialise_size_ObjSummary (nb_sum_entry\<^sub>f summary)"
definition os_sum_sz :: "OstoreState\<^sub>T \<Rightarrow> U32"
where
"os_sum_sz ostore_st \<equiv> serialise_size_summary_Obj (summary\<^sub>f ostore_st)"
definition bilbyFsMinObjSize :: U32
where
"bilbyFsMinObjSize \<equiv> bilbyFsObjHeaderSize + 8"
lemma deserialise_u8_ret:
assumes wf: "wellformed_buf buf"
assumes valid_offs:
"offs < bound\<^sub>f buf"
shows
"deserialise_u8 (buf, offs) = (\<alpha>wa $ data\<^sub>f buf) ! (unat offs)"
using valid_offs wordarray_get_ret[where arr="data\<^sub>f buf" and index=offs]
wf[simplified wellformed_buf_def]
apply (simp add: deserialise_u8_def)
apply (erule meta_impE)
apply unat_arith
apply simp
done
lemmas objheaders_simps = bilbyFsMagic_def
bilbyFsObjTypeInode_def bilbyFsObjTypeData_def
bilbyFsObjTypeDentarr_def bilbyFsObjTypeDel_def bilbyFsObjTypePad_def
bilbyFsObjTypeSuper_def bilbyFsObjTypeSum_def
bilbyFsTransIn_def bilbyFsTransCommit_def is_valid_ObjHeader_def pObjHeader_def
Obj.make_def
lemma deserialise_ObjHeader_ret:
assumes wf: "wellformed_buf buf"
assumes bound: "offs + bilbyFsObjHeaderSize \<le> bound\<^sub>f buf"
assumes no_of: "offs < offs + bilbyFsObjHeaderSize"
assumes err: "\<And>obj. P (obj, Error eInval)"
assumes suc:
"\<And>obj offs'. \<lbrakk> is_valid_ObjHeader (pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs) (bounded buf) ;
\<exists>v. obj\<lparr>ounion\<^sub>f:=v\<rparr> = pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs;
offs' = offs + bilbyFsObjHeaderSize;
offs + Obj.len\<^sub>f obj \<le> bound\<^sub>f buf;
offs < offs + Obj.len\<^sub>f obj\<rbrakk> \<Longrightarrow>
P (obj, Success (offs'))"
notes bilbyFsObjHeaderSize_def[simp]
shows "P (deserialise_ObjHeader (buf, offs, obj))"
proof -
have des_u8:
"deserialise_u8 (buf, offs + 23) = (\<alpha>wa $ data\<^sub>f buf) ! unat (offs + 23)"
"deserialise_u8 (buf, offs + 22) = (\<alpha>wa $ data\<^sub>f buf) ! unat (offs + 22)"
using bound no_of
by - ((subst deserialise_u8_ret[OF wf]), (unat_arith, simp+))+
have des_le64:
"deserialise_le64 (buf, offs + 8) = (ple64 (\<alpha>wa $ data\<^sub>f buf) (offs + 8))"
apply (rule ple64_ret)
using no_of
apply (simp add: )
apply (simp add: unat_arith_simps, unat_arith)
using bound wf no_of
apply (simp add: bounded_def wellformed_buf_def unat_arith_simps)
apply unat_arith
apply (simp add: bounded_def)
apply (subst ple64_take)
using bound no_of
apply (simp add: bounded_def unat_arith_simps)
apply unat_arith
using wf bound no_of
apply (simp add: wellformed_buf_def unat_arith_simps)
apply unat_arith
apply simp
done
have des_le32:
"deserialise_le32 (buf, offs) = (ple32 (\<alpha>wa $ data\<^sub>f buf) offs)"
"deserialise_le32 (buf, offs+4) = (ple32 (\<alpha>wa $ data\<^sub>f buf) (offs + 4))"
"deserialise_le32 (buf, offs+16) = (ple32 (\<alpha>wa $ data\<^sub>f buf) (offs + 16))"
ML_prf{*
fun solve_deserialise_le32 ctxt =
let
val add_simp = Simplifier.add_simp;
fun add_simps ctxt [] = ctxt
| add_simps ctxt (thm::thms) = add_simps (add_simp thm ctxt) thms;
val simp = Simplifier.asm_full_simp_tac;
val unat = (unat_arith_tac ctxt 1);
val ple32 = Method.rule_tac ctxt @{thms ple32_ret} [] 1;
val wf_bounded_unat = @{thms wellformed_buf_def bounded_def unat_arith_simps};
val simp_wf_bounded_unat = simp (add_simps ctxt wf_bounded_unat) 1;
val simp_bounded = simp (add_simp @{thm bounded_def} ctxt) 1;
val ple32_take = Method.rule_tac ctxt @{thms ple32_take} [] 1;
val simp_unat_plus = REPEAT_DETERM_N 2 ( simp_wf_bounded_unat THEN unat);
in
DETERM (ple32 THEN simp_unat_plus )
THEN (simp_bounded THEN ple32_take THEN simp_unat_plus)
end
*}
using wf bound no_of
by - (tactic {* solve_deserialise_le32 @{context} *})+
show ?thesis
unfolding deserialise_ObjHeader_def[unfolded tuple_simps sanitizers]
apply (clarsimp simp:Let_def err[simplified eInval_def])
apply (frule is_len_and_type_ok_hdr_szD)
apply (rule suc)
apply (clarsimp simp: objheaders_simps buf_simps des_le32 des_u8 )
apply (subgoal_tac "\<exists>v. ple32 (\<alpha>wa (data\<^sub>f buf)) (offs + 0x10) = v")
prefer 2
apply clarsimp
apply (erule exE, simp add: bounded_def)
using bound no_of wf apply (simp add: wellformed_buf_def)
apply (rule conjI)
apply unat_arith
apply (unat_arith)
apply (rule_tac x=undefined in exI)
apply (simp add: pObjHeader_def Obj.defs buf_simps des_le32 des_u8 des_le64)
apply (simp)
apply (simp, unat_arith)+
done
qed
definition
sObjUnion :: "ObjUnion\<^sub>T \<Rightarrow> U8 \<Rightarrow> U32 \<Rightarrow> U8 list"
where
"sObjUnion (ou::ObjUnion\<^sub>T) (otype::U8) (olen::U32) \<equiv>
case ou of
TObjDentarr odent \<Rightarrow> undefined (* TODO: no dentarr support for now *)
| TObjInode oinod \<Rightarrow> sObjInode oinod
| TObjData odata \<Rightarrow> sObjData odata olen
| TObjDel odel \<Rightarrow> sObjDel odel
| TObjSuper osup \<Rightarrow> sObjSuper osup
| TObjSummary g \<Rightarrow> undefined (* TODO: sObjSummary is undefined*)
| TObjPad opad \<Rightarrow> sObjPad olen"
lemmas bilbyFsObjTypes =
bilbyFsObjTypePad_def
bilbyFsObjTypeInode_def
bilbyFsObjTypeData_def
bilbyFsObjTypeDentarr_def
bilbyFsObjTypeDel_def
bilbyFsObjTypeSuper_def
bilbyFsObjTypeSum_def
lemma ObjUnion_inverse:
"\<And>v. ounion = TObjPad v \<Longrightarrow> otype = bilbyFsObjTypePad \<Longrightarrow>
pObjUnion (sObjUnion ounion otype olen @ xs) otype olen 0 = ounion"
by (simp add: sObjUnion_def pObjUnion_def )
lemma length_sObjUnion:
"\<And>v. ounion = TObjPad v \<Longrightarrow> otype = bilbyFsObjTypePad \<Longrightarrow>
olen \<ge> bilbyFsObjHeaderSize \<Longrightarrow>
length (sObjUnion ounion otype olen) = unat olen - unat bilbyFsObjHeaderSize"
apply (simp add: sObjUnion_def sObjPad_def )
apply unat_arith
done
definition sObj :: "Obj\<^sub>T \<Rightarrow> U8 list"
where
"sObj obj \<equiv> sObjHeader obj @ sObjUnion (ounion\<^sub>f obj) (otype\<^sub>f obj) (Obj.len\<^sub>f obj)"
lemma length_sObjHeader:
"length (sObjHeader obj) = unat bilbyFsObjHeaderSize"
by (simp add: sObjHeader_def length_sle32 length_sle64 bilbyFsObjHeaderSize_def)
lemma length_sObj:
"Obj.len\<^sub>f obj \<ge> bilbyFsObjHeaderSize \<Longrightarrow>
otype\<^sub>f obj = bilbyFsObjTypePad \<Longrightarrow>
is_valid_Obj obj \<Longrightarrow>
length (sObj obj) = unat (Obj.len\<^sub>f obj)"
apply (clarsimp simp add: is_valid_Obj_def split:if_splits)
apply (drule (2) length_sObjUnion)
apply (simp add: sObj_def length_sObjHeader word_le_nat_alt)
done
lemma Obj_inverse:
"otype\<^sub>f obj = bilbyFsObjTypePad \<Longrightarrow>
is_valid_Obj obj \<Longrightarrow>
Obj.offs\<^sub>f obj = 0 \<Longrightarrow>
pObj (sObj obj @ xs) 0 = obj"
unfolding pObj_def sObj_def Let_def
apply (simp add: ObjHeader_inverse)
apply (clarsimp simp: is_valid_Obj_def)
apply (frule (1) ObjUnion_inverse)
apply (simp add: pObjUnion_def sObjHeader_def word_le_nat_alt length_sObjHeader)
done
lemma buf_sub_slice_len_simplified:
"length v1 = unat j \<Longrightarrow> unat (offs :: 32 word) < length (\<alpha>wa (data\<^sub>f buf)) \<Longrightarrow>
unat (offs + j) \<le> length (\<alpha>wa (data\<^sub>f buf)) \<Longrightarrow>
unat offs < unat (offs + j) \<Longrightarrow>
length (take (unat offs) (\<alpha>wa (data\<^sub>f buf)) @
v1 @
drop (unat (offs + j)) (\<alpha>wa (data\<^sub>f buf))) = length (\<alpha>wa (data\<^sub>f buf))"
by simp unat_arith
lemma buf_sub_slice_absorb:
assumes len1: "length v1 = unat j"
and len2: "length v2 = unat (k-j)"
and j_less: "j \<le> k"
and j_nz: "j > 0"
and no_of: "unat offs < unat (offs + k)"
and len_ge: "unat (offs + k) \<le> length (\<alpha>wa (data\<^sub>f buf))"
shows "(buf_sub_slice (buf \<lparr>data\<^sub>f := WordArrayT.make
(buf_sub_slice buf offs (offs + j) v1)\<rparr>)
(offs + j) (offs + k)
v2) =
buf_sub_slice buf offs (offs + k) (v1 @ v2)"
proof -
have j_sub: "unat (offs + j) - unat offs = unat j"
using no_of j_less by unat_arith
have j_max: "unat (offs + j) \<ge> unat offs"
using no_of j_less by unat_arith
have k_j_sub: "unat (offs + k) - unat (offs + j) = unat (k - j)"
using no_of j_less by unat_arith
have k_sub: "(unat (offs + k) - unat offs) = unat k"
using no_of by unat_arith
have k_max: "(unat (offs + k)) \<ge> (unat offs)"
using no_of by unat_arith
have k_j_max: "(unat (offs + k)) \<ge> (unat (offs + j))"
using no_of j_less by unat_arith
have xx: "\<And>x v. data\<^sub>f (x\<lparr>data\<^sub>f := v\<rparr>) = v"
by simp
have len_ge': " unat offs < length (\<alpha>wa (data\<^sub>f buf))"
using len_ge no_of by unat_arith
have len_ge'': " unat (offs + j) \<le> length (\<alpha>wa (data\<^sub>f buf))"
using len_ge no_of j_less by unat_arith
have no_of': "unat offs < unat (offs + j)"
using no_of j_less j_nz by unat_arith
have len_app: "length (v1 @ v2) = unat k"
using len1 len2 j_less by unat_arith
have take_prefix: "(take (unat (offs + j))
(take (unat offs) (\<alpha>wa (data\<^sub>f buf)) @
v1 @ drop (unat (offs + j)) (\<alpha>wa (data\<^sub>f buf))))
= take (unat offs) (\<alpha>wa (data\<^sub>f buf)) @
v1"
using len1 no_of' len_ge' j_sub by simp
have drop_prefix: "drop (unat (offs + k))
(take (unat offs) (\<alpha>wa (data\<^sub>f buf)) @
v1 @ drop (unat (offs + j)) (\<alpha>wa (data\<^sub>f buf)))
= drop (unat (offs + k))(\<alpha>wa (data\<^sub>f buf))"
apply (subgoal_tac "(unat k - unat j + unat (offs + j)) = unat (offs + k)")
prefer 2
using no_of j_less apply unat_arith
using len1 len_ge' k_sub j_less no_of apply simp
by unat_arith
thus ?thesis
unfolding buf_sub_slice_def
using j_sub j_max k_j_sub k_sub k_max k_j_max apply (simp only: max_absorb1)
using len1
apply (subst take_append[where n="unat j"])+
apply (simp only: diff_self_eq_0 take_0 append_Nil2)
using len2 apply (subst take_append[where n="unat (k-j)"])+
apply (simp only: diff_self_eq_0 take_0 append_Nil2)
using len_app apply (subst take_append[where n="unat k"])
apply (simp only: diff_self_eq_0 take_0 append_Nil2)
using len1 k_j_sub apply (simp only:)
apply (simp only: xx wordarray_make fun_app_def)
using len1 len2 len_app apply (simp only: take_all[where n="unat j"]
take_all[where n="unat k"]
take_all[where n="unat (k-j)"])
using len1 len_ge len_ge' len_ge'' no_of' len_app no_of
by (simp add: buf_sub_slice_len_simplified take_prefix drop_prefix)
qed
lemma serialise_u8_ret':
notes wa_modify_ret = wordarray_modify_ret[rotated - 1, simplified Let_def]
assumes no_of: "offs < offs + 1"
and len_ge: "unat offs + 1 \<le> length (\<alpha>wa (data\<^sub>f buf))"
shows "serialise_u8 (buf, offs, v) =
buf \<lparr>data\<^sub>f := WordArrayT.make (buf_sub_slice buf offs (offs + 1) [v])\<rparr>"
proof -
have offs_sub: "(unat (offs + 1) - unat offs) = 1" using no_of by unat_arith
have no_of_unat: " unat offs < unat (offs + 1)" using no_of by (simp add: word_less_nat_alt)
show ?thesis
unfolding serialise_u8_def[unfolded sanitizers] Let_def
using no_of len_ge
apply simp
apply (rule wa_modify_ret[where index="offs" and varr="(data\<^sub>f buf)"])
prefer 2
apply (unat_arith)
apply (simp_all add:ArrA.defs ElemAO.defs ElemA.defs
setu8_def[unfolded tuple_simps sanitizers] wordarray_make buf_simps
min_absorb1 min_absorb2)
apply (rule arg_cong[where f="\<lambda>v. Buffer.data\<^sub>f_update v buf"])
apply (rule ext)
apply (rule arg_cong[where f="WordArrayT.make"])
apply (simp only: list_eq_iff_nth_eq)
apply (clarsimp simp: buf_sub_slice_length)
apply (simp add: buf_sub_slice_def min_absorb1 min_absorb2)
apply (case_tac "i=unat offs")
apply (simp only: append_assoc[symmetric] nth_append)
apply (simp add: min_absorb1 min_absorb2)
apply unat_arith
apply (case_tac "i < unat offs")
apply (simp add: min_absorb1 offs_sub max_absorb1 no_of no_of_unat nth_append)
apply (simp add: min_absorb1 offs_sub max_absorb1)
apply (subgoal_tac "(max (unat (offs + 1)) (unat offs)) = unat (offs + 1)")
prefer 2
using no_of_unat apply auto[1]
apply (clarsimp simp add: nth_append nth_Cons split: nat.splits)
apply (subst nth_drop)
apply unat_arith
apply (subgoal_tac "unat (offs + 1) = unat offs + 1")
prefer 2
using no_of_unat offs_sub apply simp
apply simp
apply (subgoal_tac "i = Suc (unat offs + x2)")
apply simp
apply unat_arith
done
qed
lemma serialise_ObjHeader_ret:
assumes no_overflow: "offs \<le> offs + bilbyFsObjHeaderSize"
and is_valid_obj: "is_valid_ObjHeader obj (drop (unat offs) (\<alpha>wa (data\<^sub>f buf)))"
and suc: "\<And>buf' offs'.
offs' = offs + bilbyFsObjHeaderSize \<Longrightarrow>
buf' = buf\<lparr>data\<^sub>f := WordArrayT.make (buf_sub_slice buf offs (offs +bilbyFsObjHeaderSize) (sObjHeader obj))\<rparr> \<Longrightarrow>
P (buf', offs')"
shows
"P (serialise_ObjHeader (buf, offs, obj))"
proof -
have offs_le_length: "unat offs \<le> length (\<alpha>wa (data\<^sub>f buf))"
using is_valid_ObjHeader_len_facts[OF is_valid_obj]
by (clarsimp simp: is_valid_ObjHeader_def bilbyFsObjHeaderSize_def) unat_arith
have offs_sub_le: "(unat (offs + bilbyFsObjHeaderSize) - unat offs) \<le> (length (\<alpha>wa (data\<^sub>f buf)) - unat offs)"
using is_valid_obj is_valid_ObjHeader_len_facts[OF is_valid_obj]
by (clarsimp simp: is_valid_ObjHeader_def bilbyFsObjHeaderSize_def) unat_arith
have offs_len_sub_eq: "unat (offs + bilbyFsObjHeaderSize) - unat offs = unat (bilbyFsObjHeaderSize)"
using no_overflow by unat_arith
have offs_obj_len_le_length: "unat (offs + bilbyFsObjHeaderSize) \<le> length (\<alpha>wa (data\<^sub>f buf))"
using is_valid_obj offs_sub_le is_valid_ObjHeader_len_facts[OF is_valid_obj]
by (clarsimp simp: is_valid_ObjHeader_def bilbyFsObjHeaderSize_def) unat_arith
have offs_obj_len_le_length': "(unat (offs + bilbyFsObjHeaderSize) -
(unat offs + unat bilbyFsObjHeaderSize)) \<le> (length (\<alpha>wa (data\<^sub>f buf)) -
(unat offs + unat bilbyFsObjHeaderSize))"
using offs_obj_len_le_length by unat_arith
have offs_plus_eq: " (unat (offs + bilbyFsObjHeaderSize) = (unat offs + unat bilbyFsObjHeaderSize))"
using no_overflow by unat_arith
show ?thesis
unfolding serialise_ObjHeader_def[unfolded sanitizers tuple_simps]
apply (simp add: Let_def)
apply (rule suc)
apply (simp add: bilbyFsObjHeaderSize_def)
apply (simp add: buf_sub_slice_def wordarray_make)
apply (simp add: min_absorb1 offs_le_length offs_sub_le)
apply (simp add: offs_len_sub_eq length_sObjHeader
offs_obj_len_le_length' offs_plus_eq)
using no_overflow apply (simp add: word_le_nat_alt max_absorb1 bilbyFsObjHeaderSize_def)
using no_overflow offs_obj_len_le_length apply (simp add: bilbyFsObjHeaderSize_def)
apply (subst serialise_le32_ret[where v="magic\<^sub>f obj"])
apply ((unat_arith, auto)+)[2]
apply (subst serialise_le32_ret[where v="crc\<^sub>f obj"])
apply ((unat_arith, auto)+)[1]
apply (simp add: buf_sub_slice_length wordarray_make)
apply (unat_arith, auto)[1]
apply (simp)
apply (subst add.commute[where a=8])
apply (subst buf_sub_slice_absorb[where offs=offs and j=4 and k=8, simplified])
apply (simp add: length_sle32)+
apply unat_arith
apply auto[1]
apply unat_arith
apply auto[1]
apply (subst serialise_le64_ret)
apply (unat_arith, auto)[1]
apply (simp add: buf_sub_slice_length wordarray_make)
apply (unat_arith, auto)[1]
apply simp
apply (subst add.commute[where a="0x10"])
apply (subst buf_sub_slice_absorb)
apply (simp add: length_sle32 length_sle64)+
apply ((unat_arith, auto)+)[2]
apply (subst serialise_le32_ret)
apply ((unat_arith, auto)+)[1]
apply (simp add: buf_sub_slice_length wordarray_make)
apply (unat_arith, auto)[1]
apply (simp)
apply (subst add.commute[where a="0x14"])
apply (subst buf_sub_slice_absorb)
apply (simp add: length_sle32 length_sle64)+
apply ((unat_arith, auto)+)[2]
apply (subst serialise_u8_ret'[where offs="offs + 0x14"])
apply (unat_arith, auto)[1]
apply (simp add: buf_sub_slice_length wordarray_make)
apply (unat_arith, auto)[1]
apply (simp)
apply (subst add.commute[where a="0x15"])
apply (subst buf_sub_slice_absorb)
apply (simp add: length_sle32 length_sle64)+
apply ((unat_arith, auto)+)[2]
apply (subst serialise_u8_ret'[where offs="offs + 0x15"])
apply (unat_arith, auto)[1]
apply (simp add: buf_sub_slice_length wordarray_make)
apply (unat_arith, auto)[1]
apply (simp)
apply (subst add.commute[where a="0x16"])
apply (subst buf_sub_slice_absorb)
apply (simp add: length_sle32 length_sle64)+
apply ((unat_arith, auto)+)[2]
apply (subst serialise_u8_ret'[where offs="offs + 0x16"])
apply (unat_arith, auto)[1]
apply (simp add: buf_sub_slice_length wordarray_make)
apply (unat_arith, auto)[1]
apply (simp)
apply (subst add.commute[where a="0x17"])
apply (subst buf_sub_slice_absorb)
apply (simp add: length_sle32 length_sle64)+
apply ((unat_arith, auto)+)[2]
apply (subst serialise_u8_ret'[where offs="offs + 0x17"])
apply (unat_arith, auto)[1]
apply (simp add: buf_sub_slice_length wordarray_make)
apply (unat_arith, auto)[1]
apply (simp)
apply (subst add.commute[where a="0x18"])
apply (subst buf_sub_slice_absorb)
apply (simp add: length_sle32 length_sle64)+
apply ((unat_arith, auto)+)[2]
apply (simp add: sObjHeader_def bilbyFsPadByte_def)
apply (unfold buf_sub_slice_def)
apply (simp add: offs_len_sub_eq[unfolded bilbyFsObjHeaderSize_def, simplified])
apply (simp add: length_sle32 length_sle64)
apply (subgoal_tac "(length (\<alpha>wa (data\<^sub>f buf)) - unat offs) \<ge> 24")
prefer 2
using offs_len_sub_eq bilbyFsObjHeaderSize_def apply (unat_arith, auto)[1]
apply simp
apply (subgoal_tac "(unat (offs + 0x18)) > (unat offs)")
prefer 2
using no_overflow apply (unat_arith, auto)[1]
apply (simp add: max_absorb1)
apply (rule arg_cong[where f="\<lambda>v. Buffer.data\<^sub>f_update v buf"])
apply (rule ext)
apply (rule arg_cong[where f="WordArrayT.make"])
apply simp
by (subst take_all,
( simp add: length_sle32 length_sle64 | (unat_arith, auto)[1] )+
)+
qed
lemmas ObjUnion_splits = ObjUnion.splits
lemma take_drop_decomp:"x \<ge> a \<Longrightarrow> take (x - a) (drop a xs) @ drop x xs = drop a xs"
by (metis drop_take drop_take_drop)
lemma serialise_ObjPad_ret:
assumes no_overflow: "offs \<le> offs + (olen - bilbyFsObjHeaderSize)"
and no_underflow: "olen - bilbyFsObjHeaderSize \<ge> 0"
and bound: "offs+ (olen - bilbyFsObjHeaderSize) \<le> bound\<^sub>f buf \<and> unat (bound\<^sub>f buf) \<le> length (\<alpha>wa (data\<^sub>f buf))"
and suc: "\<And>buf' offs'.
offs' = offs + olen - bilbyFsObjHeaderSize \<Longrightarrow>
buf' = buf\<lparr>data\<^sub>f := WordArrayT.make (buf_sub_slice buf offs (offs + (olen - bilbyFsObjHeaderSize)) (sObjPad olen))\<rparr> \<Longrightarrow>
P (buf', offs')"
shows
"P (serialise_ObjPad (buf, offs, olen))"
proof -
have offs_le_bound: "offs \<le> bound\<^sub>f buf"
using bound no_overflow by unat_arith
have sub1: "(unat (olen - 0x18)) \<le> (unat (bound\<^sub>f buf) - unat offs)"
using bound no_overflow no_underflow apply (clarsimp simp: bilbyFsObjHeaderSize_def)
by unat_arith
have sub2: "(unat (offs + (olen - 0x18)) - unat offs) = unat (olen - 0x18)"
using bound no_overflow no_underflow apply (clarsimp simp: bilbyFsObjHeaderSize_def)
by unat_arith (* takes ages *)
have sub3: "unat (olen - 0x18) \<le> (length (\<alpha>wa (data\<^sub>f buf)) - unat offs)"
using bound no_overflow no_underflow apply (clarsimp simp: bilbyFsObjHeaderSize_def)
by unat_arith
have sub4: "(unat (offs + (olen - 0x18)) - (unat offs + unat (olen - 0x18))) = 0"
using bound no_overflow no_underflow apply (clarsimp simp: bilbyFsObjHeaderSize_def)
by unat_arith
have sub5: "(unat offs +
(unat (olen - 0x18) + length (\<alpha>wa (data\<^sub>f buf))) -
unat (offs + (olen - 0x18))) = length (\<alpha>wa (data\<^sub>f buf))"
using bound no_overflow no_underflow apply (clarsimp simp: bilbyFsObjHeaderSize_def)
by unat_arith
have no_of_unat: "unat offs \<le> (unat (offs + (olen - 0x18)))"
using no_overflow no_underflow by (simp add: bilbyFsObjHeaderSize_def word_le_nat_alt)
have assoc: "(unat (offs + (olen - 0x18))) = unat offs + unat (olen - 0x18)"
using no_overflow no_underflow by (simp add: bilbyFsObjHeaderSize_def) unat_arith
show ?thesis
unfolding serialise_ObjPad_def[unfolded sanitizers tuple_simps]
apply (simp add: Let_def split: ObjUnion_splits)
apply (rule suc)
apply (simp add: bilbyFsObjHeaderSize_def)
apply (subst buf_memset_eq)
using bound apply simp
using no_overflow apply (simp add: bilbyFsObjHeaderSize_def)
apply (rule arg_cong[where f="\<lambda>v. Buffer.data\<^sub>f_update v buf"])
apply (rule ext)
apply (rule arg_cong[where f="WordArrayT.make"])
using bound offs_le_bound apply (clarsimp simp: buf_sub_slice_def bilbyFsObjHeaderSize_def)
apply (simp add: sObjPad_def bilbyFsPadByte_def buf_simps
min_absorb1 min_absorb2 word_le_nat_alt sub1 sub2 sub3 sub4 sub5
bilbyFsObjHeaderSize_def no_of_unat max_absorb1 assoc)
apply (subst take_drop_decomp)
using no_overflow no_underflow apply (clarsimp simp: bilbyFsObjHeaderSize_def)
apply simp
done
qed
lemma serialise_ObjUnion_ret:
assumes no_overflow: "offs \<le> offs + (olen - bilbyFsObjHeaderSize)"
and otype: "otype = bilbyFsObjTypePad"
and ounion: "\<And>v. ounion = TObjPad v"
and olen: " 0 \<le> olen - bilbyFsObjHeaderSize"
and bound: "offs + (olen - bilbyFsObjHeaderSize) \<le> bound\<^sub>f buf \<and> unat (bound\<^sub>f buf) \<le> length (\<alpha>wa (data\<^sub>f buf))"
and suc: "\<And>buf' offs'.
offs' = offs + olen - bilbyFsObjHeaderSize \<Longrightarrow>
buf' = buf\<lparr>data\<^sub>f := WordArrayT.make (buf_sub_slice buf offs (offs + (olen - bilbyFsObjHeaderSize)) (sObjUnion ounion otype olen))\<rparr> \<Longrightarrow>
P (buf', offs')"
shows
"P (serialise_ObjUnion (buf, offs, ounion, olen))"
unfolding serialise_ObjUnion_def[unfolded sanitizers tuple_simps]
using ounion apply (simp add: Let_def split: ObjUnion_splits)
apply (rule serialise_ObjPad_ret)
using no_overflow apply simp
using olen apply simp
using bound apply simp
apply (rule suc, simp)
apply (simp add: sObjUnion_def)
done
lemma data\<^sub>f_of_data\<^sub>f_update:
"data\<^sub>f (x\<lparr>data\<^sub>f := v\<rparr>) = v"
by simp
lemma serialise_Obj_ret:
assumes no_overflow: "offs \<le> offs + Obj.len\<^sub>f obj"
and is_valid_obj: "is_valid_ObjHeader obj (drop (unat offs) (\<alpha>wa (data\<^sub>f buf)))"
and otype: "otype\<^sub>f obj = bilbyFsObjTypePad"
and ounion: "\<And>v. ounion\<^sub>f obj = TObjPad v"
and bound: " offs + Obj.len\<^sub>f obj \<le> bound\<^sub>f buf \<and>
unat (bound\<^sub>f buf) \<le> length (\<alpha>wa (data\<^sub>f buf))"
and suc: "\<And>buf'.
buf' = buf\<lparr>data\<^sub>f := WordArrayT.make (buf_sub_slice buf offs (offs + Obj.len\<^sub>f obj) (sObj obj))\<rparr> \<Longrightarrow>
P (buf', offs + Obj.len\<^sub>f obj)"
shows
"P (serialise_Obj (buf, offs, obj))"
unfolding serialise_Obj_def[unfolded tuple_simps sanitizers]
apply (simp add: Let_def)
apply (rule serialise_ObjHeader_ret)
using no_overflow is_valid_obj apply (clarsimp simp: is_valid_ObjHeader_def bilbyFsObjHeaderSize_def)
apply (frule is_len_and_type_ok_hdr_szD, simp add: bilbyFsObjHeaderSize_def)
apply unat_arith
using is_valid_obj apply assumption
apply simp
apply (rule serialise_ObjUnion_ret)
using is_valid_obj no_overflow apply (clarsimp simp: is_valid_ObjHeader_def bilbyFsObjHeaderSize_def )
apply (frule is_len_and_type_ok_hdr_szD)
apply (simp add: bilbyFsObjHeaderSize_def)
apply unat_arith
apply (rule otype)
using ounion apply simp
using is_valid_obj no_overflow apply (clarsimp simp: is_valid_ObjHeader_def bilbyFsObjHeaderSize_def)
using bound apply (simp add: wordarray_make buf_sub_slice_length)
apply simp
apply (rule suc)
apply (rule arg_cong[where f="\<lambda>v. Buffer.data\<^sub>f_update v buf"])
apply (rule ext)
apply (rule arg_cong[where f="WordArrayT.make"])
apply (thin_tac x for x)+
apply (subst buf_sub_slice_absorb)
apply (simp add: length_sObjHeader)
apply (subst length_sObjUnion[OF ounion otype])
using is_valid_obj apply (clarsimp simp: is_valid_ObjHeader_def is_len_and_type_ok_hdr_szD)
using is_valid_obj no_overflow apply (clarsimp simp: is_valid_ObjHeader_def unat_plus_simple)
apply (drule is_len_and_type_ok_hdr_szD)
apply (unat_arith)
apply (simp add: is_len_and_type_ok_hdr_szD)
apply(simp add: bilbyFsObjHeaderSize_def)
using no_overflow is_valid_obj apply (clarsimp simp: is_valid_ObjHeader_def bilbyFsObjHeaderSize_def)
apply (simp add: is_len_and_type_ok_def otype otype_simps)
apply (unat_arith)
using bound is_valid_obj apply (clarsimp simp: is_valid_ObjHeader_def)
apply unat_arith
apply (simp add: sObj_def)
done
lemma binNot_NOT: "binNot (x::64 word) = NOT x"
unfolding binNot_def[unfolded Let_def]
by (rule subst[where s="-1"], fastforce, fastforce)
lemma deserialise_ObjDel_ret:
assumes bound: "unat offs + 8 \<le> length (\<alpha>wa $ data\<^sub>f buf)"
assumes err: "P (Error (eInval, ex))"
assumes offs: "offs < offs + 8"
assumes suc:
"\<And>obj offs'. \<lbrakk>
obj = pObjDel (\<alpha>wa $ data\<^sub>f buf) offs;
ObjDel.id\<^sub>f obj AND NOT bilbyFsOidMaskAll \<in>
{ bilbyFsOidMaskData, bilbyFsOidMaskInode,bilbyFsOidMaskDentarr};
offs' = offs + 8\<rbrakk> \<Longrightarrow>
P (Success (ex, obj, offs'))"
shows "P (deserialise_ObjDel (ex, buf, offs))"
proof -
have des_le64: "deserialise_le64 (buf, offs) = ple64 (\<alpha>wa $ data\<^sub>f buf) offs"
using bound offs
by (fastforce intro!: deserialise_le64_ret simp: unat_arith_simps)
show ?thesis
unfolding deserialise_ObjDel_def[unfolded tuple_simps sanitizers]
apply (clarsimp simp: Let_def err[simplified eInval_def])
by (fastforce
intro: suc
simp: Let_def binNot_NOT bilbyFsOidMaskData_def des_le64 bilbyFsOidMaskAll_def
bilbyFsOidMaskInode_def bilbyFsOidMaskDentarr_def pObjDel_def ObjDel.make_def)
qed
lemma deserialise_ObjInode_ret:
assumes bound: "unat offs + 60 \<le> length (\<alpha>wa $ data\<^sub>f buf)"
assumes offs: "offs < offs + 60"
assumes err: "\<And>ex e. e \<in> {eInval, eNoMem} \<Longrightarrow> P (Error (e, ex))"
assumes suc:
"\<And>ex oi offs'. \<lbrakk>
oi = pObjInode (\<alpha>wa (data\<^sub>f buf)) offs;
offs' = offs + 60\<rbrakk> \<Longrightarrow>
P (Success (ex, oi, offs'))"
shows "P (deserialise_ObjInode (ex, buf, offs))"
proof -
have des_le64:
"deserialise_le64 (buf, offs) = (ple64 (\<alpha>wa $ data\<^sub>f buf) offs)"
"deserialise_le64 (buf, offs + 8) = (ple64 (\<alpha>wa $ data\<^sub>f buf) (offs + 8))"
"deserialise_le64 (buf, offs + 16) = (ple64 (\<alpha>wa $ data\<^sub>f buf) (offs + 16))"
"deserialise_le64 (buf, offs + 24) = (ple64 (\<alpha>wa $ data\<^sub>f buf) (offs + 24))"
"deserialise_le64 (buf, offs + 32) = (ple64 (\<alpha>wa $ data\<^sub>f buf) (offs + 32))"
using bound offs
by - (simp,rule deserialise_le64_ret[simplified];
(simp add: unat_arith_simps, unat_arith?))+
have des_le32:
"deserialise_le32 (buf, offs + 40) = (ple32 (\<alpha>wa $ data\<^sub>f buf) (offs + 40))"
"deserialise_le32 (buf, offs + 44) = (ple32 (\<alpha>wa $ data\<^sub>f buf) (offs + 44))"
"deserialise_le32 (buf, offs + 48) = (ple32 (\<alpha>wa $ data\<^sub>f buf) (offs + 48))"
"deserialise_le32 (buf, offs + 52) = (ple32 (\<alpha>wa $ data\<^sub>f buf) (offs + 52))"
"deserialise_le32 (buf, offs + 56) = (ple32 (\<alpha>wa $ data\<^sub>f buf) (offs + 56))"
using bound offs
by - (simp,rule deserialise_le32_ret[simplified];
(simp add: unat_arith_simps, unat_arith?))+
show ?thesis
unfolding deserialise_ObjInode_def[unfolded tuple_simps sanitizers]
by (fastforce
intro: suc err
split: R.split
simp: eInval_def eNoMem_def binNot_NOT Let_def bilbyFsOidMaskAll_def des_le32
bilbyFsOidMaskInode_def word32Max_def pObjInode_def ObjInode.make_def des_le64)
qed
lemma deserialise_ObjSuper_ret:
assumes bound: "unat offs + 40 \<le> length (\<alpha>wa $ data\<^sub>f buf)"
assumes offs: "offs \<le> offs + 40" (* added by Yutaka on 11th.*)
assumes err: "\<And>ex. P (Error (eNoMem, ex))"
assumes suc:
"\<And>ex osup offs'. \<lbrakk>
osup = pObjSuper (\<alpha>wa (data\<^sub>f buf)) offs;
offs' = offs + 40\<rbrakk> \<Longrightarrow>
P (Success (ex, osup, offs'))"
shows "P (deserialise_ObjSuper (ex, buf, offs))"
proof -
have des_le64:
"deserialise_le64 (buf, offs + 32) = (ple64 (\<alpha>wa $ data\<^sub>f buf) (offs + 32))"
using bound offs
by - (simp,rule deserialise_le64_ret[simplified];
(simp add: unat_arith_simps, unat_arith?))
have des_le32:
"deserialise_le32 (buf, offs) = (ple32 (\<alpha>wa $ data\<^sub>f buf) offs)"
"deserialise_le32 (buf, offs + 4) = (ple32 (\<alpha>wa $ data\<^sub>f buf) (offs + 4))"
"deserialise_le32 (buf, offs + 8) = (ple32 (\<alpha>wa $ data\<^sub>f buf) (offs + 8))"
"deserialise_le32 (buf, offs + 12) = (ple32 (\<alpha>wa $ data\<^sub>f buf) (offs + 12))"
"deserialise_le32 (buf, offs + 16) = (ple32 (\<alpha>wa $ data\<^sub>f buf) (offs + 16))"
"deserialise_le32 (buf, offs + 20) = (ple32 (\<alpha>wa $ data\<^sub>f buf) (offs + 20))"
"deserialise_le32 (buf, offs + 24) = (ple32 (\<alpha>wa $ data\<^sub>f buf) (offs + 24))"
"deserialise_le32 (buf, offs + 28) = (ple32 (\<alpha>wa $ data\<^sub>f buf) (offs + 28))"
using bound offs
by - (simp,rule deserialise_le32_ret[simplified];
(simp add: unat_arith_simps, unat_arith?))+
show ?thesis
unfolding deserialise_ObjSuper_def[unfolded tuple_simps sanitizers]
by (fastforce
intro: suc err[unfolded eNoMem_def]
split: R.split
simp: pObjSuper_def ObjSuper.make_def des_le32 des_le64)
qed
lemma slice_Cons_helper:
"i < length xs \<Longrightarrow>
xs \<noteq> [] \<Longrightarrow>
drop i xs =
(xs ! i) # drop ( (i + 1)) xs"
apply (cases xs, simp_all)
by (metis (no_types, hide_lams) drop_Suc_Cons Cons_nth_drop_Suc length_Cons)
lemma slice_singleton:
"f < length xs \<Longrightarrow> slice f (Suc f) xs = [xs ! f]"
unfolding slice_def by (simp add:drop_take list_eq_iff_nth_eq)
lemma take_n_minus_1_append:
"0<n \<Longrightarrow> xs \<noteq> [] \<Longrightarrow> n \<le> length xs \<Longrightarrow>
take (n - Suc 0) xs @ [xs ! (n - Suc 0)] = take n xs"
apply (simp only: list_eq_iff_nth_eq)
apply clarsimp
apply (case_tac "(length xs) < (n - Suc 0)")
apply (clarsimp simp add: min_absorb2)+
by (metis One_nat_def Suc_pred' elem_take_n le0 le_less_trans diff_le_self
less_not_refl linorder_neqE_nat diff_Suc_less take_Suc_conv_app_nth)
lemma take_n_minus_1_append_eq:
"v = xs ! (unat (n - 1)) \<Longrightarrow> unat n \<le> length xs \<Longrightarrow> n> 0 \<Longrightarrow>
take (unat ((n::U32) - 1)) xs @ [v] = take (unat n) xs"
apply (simp add: list_eq_iff_nth_eq min_absorb2 unat_arith_simps)
apply clarsimp
apply (subst take_n_minus_1_append)
apply simp+
apply (case_tac xs, simp_all)
done
lemma slice_n_minus_1_append_last:
"unat acc + unat n \<le> length xs \<Longrightarrow>
(n::U32) > 0 \<Longrightarrow>
acc \<le> acc + n \<Longrightarrow>
slice (unat acc) (unat acc + unat (n - 1)) xs @
[xs ! unat (acc + (n - 1))] =
slice (unat acc) (unat acc + unat n) xs"
apply (simp add: slice_def list_eq_iff_nth_eq)
apply (subgoal_tac "(length xs) \<ge> (unat acc + unat (n - 1))")
prefer 2
apply unat_arith
apply (rule conjI)
apply (simp add: min_absorb1 min_absorb2)
apply (clarsimp simp: drop_take min_absorb1 min_absorb2 )
apply (subst take_n_minus_1_append_eq)
apply simp
apply (rule arg_cong[where f="nth xs"])
apply unat_arith (* takes long *)
apply simp+
done
lemma map_deserialise_waU8_map_eq_slice_apply:
assumes nonempty: "xs \<noteq> []"
assumes "length xs = unat (n:: 32 word)"
assumes n_gr_0: "n > 0"
assumes no_overflow: "acc \<le> acc + n"
assumes bound: "unat acc + length xs \<le> length (\<alpha>wa d)"
shows "
(mapAccumObs 0 (length xs) deserialise_waU8_map xs acc d) =
(FunBucket.slice (unat acc) (unat acc + (length xs)) (\<alpha>wa d), acc + n)"
using assms
apply (clarsimp simp: mapAccumObs_def ElemAO.make_def
deserialise_waU8_map_def[unfolded tuple_simps sanitizers] slice_def[where frm=0])
apply (induct "xs" arbitrary: n rule: rev_nonempty_induct)
apply (drule sym, simp add: slice_singleton wordarray_get_ret unat_arith_simps)
apply (drule_tac x="n - 1" in meta_spec)
apply (erule meta_impE)
apply unat_arith
apply (erule meta_impE)
apply (subgoal_tac "unat n \<ge> 2")
apply unat_arith
apply (case_tac xs, simp, simp)
apply (erule meta_impE)
apply unat_arith
apply (erule meta_impE)
apply unat_arith
apply (simp add: prod.case_eq_if)
apply (rule wordarray_get_ret')
apply unat_arith (* takes a while *)
apply (simp only: slice_n_minus_1_append_last)
done
lemma map_deserialise_waU8_map_eq_slice:
assumes n_gr_0: "n > 0"
assumes no_overflow: "acc \<le> acc + n"
assumes bound: "unat acc + unat n \<le> length (\<alpha>wa d)"
assumes "length xs = unat (n:: 32 word)"
shows "
prod.fst (mapAccumObs 0 (unat n) deserialise_waU8_map xs acc d) =
(FunBucket.slice (unat acc) (unat acc + unat n ) (\<alpha>wa d))"
using map_deserialise_waU8_map_eq_slice_apply[THEN arg_cong[where f=prod.fst]]
assms
by (subgoal_tac "xs \<noteq> []") (fastforce simp: unat_arith_simps)+
lemma deserialise_wordarray_U8_ret:
assumes err: "\<And>ex. P (Error (eNoMem, ex))"
assumes suc:
"\<And>ex wa.
offs \<le> offs + len \<longrightarrow> unat offs + unat len \<le> length (\<alpha>wa $ data\<^sub>f buf) \<longrightarrow>
wa = WordArrayT.make (slice (unat offs) (unat offs + unat len) (\<alpha>wa (data\<^sub>f buf))) \<Longrightarrow>
P (Success (ex, wa))"
shows "P (deserialise_wordarray_U8 (ex, buf, offs, len))"
unfolding deserialise_wordarray_U8_def[unfolded tuple_simps sanitizers]
apply (simp add: Let_def)
apply (rule wordarray_create_ret)
apply simp
apply (simp add: err[unfolded eNoMem_def])
apply (rename_tac ex' wa)
apply simp
apply (rule wordarray_copy_ret)
apply (simp add:Let_def prod.case_eq_if)
apply (rule suc)
apply clarsimp
done
lemma deserialise_ObjData_ret:
assumes offs_no_of: "offs \<le> offs + (olen - bilbyFsObjHeaderSize)"
assumes buf_len: "unat (offs + (olen - bilbyFsObjHeaderSize)) \<le> length (\<alpha>wa (data\<^sub>f buf))"
assumes olen: "is_len_and_type_ok (bilbyFsObjTypeData, olen)"
assumes err: "\<And>ex e. e \<in> {eInval, eNoMem} \<Longrightarrow> P (Error (e, ex))"
assumes suc:
"\<And>ex od offs' . \<lbrakk>
ObjData.id\<^sub>f od AND NOT bilbyFsOidMaskAll OR bilbyFsOidMaskData = ObjData.id\<^sub>f od;
od = pObjData (\<alpha>wa (data\<^sub>f buf)) offs olen;
offs' = offs + olen - bilbyFsObjHeaderSize\<rbrakk> \<Longrightarrow>
P (Success (ex, od, offs'))"
shows "P (deserialise_ObjData (ex, buf, offs, olen))"
proof -
have hdr_le_olen: "bilbyFsObjDataHeaderSize \<le> (olen - bilbyFsObjHeaderSize)"
using olen
by (simp add: is_len_and_type_ok_def[unfolded sanitizers tuple_simps] otype_simps
bilbyFsObjHeaderSize_def bilbyFsObjDataHeaderSize_def) unat_arith
have offs_pl_hdr_le_offs_pl_olen:
"offs + bilbyFsObjDataHeaderSize \<le> offs + (olen - bilbyFsObjHeaderSize)"
using hdr_le_olen offs_no_of
by (simp add: bilbyFsObjDataHeaderSize_def bilbyFsObjHeaderSize_def word_plus_mono_right)
have offs_pl_hdr_no_of:
"offs < offs + bilbyFsObjDataHeaderSize"
using offs_no_of hdr_le_olen
by (simp add: bilbyFsObjDataHeaderSize_def bilbyFsObjHeaderSize_def)
unat_arith
have offs_pl_hdr_le_buf_len:
"unat offs + unat bilbyFsObjDataHeaderSize \<le> length (\<alpha>wa (data\<^sub>f buf))"
using buf_len hdr_le_olen offs_pl_hdr_no_of offs_pl_hdr_le_offs_pl_olen
by (simp add: bilbyFsObjHeaderSize_def bilbyFsObjDataHeaderSize_def)
unat_arith
have unat_offs_pl_olen_etc_eq: "unat (offs + (olen - bilbyFsObjHeaderSize)) = unat (offs + 8) + unat (0xFFFFFFE0 + olen)"
using olen hdr_le_olen offs_pl_hdr_no_of offs_pl_hdr_le_offs_pl_olen
apply (simp add: bilbyFsObjHeaderSize_def bilbyFsObjDataHeaderSize_def)
apply (simp add: is_len_and_type_ok_def[unfolded sanitizers tuple_simps] otype_simps bilbyFsObjHeaderSize_def)
apply (subgoal_tac "unat (offs + (olen - 0x18)) = unat (offs + 8) + unat (olen - 0x18 - 8)")
apply unat_arith
apply (simp add: unat_arith_simps)
apply unat_arith
done
show ?thesis
unfolding deserialise_ObjData_def[unfolded tuple_simps sanitizers]
apply (clarsimp simp: Let_def err[unfolded eNoMem_def eInval_def] binNot_NOT)
apply (rule deserialise_wordarray_U8_ret)
apply (simp add: err)
apply (erule impE)
using offs_pl_hdr_no_of apply (simp add: bilbyFsObjHeaderSize_def bilbyFsObjDataHeaderSize_def add.commute add.assoc)
apply (subgoal_tac "olen + 0xFFFFFFE8 = olen - 0x18") (* Oh! Beloved words <3 *)
prefer 2
apply simp
apply (simp only:)
apply simp
using offs_pl_hdr_le_offs_pl_olen apply (simp add: bilbyFsObjHeaderSize_def bilbyFsObjDataHeaderSize_def )
apply simp
apply (rule suc)
apply simp
apply (simp add: bilbyFsOidMaskAll_def bilbyFsOidMaskData_def
pObjData_def ObjData.make_def bilbyFsObjHeaderSize_def)
apply (simp add: Let_def pObjData_def ObjData.make_def bilbyFsObjHeaderSize_def bilbyFsObjDataHeaderSize_def)
apply (subst deserialise_le64_ret)
using offs_pl_hdr_le_buf_len[simplified bilbyFsObjHeaderSize_def bilbyFsObjDataHeaderSize_def]
apply (simp add:)
using offs_pl_hdr_no_of
apply (simp add: bilbyFsObjDataHeaderSize_def)
apply (erule impE)
using buf_len unat_offs_pl_olen_etc_eq
apply simp
apply simp
apply (simp add: bilbyFsObjHeaderSize_def)
done
qed
lemma deserialise_ObjPad_ret:
assumes err: "P (Error (eInval, ex))"
assumes suc: "\<And> out offs' .
\<lbrakk> olen - bilbyFsObjHeaderSize \<le> olen ;
out=();
offs' = offs + (olen - bilbyFsObjHeaderSize) \<rbrakk> \<Longrightarrow>
P (Success (ex, out, offs'))"
shows "P (deserialise_ObjPad (ex, buf, offs, olen))"
unfolding deserialise_ObjPad_def[unfolded tuple_simps sanitizers]
by (auto simp: Let_def err[unfolded eInval_def] suc[unfolded bilbyFsObjHeaderSize_def] split: R.split)
lemma no_offs_overflow:
assumes wellformed_buf: "wellformed_buf buf"
assumes no_overflow: "length (\<alpha>wa $ data\<^sub>f buf) \<le> unat bilbyFsMaxEbSize"
assumes offs_bound: "offs \<le> (bound\<^sub>f buf)"
assumes "n < bilbyFsMaxEbSize"
assumes "m < bilbyFsMaxEbSize"
shows "offs + n \<le> offs + n + m"
using assms
by (auto simp add: bilbyFsMaxEbSize_def wellformed_buf_def unat_arith_simps)
lemma no_offs_overflow_le:
assumes wellformed_buf: "wellformed_buf buf"
assumes no_overflow: "length (\<alpha>wa $ data\<^sub>f buf) \<le> unat bilbyFsMaxEbSize"
assumes offs_bound: "offs \<le> (bound\<^sub>f buf)"
assumes "n < bilbyFsMaxEbSize"
assumes "m < bilbyFsMaxEbSize"
assumes "m > 0"
shows "offs + n < offs + n + m"
using assms
by (auto simp add: bilbyFsMaxEbSize_def wellformed_buf_def unat_arith_simps)
lemma conc_offs_no_of:
assumes wellformed_buf: "wellformed_buf buf"
assumes no_overflow: "length (\<alpha>wa $ data\<^sub>f buf) \<le> unat bilbyFsMaxEbSize"
assumes offs_bound: "offs \<le> (bound\<^sub>f buf)"
assumes "m < bilbyFsMaxEbSize"
assumes "m > 0"
shows "offs < offs + m"
using assms
by (auto simp add: bilbyFsMaxEbSize_def wellformed_buf_def unat_arith_simps)
lemma slice_take:
"m \<le> l \<Longrightarrow>
slice n m (take l xs) = slice n m xs"
by (simp add: slice_def)
lemma deserialise_pu8_ret:
assumes valid_offs:
"unat offs + 1 < length (\<alpha>wa $ data\<^sub>f buf)"
assumes no_of:
"offs < offs + 1"
shows
"deserialise_u8 (buf, offs) = (pu8 (\<alpha>wa $ data\<^sub>f buf) offs)"
proof -
from no_of have no_of': "offs \<le> offs + 1" by simp
hence offs_pl_1: "unat (offs + 1) = unat offs + 1" by (simp add: unat_plus_simple)
show ?thesis
using valid_offs
apply (clarsimp simp: wordarray_get_ret[where arr="data\<^sub>f buf"]
deserialise_u8_def pu8_def)
apply (rule trans, rule word_rcat_rsplit[symmetric])
apply (rule arg_cong[where f=word_rcat])
apply (subst word_rsplit_upt[where n=1], simp add: word_size)
apply (simp)
apply (simp add: slice_def)
apply (simp add: ucast_def)
apply (subst Cons_nth_drop_Suc[symmetric])
apply simp
apply simp
done
qed
lemma pu8_take:
assumes offs:"offs < offs+1"
assumes ntake:"unat (offs + 1) \<le> ntake"
shows "pu8 (take ntake ys) offs = pu8 ys offs"
apply (simp add: pu8_def)
apply (rule arg_cong[where f="word_rcat"])
apply (rule slice_take)
using ntake offs by unat_arith
lemma deserialise_ObjDentry_ret:
assumes wellformed_buf: "wellformed_buf buf"
assumes no_buf_overflow: "length (\<alpha>wa $ data\<^sub>f buf) \<le> unat bilbyFsMaxEbSize"
assumes bound: "end_offs \<le> bound\<^sub>f buf"
assumes off_less_end_offs: "offs \<le> end_offs"
assumes err:
"\<And>ex e. e \<in> {eInval, eNoMem} \<Longrightarrow> P (Error (e, ex))"
assumes suc:
"\<And>ex dentry offs'. \<lbrakk>
unat offs + 8 + unat (wordarray_length (name\<^sub>f dentry)) \<le> unat (bound\<^sub>f buf);
wordarray_length (name\<^sub>f dentry) \<le> bilbyFsMaxNameLen + 1;
offs + 8 + wordarray_length (name\<^sub>f dentry) \<le> end_offs ;
dentry = pObjDentry (take (unat end_offs) (\<alpha>wa (data\<^sub>f buf))) offs ;
offs' = offs + 8 + wordarray_length (name\<^sub>f dentry);
offs' \<le> (bound\<^sub>f buf)
\<rbrakk> \<Longrightarrow>
P (Success (ex, dentry, offs'))"
shows "P (deserialise_ObjDentry (ex, buf, offs, end_offs))"
proof -
{
fix ex' dentry offs'
assume des_suc: "unat offs + 8 \<le> unat (bound\<^sub>f buf)"
then have offs_ok:"\<forall>n\<in>{0..7}. unat (offs + n) < length (\<alpha>wa $ data\<^sub>f buf)"
proof -
from wellformed_buf[unfolded wellformed_buf_def] des_suc
have "unat offs + 8 \<le> length (\<alpha>wa $ data\<^sub>f buf)"
by unat_arith
thus ?thesis
by unat_arith
qed
from des_suc have deserialises:
"deserialise_le32 (buf, offs) = (ple32 (\<alpha>wa $ data\<^sub>f buf) offs)"
"deserialise_u8 (buf, offs + 4) = (pu8 (\<alpha>wa $ data\<^sub>f buf) (offs + 4))"
"deserialise_le16 (buf, offs + 6) = (ple16 (\<alpha>wa $ data\<^sub>f buf) (offs + 6))"
apply clarsimp
apply(rule deserialise_le32_ret[simplified])
using assms[simplified bilbyFsMaxEbSize_def wellformed_buf_def]
apply unat_arith
using assms[simplified bilbyFsMaxEbSize_def ]
apply unat_arith
apply (subst deserialise_pu8_ret)
using offs_ok des_suc wellformed_buf
apply (simp add: wellformed_buf_def, unat_arith)
using des_suc
apply unat_arith
apply simp+
apply(rule deserialise_le16_ret[simplified])
using offs_ok des_suc wellformed_buf apply (simp add: wellformed_buf_def, unat_arith)
using des_suc
apply unat_arith
done
}
note deserialises = this
have offs_le_bound: "offs \<le> bound\<^sub>f buf"
using off_less_end_offs bound by simp
have const_offs_no_of: "\<And>n. n < bilbyFsMaxEbSize \<Longrightarrow> 0 < n \<Longrightarrow> offs < offs + n"
apply (rule conc_offs_no_of[OF wellformed_buf no_buf_overflow, unfolded bilbyFsMaxEbSize_def, simplified])
using offs_le_bound by (simp add:bilbyFsMaxEbSize_def)+
note no_of_8 = no_offs_overflow[OF wellformed_buf no_buf_overflow offs_le_bound, where m=8 and n=0, unfolded bilbyFsMaxEbSize_def, simplified, simplified unat_plus_simple]
show ?thesis
unfolding deserialise_ObjDentry_def[simplified tuple_simps sanitizers]
apply (clarsimp simp: Let_def err[unfolded eNoMem_def eInval_def])
apply (subst (asm) not_less)+
apply (rule deserialise_wordarray_U8_ret)
apply (clarsimp simp add: err)
apply(clarsimp simp add: err eNoMem_def Let_def prod.case_eq_if split: R.splits)
apply (erule impE)
apply (rule no_offs_overflow[OF wellformed_buf no_buf_overflow])
using off_less_end_offs bound apply fastforce
apply (simp add: bilbyFsMaxEbSize_def)+
apply unat_arith
apply (subgoal_tac "unat offs + unat (8::32word) + unat (ucast (deserialise_le16 (buf, offs + 6))) \<le> unat end_offs")
prefer 2
apply (subst add.assoc)
apply (subst unat_plus_simple[THEN iffD1, symmetric])
apply (simp add: unat_arith_simps)
apply (subst unat_plus_simple[THEN iffD1, symmetric])
apply (rule no_offs_overflow[OF wellformed_buf no_buf_overflow, where n=0, simplified])
using off_less_end_offs bound apply fastforce
apply (simp add: bilbyFsMaxEbSize_def)+
apply (simp add: unat_arith_simps)
apply (simp add: word_le_nat_alt[symmetric] add.assoc)
apply (erule impE)
using bound wellformed_buf[unfolded wellformed_buf_def]
apply (simp add: unat_arith_simps)
apply unat_arith
apply (subgoal_tac "unat offs + 8 \<le> unat (bound\<^sub>f buf)")
prefer 2
apply (subst unat_plus_simple[THEN iffD1, symmetric,
where y="8::32word", simplified])
apply (rule no_offs_overflow[OF wellformed_buf no_buf_overflow,
where n=0, simplified])
using off_less_end_offs bound apply fastforce
apply (simp add: bilbyFsMaxEbSize_def)+
apply (subst word_le_nat_alt[symmetric])
apply (cut_tac no_offs_overflow[OF wellformed_buf no_buf_overflow,
where offs=offs and n=8 and m="ucast (deserialise_le16 (buf, offs + 6))"])
using off_less_end_offs bound apply (simp_all add: bilbyFsMaxEbSize_def)
apply unat_arith
apply (simp add: deserialises)
apply (subgoal_tac "wordarray_length (WordArrayT.make
(FunBucket.slice (unat (offs + 8))
(unat (offs + 8) + unat (ucast (ple16 (\<alpha>wa (data\<^sub>f buf)) (offs + 6)) :: 32 word))
(\<alpha>wa (data\<^sub>f buf)))) \<le> ucast (ple16 (\<alpha>wa (data\<^sub>f buf)) (offs + 6))")
prefer 2
apply (subst wordarray_length_ofnat)
apply (simp add: wordarray_length_ret)
apply (subst wordarray_make)
apply (simp add: slice_length)
apply (subst min_absorb1)
prefer 3
using wellformed_buf[unfolded wellformed_buf_def] no_buf_overflow[unfolded bilbyFsMaxEbSize_def]
apply (simp add: unat_arith_simps)
apply (subgoal_tac
"unat (ucast (ple16 (\<alpha>wa (data\<^sub>f buf)) (offs + 6)) :: 32 word) =
unat (ple16 (\<alpha>wa (data\<^sub>f buf)) (offs + 6))")
prefer 2
apply (fastforce intro: uint_up_ucast simp: eq_nat_nat_iff unat_def is_up)
apply (rule suc)
apply (simp_all add: Let_def pObjDentry_def ObjDentry.make_def bilbyFsMaxNameLen_def)
using bound apply unat_arith
using wellformed_buf[unfolded wellformed_buf_def] no_buf_overflow[unfolded bilbyFsMaxEbSize_def]
apply (simp add: unat_arith_simps)
apply (simp add: ple16_take ple32_take const_offs_no_of bilbyFsMaxEbSize_def plus_no_overflow_unat_lift[OF const_offs_no_of[unfolded bilbyFsMaxEbSize_def, simplified]])
apply (subst ple16_take)
apply (rule no_offs_overflow_le[OF wellformed_buf no_buf_overflow offs_le_bound])
apply (simp add: bilbyFsMaxEbSize_def)+
using no_of_8
apply (simp add: add.commute)
apply (subst ple16_take)
apply (rule no_offs_overflow_le[OF wellformed_buf no_buf_overflow offs_le_bound])
apply (simp add: bilbyFsMaxEbSize_def)+
using no_of_8
apply (simp add: add.commute)
apply (subst pu8_take)
using no_offs_overflow[OF wellformed_buf no_buf_overflow offs_le_bound, where m=5 and n=0, unfolded bilbyFsMaxEbSize_def, simplified]
no_offs_overflow[OF wellformed_buf no_buf_overflow offs_le_bound, where m=4 and n=0, unfolded bilbyFsMaxEbSize_def, simplified]
apply (simp add: add.commute unat_plus_simple)
apply unat_arith
using no_of_8
no_offs_overflow[OF wellformed_buf no_buf_overflow offs_le_bound, where m=5 and n=0, unfolded bilbyFsMaxEbSize_def, simplified]
apply (fastforce simp add: unat_plus_simple add.commute)
apply (subst ObjDentry.surjective, simp)
apply (rule arg_cong[where f=WordArrayT.make])
apply (rule slice_take[symmetric], simp)
apply (rule word_unat.Rep_eqD)
apply (simp add: wordarray_length_ret wordarray_make length_slice)
using no_of_8 wellformed_buf
apply (simp add: wellformed_buf_def)
apply unat_arith
using wellformed_buf[unfolded wellformed_buf_def] no_buf_overflow[unfolded bilbyFsMaxEbSize_def]
apply (simp add: unat_arith_simps)
done
qed
lemma loop_deserialise_ObjDentry_ret:
assumes wellformed_buf: "wellformed_buf buf"
assumes no_buf_overflow: "length (\<alpha>wa $ data\<^sub>f buf) \<le> unat bilbyFsMaxEbSize"
assumes bound: "end_offs \<le> bound\<^sub>f buf"
assumes off_less_end_offs: "offs \<le> end_offs"
assumes st_offs: "st_offs \<le> offs"
shows "case loop_deserialise_ObjDentry (OptElemAO.make dentry (ex, offs) (buf, end_offs)) of
Break (none, e, ex) \<Rightarrow> none= Option.None () \<and> e = eInval
| Iterate (optdentry, ex, offs') \<Rightarrow>
\<exists>dentry. optdentry = Option.Some dentry \<and>
unat offs + 8 + unat (wordarray_length (name\<^sub>f dentry)) \<le> unat (bound\<^sub>f buf) \<and>
wordarray_length (name\<^sub>f dentry) \<le> bilbyFsMaxNameLen + 1 \<and>
offs + 8 + wordarray_length (name\<^sub>f dentry) \<le> end_offs \<and>
dentry = pObjDentry (take (unat end_offs) (\<alpha>wa (data\<^sub>f buf))) offs \<and>
offs' = offs + 8 + wordarray_length (name\<^sub>f dentry) \<and>
offs' \<le> (bound\<^sub>f buf)"
unfolding loop_deserialise_ObjDentry_def[unfolded tuple_simps sanitizers]
apply (clarsimp simp: Let_def OptElemAO.make_def)
apply (rule deserialise_ObjDentry_ret[OF assms(1-4)])
by (clarsimp simp: eInval_def)+
lemma slice_Cons:
"frm < length xs \<Longrightarrow> frm < to
\<Longrightarrow> slice frm to xs = xs ! frm # slice (Suc frm) to xs"
apply (simp add: slice_def)
apply (subst slice_Cons_helper[where i=frm], simp_all)
apply clarsimp
done
lemma slice_list_update:
"n < length xs
\<Longrightarrow> slice i j (xs[n := x]) = (if n < i then slice i j xs
else if n \<ge> j then slice i j xs
else (slice i j xs)[n - i := x])"
by (simp add: slice_def drop_list_update take_list_update)
lemma mapAccumObsOpt_step:
assumes frm: "frm < to" "frm < length xs"
shows "mapAccumObsOpt frm to fn xs vacc obs =
(case fn (OptElemAO.make (xs ! frm) vacc obs)
of Iterate (oelem, acc) \<Rightarrow>
mapAccumObsOpt (Suc frm) to fn (xs [frm := oelem]) acc obs
| Break (oelem, d) \<Rightarrow> Break (xs [frm := oelem], d))"
proof -
let ?folder = "(\<lambda>elem. case_LoopResult (\<lambda>(ys, d). Break (ys @ [elem], d))
(\<lambda>(ys, acc).
case fn (OptElemAO.make elem acc obs) of
Break (oelem, d) \<Rightarrow> Break (ys @ [oelem], d)
| Iterate (oelem, acc) \<Rightarrow> Iterate (ys @ [oelem], acc)))"
{ fix xs ys d
have fold_break: "fold ?folder xs (Break (ys, d))
= Break (ys @ xs, d)"
by (induct xs arbitrary: ys d, simp_all)
}
note fold_break = this
have fold_iterate_Cons: "\<And>xs. \<forall>y ys acc. fold ?folder xs (Iterate (y # ys, acc))
= (case (fold ?folder xs (Iterate (ys, acc)))
of Iterate (zs, acc) \<Rightarrow> Iterate (y # zs, acc)
| Break (zs, d) \<Rightarrow> Break (y # zs, d))"
apply (induct_tac xs, simp_all)
apply clarsimp
apply (case_tac "fn (OptElemAO.make a acc obs)")
apply (clarsimp simp add: fold_break)
apply clarsimp
done
from frm have drop_helper: "\<And>x xs. drop (to - frm) (x # xs) = drop (to - Suc frm) xs"
apply (cases "to - frm", simp_all)
apply (cases to, simp_all)
apply (cases frm, simp_all)
apply (metis Suc_diff_Suc Suc_inject)
done
show ?thesis using frm
apply (simp add: mapAccumObsOpt_def)
apply (simp add: slice_Cons)
apply (cases "fn (OptElemAO.make (xs ! frm) vacc obs)")
apply (clarsimp simp: fold_break)
apply (simp add: slice_def upd_conv_take_nth_drop max_absorb2)
apply (subst append_take_drop_id
[where xs="drop (Suc frm) xs" and n="to -frm - 1",
simplified take_drop, symmetric])
apply simp
apply (clarsimp simp: mapAccumObsOpt_def slice_list_update take_list_update)
apply (simp add: fold_iterate_Cons)
apply (simp split: LoopResult.split)
apply (clarsimp simp: slice_def upd_conv_take_nth_drop min_absorb2 max_absorb2
drop_helper)
done
qed
lemma mapAccumObsOpt_n_n:
"mapAccumObsOpt n n fn xs vacc obs = Iterate (xs, vacc)"
by (clarsimp simp: mapAccumObsOpt_def slice_n_n)
lemma mapAccumObsOpt_frm_eq_len:
"frm = length xs \<Longrightarrow> mapAccumObsOpt frm to fn xs vacc obs = Iterate (xs @ [], vacc)"
by (clarsimp simp: mapAccumObsOpt_def slice_def)
lemma snd_fold_simp:
"prod.snd (fold (\<lambda>_ (a, b). (f a b, f' b)) xs (a,b)) =
fold (\<lambda>_ b. f' b) xs b"
by (induct xs arbitrary: a b, simp_all)
lemma fst_fold_append_simp:
"prod.fst (fold (\<lambda>_ (xs, n). (xs @ [f n], f' n)) ls (f n' # xs, f' n)) =
f n' # prod.fst (fold (\<lambda>_ (xs, n). (xs @ [f n], f' n)) ls (xs, f' n)) "
by (induct ls arbitrary: n xs, simp_all)
lemma snd_snd_fold_simp:
"(prod.snd (fold (\<lambda>_ (xs, doffs, offslist). (f xs doffs, f' doffs, f'' doffs offslist)) ls (xs, n, offslist))) =
fold (\<lambda>_ (doffs, offslist). (f' doffs, f'' doffs offslist)) ls (n, offslist)"
by (induct ls arbitrary: xs n offslist, simp_all)
lemma snd_fold_append_gen_simp:
"prod.snd (fold (\<lambda>_ (x, xs). (f' x, xs @ [f x])) ls (x, xs @ ys)) =
xs @ prod.snd (fold (\<lambda>_ (x, xs). (f' x, xs @ [f x])) ls (x, ys))"
by (induct ls arbitrary: x ys, simp_all)
lemma snd_fold_append_simp:
"prod.snd (fold (\<lambda>_ (x, xs). (f' x, xs @ [f x])) ls (x, xs)) =
xs @ prod.snd (fold (\<lambda>_ (x, xs). (f' x, xs @ [f x])) ls (x, []))"
using snd_fold_append_gen_simp[where ys=Nil, simplified] .
lemma fst_fold_triple_simp:
"prod.fst (fold (\<lambda>_ (a, b, c). (f a b, f' b, f'' b c)) ns (a, b, c)) =
prod.fst (fold (\<lambda>_ (a, b). (f a b, f' b)) ns (a, b))"
by (induct ns arbitrary: a b c, simp_all)
lemma fst_snd_fold_triple_simp:
"prod.fst (prod.snd (fold (\<lambda>_ (a, b, c). (f a b, f' b, f'' b c)) ns (a, b, c))) =
prod.snd (fold (\<lambda>_ (a, b). (f a b, f' b)) ns (a, b))"
by (induct ns arbitrary: a b c, simp_all)
definition dentarr_offs_list_drop :: "U8 list \<Rightarrow> U32 \<Rightarrow> nat list \<Rightarrow> U32 \<Rightarrow> (32 word list)"
where
"dentarr_offs_list_drop data ost entriesno offs =
prod.snd (fold (\<lambda>_ (doffs, offslist).
let dentry = pObjDentry (drop (unat offs) data) (doffs - offs);
newoffs = doffs + 8 + wordarray_length (ObjDentry.name\<^sub>f dentry)
in (newoffs, offslist @ [newoffs]))
entriesno (ost, []))
"
definition
dentarr_offs_list_drop_end_offs_pred
where
"dentarr_offs_list_drop_end_offs_pred data ost entriesno offs end_offs \<equiv>
\<forall>v\<in>set (dentarr_offs_list_drop data ost entriesno offs).
v \<le> end_offs"
definition
"dentarr_offs_list data ost entriesno \<equiv>
(prod.snd (fold (\<lambda>_ (doffs, offslist).
let dentry = pObjDentry data doffs;
newoffs = doffs + 8 + wordarray_length (ObjDentry.name\<^sub>f dentry)
in (newoffs, offslist @ [newoffs]))
entriesno (ost, [])))"
definition
dentarr_offs_list_end_offs_pred
where
"dentarr_offs_list_end_offs_pred data ost entriesno end_offs \<equiv>
\<forall>v\<in>set (dentarr_offs_list data ost entriesno).
v \<le> end_offs"
definition
dentarr_otype_end_offs_pred
where
"dentarr_otype_end_offs_pred otype data offs end_offs \<equiv>
(otype = bilbyFsObjTypeDentarr \<longrightarrow>
(let nbentry = ple32 data (offs + 8)
in dentarr_offs_list_end_offs_pred data (offs+bilbyFsObjDentarrHeaderSize) [0..<unat nbentry] end_offs))"
lemmas dentarr_end_offs_simps = dentarr_offs_list_def dentarr_offs_list_end_offs_pred_def
dentarr_otype_end_offs_pred_def
definition
dentarr_otype_drop_end_offs_pred
where
"dentarr_otype_drop_end_offs_pred otype data offs end_offs \<equiv>
(otype = bilbyFsObjTypeDentarr \<longrightarrow>
(let nbentry = ple32 data (offs+8)
in dentarr_offs_list_drop_end_offs_pred data (offs+bilbyFsObjDentarrHeaderSize)
[0..<unat nbentry] offs end_offs))
"
definition
dentarr_otype_drop_end_offs_st_pred
where
"dentarr_otype_drop_end_offs_st_pred otype data offs st_offs end_offs \<equiv>
(otype = bilbyFsObjTypeDentarr \<longrightarrow>
(let nbentry = ple32 data (offs+8)
in dentarr_offs_list_drop_end_offs_pred data (offs+bilbyFsObjDentarrHeaderSize)
[0..<unat nbentry] st_offs end_offs))
"
lemmas dentarr_drop_end_offs_simps = dentarr_offs_list_drop_def dentarr_offs_list_drop_end_offs_pred_def
dentarr_otype_drop_end_offs_pred_def dentarr_otype_drop_end_offs_st_pred_def
lemma ple32_eq_slice:
assumes "offs < offs + 4"
assumes "unat offs + 4 \<le> length xs"
assumes "offs + 4 < end_offs"
shows "ple32 xs offs = ple32 (slice (unat offs) (unat end_offs) xs) 0"
using assms
apply (simp add: slice_def ple32_def drop_take word_add_eq_unat)
apply (drule less_to_le, simp add: unat_plus_simple word_less_nat_alt)
done
lemma split_upt_on_l_n:
"n < m \<Longrightarrow> l \<le> n \<Longrightarrow> [l ..< m] = [l ..< n] @ [n] @ [Suc n ..< m]"
apply (subst upt_add_eq_append')
apply simp+
apply (simp add: upt_conv_Cons)
done
lemma unat_plus_simple_imp:
"x \<le> (x::'a::len word) + y \<Longrightarrow> (unat (x + y) = unat x + unat y)"
by (simp add: unat_plus_simple)
lemma pObjDentry_drop_eq:
assumes offs_le_ost: "offs \<le> ost"
and ost_no_of8: " ost < ost + 8"
and ost_le_offs_olen: " ost \<le> end_offs"
and offs_olen_ys: "unat end_offs \<le> length ys"
and ys_le_max: " length ys \<le> unat bilbyFsMaxEbSize"
and end_offs: "end_offs_nat = unat end_offs"
shows " pObjDentry (take end_offs_nat ys) ost = pObjDentry (drop (unat offs) (take end_offs_nat ys)) (ost - offs)"
proof -
have ost_4_nat: "unat (ost + 4) = unat ost + 4"
using ost_no_of8 by (simp add: unat_arith_simps) unat_arith
have ost_le_max: "ost \<le> bilbyFsMaxEbSize" using ys_le_max offs_olen_ys ost_le_offs_olen
by unat_arith
hence offs_le_max: "offs \<le> bilbyFsMaxEbSize"
using offs_le_ost by unat_arith
have ost_minus_offs_bound: "ost - offs \<le> bilbyFsMaxEbSize"
using offs_le_ost ost_le_max
by unat_arith
have ost_no_ofs: "ost < ost + 4" "ost < ost + 6" using ost_no_of8
by (clarsimp simp add: unat_arith_simps , unat_arith)+
hence ost_offs_x: "unat (ost - offs + 4) = unat ost - unat offs + 4"
"unat (ost - offs + 6) = unat ost - unat offs + 6"
"unat (ost - offs + 8) = unat ost - unat offs + 8"
using offs_le_ost offs_le_ost[simplified word_le_nat_alt] ost_4_nat
ost_minus_offs_bound
apply (simp_all add: bilbyFsMaxEbSize_def)
apply ((drule plus_no_overflow_unat_lift)+,
(subst unat_plus_simple_imp,
simp only: word_le_nat_alt, unat_arith,subst unat_sub, simp+))
apply ((drule plus_no_overflow_unat_lift)+,
(subst unat_plus_simple_imp,
simp only: word_le_nat_alt, unat_arith,subst unat_sub, simp+))
apply ((drule plus_no_overflow_unat_lift)+)
apply (subst unat_plus_simple_imp)
apply (simp only: word_le_nat_alt word_less_nat_alt)
using offs_le_max[simplified bilbyFsMaxEbSize_def word_le_nat_alt]
ost_no_of8
apply (simp only:unat_arith_simps)
apply unat_arith
apply (subst unat_sub, simp+)
done
have offs_cancel: "(unat ost - unat offs + 4 + unat offs) = unat ost + 4"
"(unat ost - unat offs + 6 + unat offs) = unat ost + 6"
"(unat ost - unat offs + 8 + unat offs) = unat ost + 8"
using offs_le_ost[simplified word_less_nat_alt] by unat_arith+
have ple16_eq: "ple16 (take end_offs_nat ys) (ost + 6) = ple16 (drop (unat offs) (take end_offs_nat ys)) (ost - offs + 6)"
apply (simp add: ple16_def)
apply (rule arg_cong[where f=word_rcat])
apply (rule arg_cong[where f=rev])
apply (rule arg_cong[where f="take 2"])
apply (fastforce simp add: ost_offs_x offs_cancel less_to_le[OF ost_no_ofs(2), simplified unat_plus_simple])
done
have offs_cancel': "\<forall>v. unat ost - unat offs + 8 + unat v + unat offs = unat ost + 8 + unat v"
using offs_le_ost[simplified word_less_nat_alt]
by unat_arith
show ?thesis
apply (simp add: pObjDentry_def Let_def ObjDentry.make_def)
apply (rule conjI)
apply (simp add: ple32_def)
apply (rule arg_cong[where f=word_rcat])
apply (rule arg_cong[where f=rev])
apply (rule arg_cong[where f="take 4"])
apply (subst unat_sub[OF offs_le_ost])
using offs_le_ost
apply (subst add_diff_assoc2, fastforce simp: word_le_nat_alt)
apply fastforce
apply (rule conjI)
apply (simp add: pu8_def )
apply (rule arg_cong[where f=word_rcat])
apply (simp only: slice_def drop_take fun_app_def)
using ost_offs_x ost_4_nat
apply simp
apply (simp add: take_drop offs_cancel)
apply (subst add.commute, fastforce simp only: offs_cancel)
apply (simp add: ple16_eq )
apply (rule arg_cong[where f=WordArrayT.make])
apply (subgoal_tac "\<exists>v. ple16 (drop (unat offs) (take (unat offs + unat (Obj.len\<^sub>f obj)) ys)) (ost - offs + 6) = v")
apply (erule exE)
apply (simp only: ost_offs_x less_to_le[OF ost_no_of8, simplified unat_plus_simple])
apply (simp add: slice_def take_drop )
apply (simp add: offs_cancel offs_cancel')+
done
qed
lemma wa_length_ObjDentry_name_le:
"unat (wordarray_length (ObjDentry.name\<^sub>f (pObjDentry xs ost))) \<le> length xs"
by (simp add: pObjDentry_def Let_def ObjDentry.make_def wordarray_make wordarray_length_ret slice_def)
lemma wa_length_ObjDentry_name_le_len:
"unat (wordarray_length (ObjDentry.name\<^sub>f (pObjDentry xs ost))) \<le> unat (ple16 xs (ost + 6))"
by (simp add: pObjDentry_def Let_def ObjDentry.make_def wordarray_make wordarray_length_ret slice_def)
lemma dentarr_end_offs_list_induct_helper:
assumes diff: "Suc diff = unat to - frm"
and ih: "dentarr_offs_list_end_offs_pred (take (unat end_offs) (\<alpha>wa (data\<^sub>f buf))) (offs + 8 +
wordarray_length
(ObjDentry.name\<^sub>f (pObjDentry (take (unat end_offs) (\<alpha>wa (data\<^sub>f buf))) offs)))
[Suc frm..<unat to] end_offs"
and cur: " offs + 8 +
wordarray_length (ObjDentry.name\<^sub>f (pObjDentry (take (unat end_offs) (\<alpha>wa (data\<^sub>f buf))) offs))
\<le> end_offs"
shows
"dentarr_offs_list_end_offs_pred (take (unat end_offs) (\<alpha>wa (data\<^sub>f buf))) offs [frm..<unat to] end_offs"
proof -
have frm_lt_to: "frm < unat to" using diff by unat_arith
show ?thesis
apply (clarsimp simp: dentarr_end_offs_simps )
apply (subst (asm) upt_rec, simp add: frm_lt_to Let_def)
apply (subst (asm) snd_fold_append_simp)
apply clarsimp
apply (erule disjE)
using cur apply simp
using ih apply (simp add: dentarr_end_offs_simps Let_def)
done
qed
lemma offs_pl_8_name_of:
" wellformed_buf buf \<Longrightarrow>
length (\<alpha>wa $ data\<^sub>f buf) \<le> unat bilbyFsMaxEbSize \<Longrightarrow>
offs + 8 + wordarray_length (ObjDentry.name\<^sub>f (pObjDentry (take (unat end_offs) (\<alpha>wa (data\<^sub>f buf))) offs)) \<le> bound\<^sub>f buf \<Longrightarrow>
offs \<le> bilbyFsMaxEbSize \<Longrightarrow>
offs < offs + 8"
apply (simp add: bilbyFsMaxEbSize_def)
using wa_length_ObjDentry_name_le[where xs="(take (unat end_offs) (\<alpha>wa (data\<^sub>f buf)))" and ost=offs]
apply (clarsimp simp add: wellformed_buf_def)
apply (simp add: unat_arith_simps)
done
lemma mapAccumObsOpt_loop_deserialise_ObjDentry_ret:
assumes wellformed_buf: "wellformed_buf buf"
assumes no_buf_overflow: "length (\<alpha>wa $ data\<^sub>f buf) \<le> unat bilbyFsMaxEbSize"
assumes bound: "end_offs \<le> bound\<^sub>f buf"
assumes off_less_end_offs: "offs \<le> end_offs"
assumes frm: "frm \<le> unat (to::word32)" "unat to \<le> length ys"
assumes st_offs: "st_offs \<le> offs"
shows
"let list_spec =
case (fold (\<lambda>_ (xs, doffs, offslist).
let dentry = pObjDentry (take (unat end_offs) (\<alpha>wa (data\<^sub>f buf))) doffs ;
newoffs = doffs + 8 + wordarray_length (ObjDentry.name\<^sub>f dentry)
in (xs@[Option.Some dentry],
newoffs, offslist @ [newoffs]))
[frm..<unat to] ([], offs, []))
of (xs, offs) \<Rightarrow> ((take frm ys) @ xs @ (drop (unat to) ys), offs);
data = take (unat end_offs) (\<alpha>wa (data\<^sub>f buf)) in
(case mapAccumObsOpt frm (unat to) loop_deserialise_ObjDentry
ys (ex, offs) (buf, end_offs) of
Break (ys, d, ex) \<Rightarrow>
d \<in> {eInval, eNoMem}
| Iterate (ys, ex, offs') \<Rightarrow>
(ys, ex, offs') = (prod.fst list_spec, ex, prod.fst (prod.snd list_spec)) \<and>
offs' \<le> end_offs \<and>
dentarr_offs_list_end_offs_pred data offs [frm..<unat to] end_offs \<and>
dentarr_offs_list_drop_end_offs_pred data offs [frm..<unat to] st_offs end_offs)"
using assms
proof (induct "unat to - frm" arbitrary: frm ys ex offs)
case 0
thus ?case
by (simp add: dentarr_end_offs_simps mapAccumObsOpt_n_n dentarr_drop_end_offs_simps)
next
case (Suc diff)
note IH = this(1) and rest = this(2-)
have offs_le_max: "offs \<le> bilbyFsMaxEbSize"
using rest by (simp add: unat_arith_simps wellformed_buf_def)
hence offs_pl_8: "offs < offs + 8"
by (simp add: bilbyFsMaxEbSize_def unat_arith_simps)
have offs_pl_8_pl_name:
"offs + 8 \<le> offs + 8 + wordarray_length (ObjDentry.name\<^sub>f (pObjDentry (take (unat end_offs) (\<alpha>wa (data\<^sub>f buf))) offs))"
using wa_length_ObjDentry_name_le[where xs="take (unat end_offs) (\<alpha>wa (data\<^sub>f buf))" and ost=offs] rest offs_le_max
less_to_le[OF offs_pl_8]
by (simp add: wellformed_buf_def bilbyFsMaxEbSize_def unat_arith_simps)
have pObjDentry_eq:
"pObjDentry (drop (unat st_offs) (take (unat end_offs) (\<alpha>wa (data\<^sub>f buf)))) (offs - st_offs) = pObjDentry (take (unat end_offs) (\<alpha>wa (data\<^sub>f buf))) offs"
using rest offs_pl_8 by (fastforce intro: pObjDentry_drop_eq[symmetric,where end_offs=end_offs and offs=st_offs]
simp add: wellformed_buf_def word_le_nat_alt)
from rest show ?case
apply (subst mapAccumObsOpt_step, simp, simp)
apply (clarsimp simp: Let_def split: LoopResult.split)
apply (rule conjI)
using loop_deserialise_ObjDentry_ret[OF wellformed_buf no_buf_overflow bound ,
where dentry="ys ! frm" and ex = ex and offs=offs]
apply fastforce
apply clarsimp
apply (rename_tac elem ex' offs')
apply (cut_tac
frm="Suc frm" and
ys= "ys[frm := elem]" and
ex =ex' and offs = offs' in IH[OF _ wellformed_buf no_buf_overflow bound], simp_all)
apply(cut_tac loop_deserialise_ObjDentry_ret[OF wellformed_buf no_buf_overflow bound ,
where dentry="ys ! frm" and ex = ex and offs=offs and st_offs=st_offs], simp_all)
apply(cut_tac loop_deserialise_ObjDentry_ret[OF wellformed_buf no_buf_overflow bound ,
where dentry="ys ! frm" and ex = ex and offs=offs and st_offs=st_offs], simp_all)
apply clarsimp
using offs_pl_8_pl_name less_to_le[OF offs_pl_8]
apply (fastforce simp add: unat_plus_simple word_le_nat_alt)
apply (clarsimp simp: Let_def)
apply (rule conjI)
apply fastforce
apply (clarsimp simp: Let_def)
apply (rename_tac ex'')
apply (thin_tac "mapAccumObsOpt _ _ _ _ _ _ = _")
apply(cut_tac loop_deserialise_ObjDentry_ret[OF wellformed_buf no_buf_overflow bound,
where dentry="ys ! frm" and ex = ex and offs=offs], simp_all)
apply (clarsimp simp: Let_def fst_fold_triple_simp fst_snd_fold_triple_simp prod.case_eq_if)
apply (rule conjI)
apply (simp add: upt_conv_Cons[where i = frm])
apply (subst take_Suc_conv_app_nth, simp)
apply (simp add: take_list_update prod.case_eq_if snd_fold_simp)
apply (subst fst_fold_append_simp[where xs="[]", simplified, symmetric])
apply fastforce
apply (rule conjI)
apply (simp add: snd_fold_simp)
apply (case_tac "[frm..<unat to]")
apply (fastforce+)
apply (rename_tac l ls)
apply (subgoal_tac "[Suc frm..<unat to] = ls")
prefer 2
apply (subst (asm) upt_rec[where i=frm], case_tac "frm = unat to"; fastforce)
apply simp
apply (rule conjI)
apply (erule (2) dentarr_end_offs_list_induct_helper)
apply (simp add: dentarr_offs_list_drop_end_offs_pred_def)
apply clarsimp
apply (rename_tac offs')
apply (simp add: snd_fold_simp)
apply (case_tac "offs' = offs + 8 + wordarray_length (ObjDentry.name\<^sub>f (pObjDentry (take (unat end_offs) (\<alpha>wa (data\<^sub>f buf))) offs))")
apply simp
apply (simp add: dentarr_offs_list_drop_def)
apply (subst (asm) split_upt_on_l_n[where l=frm and n=frm, simplified], fastforce)
apply (simp add: Let_def)
apply (subst (asm) snd_fold_append_simp[where xs="[_]"])
apply (erule_tac x="offs' " in ballE, fastforce)
apply (fastforce simp add: pObjDentry_eq)
done
qed
lemma replicate_simp:
"replicate (unat to + 1 - unat to) (Option.None ()) = [Option.None ()]"
by (simp add: unat_arith_simps)
lemma mapAccumObsOpt_loop_deserialise_ObjDentry_array_ret:
assumes wellformed_buf: "wellformed_buf buf"
assumes no_buf_overflow: "length (\<alpha>wa $ data\<^sub>f buf) \<le> unat bilbyFsMaxEbSize"
assumes bound: "end_offs \<le> bound\<^sub>f buf"
assumes off_less_end_offs: "offs \<le> end_offs"
assumes st_offs: "st_offs \<le> offs"
shows
"let data = take (unat end_offs) (\<alpha>wa (data\<^sub>f buf));
arr_spec = pArrObjDentry data offs to in
(case mapAccumObsOpt 0 (unat to) loop_deserialise_ObjDentry
(replicate (unat to + 1) (Option.None ())) (ex, offs) (buf, end_offs) of
LoopResult.Break (ys, d, ex) \<Rightarrow>
d \<in> {eInval, eNoMem}
| LoopResult.Iterate (ys, ex, offs') \<Rightarrow>
(ys, ex, offs') = (\<alpha>a (prod.fst arr_spec), ex, prod.fst (prod.snd arr_spec)) \<and>
offs' \<le> end_offs \<and>
dentarr_offs_list_end_offs_pred data offs [0..<unat to] end_offs \<and>
dentarr_offs_list_drop_end_offs_pred data offs [0..<unat to] st_offs end_offs)"
unfolding pArrObjDentry_def Let_def
apply (clarsimp simp: array_make split: LoopResult.splits prod.splits)
using mapAccumObsOpt_loop_deserialise_ObjDentry_ret[OF assms(1-4), simplified Let_def,
where frm=0 and to=to and ex=ex and st_offs=st_offs and
ys="replicate (unat to + 1)(Option.None ())", simplified take_0 drop_replicate replicate_simp]
st_offs
apply (clarsimp split: LoopResult.splits)
done
lemma array_map_loop_deserialise_ObjDentry_ret:
assumes wellformed_buf: "wellformed_buf buf"
assumes no_buf_overflow: "length (\<alpha>wa $ data\<^sub>f buf) \<le> unat bilbyFsMaxEbSize"
assumes bound: "end_offs \<le> bound\<^sub>f buf"
assumes off_less_end_offs: "offs \<le> end_offs"
assumes st_offs: "st_offs \<le> offs"
shows "case array_map (ArrayMapP.make (ArrayT.make (replicate (unat to + 1) (Option.None ())))
0 to loop_deserialise_ObjDentry (ex, offs) (buf, end_offs)) of
LoopResult.Break (arr, err, ex) \<Rightarrow> err \<in> {eInval, eNoMem}
| LoopResult.Iterate (arr, ex', offs') \<Rightarrow>
let data = take (unat end_offs) (\<alpha>wa (data\<^sub>f buf));
(parr, poffs, poffslist) = pArrObjDentry data offs to;
ostlist = pArrObjDentry data offs to
in
arr = parr \<and> offs' = poffs \<and>
offs' \<le> end_offs \<and>
dentarr_offs_list_end_offs_pred data offs [0..<unat to] end_offs \<and>
dentarr_offs_list_drop_end_offs_pred data offs [0..<unat to] st_offs end_offs"
apply (clarsimp simp: ArrayMapP.make_def array_make array_map_ret)
using assms mapAccumObsOpt_loop_deserialise_ObjDentry_array_ret
[unfolded Let_def, where to=to and buf=buf and ex=ex and offs=offs and end_offs=end_offs and st_offs=st_offs]
by (clarsimp simp: array_make' Let_def split: LoopResult.splits)
lemma deserialise_Array_ObjDentry_ret:
assumes wellformed_buf: "wellformed_buf buf"
assumes no_buf_overflow: "length (\<alpha>wa $ data\<^sub>f buf) \<le> unat bilbyFsMaxEbSize"
assumes bound: "end_offs \<le> bound\<^sub>f buf"
assumes off_less_end_offs: "offs \<le> end_offs"
assumes st_offs: "st_offs \<le> offs"
assumes offs_pl_8_no_of: "offs \<le> offs + 8"
assumes offs_pl_8_le_end_offs: "offs + 8 \<le> end_offs"
assumes err: "\<And>ex e. e \<in> {eInval, eNoMem} \<Longrightarrow> P (Error (e, ex))"
assumes suc:
"\<And>ex arr offs' offslist data.
\<lbrakk> (arr, offs',offslist) = (pArrObjDentry (take (unat end_offs) (\<alpha>wa (data\<^sub>f buf))) offs nb_dentry);
offs' \<le> end_offs;
data = take (unat end_offs) (\<alpha>wa (data\<^sub>f buf));
dentarr_offs_list_end_offs_pred data offs [0..<unat nb_dentry] end_offs;
dentarr_offs_list_drop_end_offs_pred data offs [0..<unat nb_dentry] st_offs end_offs \<rbrakk> \<Longrightarrow>
P (Success (ex, arr, offs'))"
shows "P (deserialise_Array_ObjDentry (ex, buf, offs, nb_dentry, end_offs))"
unfolding deserialise_Array_ObjDentry_def[unfolded tuple_simps sanitizers]
apply (simp add: Let_def)
apply (rule array_create_ret)
apply (simp add: err[unfolded eNoMem_def])
apply (rename_tac ex' arr a)
apply (subgoal_tac "unat nb_dentry + 1 = unat (nb_dentry+1) ")
apply (clarsimp simp: prod.case_eq_if id_def Let_def split: LoopResult.splits)
apply (subgoal_tac "a = ArrayT.make (replicate (unat (nb_dentry + 1)) (Option.None ()))", simp)
apply (cut_tac ex=ex' in array_map_loop_deserialise_ObjDentry_ret[OF assms(1-5), where to = nb_dentry])
apply (clarsimp simp: Let_def err split: LoopResult.splits)
apply (rename_tac offslist a ex'' offs')
apply (rule suc)
apply simp+
apply (metis array_make')
apply unat_arith
done
lemma word_add_diff_assoc:
"(a::'a:: len0 word) + b - c = a + (b - c)"
by simp
method offs_olen_of_solver =
(((drule less_to_le)?, simp add: word_add_diff_assoc unat_plus_simple),
(simp only: unat_arith_simps)?, simp? ; unat_arith)
lemma deserialise_ObjDentarr_ret:
assumes wf: "wellformed_buf buf"
assumes buf_len: "length (\<alpha>wa $ data\<^sub>f buf) \<le> unat bilbyFsMaxEbSize"
assumes err: "\<And>ex e. e \<in> {eInval, eNoMem} \<Longrightarrow> P (Error (e, ex))"
assumes offs_bound: "offs + olen - bilbyFsObjHeaderSize \<le> (bound\<^sub>f buf)"
assumes offs_olen: "offs < offs + olen - bilbyFsObjHeaderSize"
assumes olen: "bilbyFsObjHeaderSize + bilbyFsObjDentarrHeaderSize + bilbyFsObjDentryHeaderSize \<le> olen"
assumes st_offs: "st_offs \<le> offs"
assumes suc:
"\<And>ex dentarr offs'. \<lbrakk>
dentarr = pObjDentarr (\<alpha>wa (data\<^sub>f buf)) offs olen;
offs' = pObjDentarrSize (\<alpha>wa (data\<^sub>f buf)) offs olen;
let end_offs = offs + olen - bilbyFsObjHeaderSize;
data = take (unat end_offs) (\<alpha>wa (data\<^sub>f buf));
nb_dentry = ple32 (\<alpha>wa (data\<^sub>f buf)) (offs+8) in
dentarr_offs_list_end_offs_pred data (offs+bilbyFsObjDentarrHeaderSize) [0..<unat nb_dentry] end_offs \<and>
dentarr_offs_list_drop_end_offs_pred data (offs+bilbyFsObjDentarrHeaderSize) [0..<unat nb_dentry] st_offs end_offs;
offs' \<le> offs + olen - bilbyFsObjHeaderSize
\<rbrakk> \<Longrightarrow>
P (Success (ex, dentarr, offs'))"
notes bilbyFsObjDentarrHeaderSize_def[simp] bilbyFsObjHeaderSize_def[simp]
bilbyFsObjDentryHeaderSize_def[simp]
shows "P (deserialise_ObjDentarr (ex, buf, offs, olen))"
proof -
have offs_no_of: "offs < offs + bilbyFsObjDentarrHeaderSize"
using olen and offs_olen by simp unat_arith
have bound_max: "bound\<^sub>f buf \<le> bilbyFsMaxEbSize"
using wf and buf_len by (simp add: wellformed_buf_def) unat_arith
have offs_bound': "offs < bilbyFsMaxEbSize"
using offs_bound offs_olen bound_max offs_no_of by simp
have offs_hdr_no_of: "offs < offs + bilbyFsObjDentarrHeaderSize"
using offs_bound' by (simp add: bilbyFsMaxEbSize_def unat_arith_simps)
have offs_pl_hdr_le_len: "unat offs + unat bilbyFsObjDentarrHeaderSize \<le> length (\<alpha>wa $ data\<^sub>f buf)"
using offs_bound wf offs_no_of offs_olen olen
by (simp add: wellformed_buf_def) unat_arith
have deserialises:
"deserialise_le32 (buf, offs + 8) = (ple32 (\<alpha>wa $ data\<^sub>f buf) (offs + 8))"
"deserialise_le64 (buf, offs) = (ple64 (\<alpha>wa $ data\<^sub>f buf) offs)"
using offs_pl_hdr_le_len apply (clarsimp simp:)
apply (rule deserialise_le32_ret[simplified])
using offs_hdr_no_of apply unat_arith
using offs_hdr_no_of apply (simp add: unat_arith_simps)
apply unat_arith
using offs_pl_hdr_le_len apply (clarsimp)
apply (rule deserialise_le64_ret[simplified])
using offs_hdr_no_of apply unat_arith
using offs_hdr_no_of apply (simp add: unat_arith_simps)
apply unat_arith
done
show ?thesis
unfolding deserialise_ObjDentarr_def[unfolded tuple_simps sanitizers]
apply (clarsimp simp: Let_def err[unfolded eInval_def])
apply (subgoal_tac "\<exists>v. olen - bilbyFsObjHeaderSize = v \<and> bilbyFsObjDentarrHeaderSize + bilbyFsObjDentryHeaderSize \<le> v")
apply (erule exE)
apply (erule conjE)
apply (rule deserialise_Array_ObjDentry_ret[OF assms(1,2), where st_offs=st_offs,
simplified])
using offs_bound apply simp
subgoal using offs_olen olen by - offs_olen_of_solver
subgoal for v
using st_offs offs_olen by - offs_olen_of_solver
subgoal for v
using offs_olen by - offs_olen_of_solver
subgoal for v
using offs_olen by (simp add: word_add_diff_assoc add.commute)
(rule word_plus_mono_right; simp)
subgoal for v _ e by (fastforce intro: err)
subgoal for v ex arr offs' offslist
apply (case_tac "R.Success (ex, arr, offs')", simp_all)
apply (clarsimp simp: Let_def err[unfolded eNoMem_def] split: R.split)
apply (rule suc)
subgoal
apply (simp add: pObjDentarr_def Let_def)
apply (subst ObjDentarr.surjective, simp add: ObjDentarr.make_def deserialises prod_eq_iff)
done
subgoal by (clarsimp simp add: prod_eq_iff pObjDentarrSize_def deserialises)
subgoal by (simp add: Let_def deserialises)
subgoal by simp
done
subgoal using olen by (simp) unat_arith
done
qed
lemmas pObjUnion_def' =
pObjUnion_def[unfolded otype_simps, simplified]
lemmas len_otype_ok = is_len_and_type_ok_def[unfolded sanitizers tuple_simps]
lemma olen_bound_trivial:
" 0x28 \<le> (olen::U32) \<Longrightarrow>
offs + olen - 0x18 \<le> bound\<^sub>f buf \<Longrightarrow>
offs \<le> offs + olen - 0x18 \<Longrightarrow> offs + 0x10 \<le> bound\<^sub>f buf"
by unat_arith
lemma offs_trivial:
"(offs::U32) \<le> offs + olen - 0x18 \<Longrightarrow>
0x28 \<le> olen \<Longrightarrow>
offs < offs + 0x10"
by unat_arith
lemma unat_obj_len_minus_hdrsz:
assumes len_otype_rel: "bilbyFsObjHeaderSize \<le> olen"
assumes offs_no_of: "offs \<le> offs + olen - bilbyFsObjHeaderSize"
shows
"unat (offs + olen - bilbyFsObjHeaderSize) = unat offs + unat olen - unat bilbyFsObjHeaderSize"
using assms
by (simp add: bilbyFsObjHeaderSize_def word_add_diff_assoc unat_plus_simple) (simp add: unat_arith_simps)
lemma deserialise_ObjUnion_ret:
assumes wf: "wellformed_buf buf"
assumes no_buf_overflow: "length (\<alpha>wa $ data\<^sub>f buf) \<le> unat bilbyFsMaxEbSize"
assumes bound: "offs + olen - bilbyFsObjHeaderSize \<le> bound\<^sub>f buf"
assumes len_otype_rel: "is_len_and_type_ok (otype, olen)"
assumes offs_no_of: "offs \<le> offs + olen - bilbyFsObjHeaderSize"
assumes offs_no_underflow: "offs - bilbyFsObjHeaderSize \<le> offs"
assumes err:
"\<And>ex e. e \<in> {eInval, eNoMem} \<Longrightarrow> P (Error (e, ex))"
assumes suc:
"\<And>ex ounion offs'. ounion = pObjUnion ((*take (unat (offs + olen))*) (\<alpha>wa (data\<^sub>f buf))) otype olen offs \<Longrightarrow>
offs' \<le> (offs + olen - bilbyFsObjHeaderSize) \<Longrightarrow>
let end_offs = offs + olen - bilbyFsObjHeaderSize;
data = take (unat end_offs) (\<alpha>wa (data\<^sub>f buf));
nb_dentry = ple32 (\<alpha>wa (data\<^sub>f buf)) (offs+8) in
dentarr_otype_end_offs_pred otype data offs end_offs \<and>
dentarr_otype_drop_end_offs_st_pred otype data offs (offs - bilbyFsObjHeaderSize) end_offs
\<Longrightarrow>
P (Success (ex, ounion, offs'))"
notes suc_simps = len_otype_ok Let_def pObjUnion_def' suc add.commute bilbyFsObjHeaderSize_def
otype_simps dentarr_end_offs_simps dentarr_drop_end_offs_simps
shows "P (deserialise_ObjUnion (ex, buf, offs, (otype, olen)))"
unfolding deserialise_ObjUnion_def[unfolded tuple_simps, simplified sanitizers]
using is_len_and_type_ok_hdr_szD[OF len_otype_rel]
apply (clarsimp simp: Let_def)
apply (rule conjI)
apply clarsimp
apply (rule deserialise_ObjSuper_ret, simp)
using len_otype_rel offs_no_of bound wf
apply (simp add: len_otype_ok Let_def prod.case_eq_if wellformed_buf_def bilbyFsObjHeaderSize_def)
apply unat_arith
using len_otype_rel offs_no_of bound wf
apply (simp add: len_otype_ok Let_def prod.case_eq_if wellformed_buf_def bilbyFsObjHeaderSize_def)
apply unat_arith
apply (simp add: err)
using len_otype_rel
apply (simp add: suc_simps)
apply clarsimp
apply (rule conjI)
apply clarsimp
apply (rule deserialise_ObjDel_ret, simp)
using len_otype_rel offs_no_of bound wf
apply (simp add: len_otype_ok Let_def prod.case_eq_if wellformed_buf_def bilbyFsObjHeaderSize_def)
apply unat_arith
apply (simp add: err)
using len_otype_rel offs_no_of bound wf
apply (simp add: len_otype_ok Let_def prod.case_eq_if wellformed_buf_def bilbyFsObjHeaderSize_def)
apply unat_arith
using len_otype_rel
apply (simp add: suc_simps)
apply clarsimp
apply (rule conjI)
apply clarsimp
apply (rule deserialise_ObjDentarr_ret[OF wf no_buf_overflow, where st_offs ="offs - bilbyFsObjHeaderSize"])
apply (simp add: err)
using bound offs_no_of len_otype_rel
apply (simp add: len_otype_ok Let_def prod.case_eq_if wellformed_buf_def bilbyFsObjHeaderSize_def)
using offs_no_of len_otype_rel
apply (simp add: len_otype_ok bilbyFsObjHeaderSize_def )
apply (simp add: word_add_diff_assoc unat_plus_simple word_less_nat_alt )
apply unat_arith
using len_otype_rel
apply (simp add: len_otype_ok bilbyFsObjHeaderSize_def bilbyFsObjDentryHeaderSize_def bilbyFsObjDentarrHeaderSize_def)
using offs_no_underflow apply simp
apply (simp add: suc pObjUnion_def' )
apply (rule suc)
apply (clarsimp simp add: pObjUnion_def')+
apply (simp add: dentarr_otype_drop_end_offs_st_pred_def dentarr_otype_end_offs_pred_def dentarr_otype_drop_end_offs_pred_def
bilbyFsObjTypeDentarr_def Let_def)
apply clarsimp
apply (subgoal_tac "ple32 (take (unat (offs + olen - bilbyFsObjHeaderSize)) (\<alpha>wa (data\<^sub>f buf))) (offs + 8) = ple32 (\<alpha>wa (data\<^sub>f buf)) (offs + 8)")
apply simp
apply (subgoal_tac "\<exists>v. olen - bilbyFsObjHeaderSize = v")
apply (erule exE)
apply (subst ple32_take)
(* <automate?> *)
using len_otype_rel
apply (simp add: len_otype_ok bilbyFsObjHeaderSize_def)
using offs_no_of apply (simp add: word_add_diff_assoc bilbyFsObjHeaderSize_def)
apply (simp add: word_add_diff_assoc unat_plus_simple word_less_nat_alt word_le_nat_alt add.commute)
apply (subst (asm) add.commute)
using offs_no_of apply (simp add: bilbyFsObjHeaderSize_def) apply (simp add: word_add_diff_assoc word_le_nat_alt)
apply (simp only: unat_arith_simps)
apply unat_arith
apply (simp add: bilbyFsObjHeaderSize_def word_add_diff_assoc)
using offs_no_of
apply (simp add: bilbyFsObjHeaderSize_def word_add_diff_assoc word_less_nat_alt add.commute)
apply (subst (asm) add.commute, simp add: unat_plus_simple)
using offs_no_of apply (simp add: bilbyFsObjHeaderSize_def)
apply (simp add: word_add_diff_assoc)
using len_otype_rel
apply (simp add: len_otype_ok)
apply (subgoal_tac "offs \<le> offs + 0xC")
apply (simp add: unat_plus_simple add.commute, simp only: word_le_nat_alt)
apply unat_arith
apply (simp add: unat_plus_simple add.commute, simp only: word_le_nat_alt)
apply unat_arith
(* </automate?> *)
apply simp
apply (fastforce)
apply clarsimp
apply (rule conjI)
apply clarsimp
apply (rule deserialise_ObjData_ret[OF ])
using offs_no_of
apply (simp only: diff_conv_add_uminus)
apply (simp only: add.assoc)
using bound wf offs_no_of apply (simp add: bilbyFsObjHeaderSize_def
wellformed_buf_def diff_conv_add_uminus add.assoc)
apply unat_arith
using len_otype_rel apply (simp add: otype_simps)
apply (simp add: err)
apply simp
apply (simp add: suc_simps)
apply (clarsimp)
apply (rule conjI)
apply clarsimp
apply (rule deserialise_ObjInode_ret)
using len_otype_rel offs_no_of bound
bound wf offs_no_of
apply (simp add: bilbyFsObjHeaderSize_def wellformed_buf_def )
using len_otype_rel apply (simp add: otype_simps len_otype_ok)
apply unat_arith
using len_otype_rel apply (simp add: otype_simps len_otype_ok)
using offs_no_of
apply (simp add: bilbyFsObjHeaderSize_def)
apply unat_arith
apply (simp add: err)
using len_otype_rel apply (simp add: otype_simps len_otype_ok)
apply (simp add: suc_simps)
apply clarsimp
apply (rule deserialise_ObjPad_ret)
apply (simp add:err)
apply (simp add: suc_simps add_diff_eq)+
done
lemma pObjDel_take:
"is_valid_ObjHeader (pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs) (bounded buf) \<Longrightarrow>
offs + Obj.len\<^sub>f obj \<le> bound\<^sub>f buf \<Longrightarrow>
is_len_and_type_ok (otype\<^sub>f obj, Obj.len\<^sub>f obj) \<Longrightarrow>
offs < offs + Obj.len\<^sub>f obj \<Longrightarrow>
otype\<^sub>f obj = 3 \<Longrightarrow>
\<exists>v. obj\<lparr>ounion\<^sub>f := v\<rparr> = pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs \<Longrightarrow>
pObjDel (\<alpha>wa (data\<^sub>f buf)) (offs + bilbyFsObjHeaderSize) =
pObjDel (take (unat (offs + Obj.len\<^sub>f obj)) (\<alpha>wa (data\<^sub>f buf))) (offs + bilbyFsObjHeaderSize)"
apply (simp add: pObjDel_def)
apply (frule is_valid_ObjHeader_buf_len, clarify)
apply (subst ple64_take, (simp add: otype_simps len_otype_ok bilbyFsObjHeaderSize_def, unat_arith)+)
apply simp
done
lemma pObjSuper_take:
"is_valid_ObjHeader (pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs) (bounded buf) \<Longrightarrow>
offs + Obj.len\<^sub>f obj \<le> bound\<^sub>f buf \<Longrightarrow>
is_len_and_type_ok (otype\<^sub>f obj, Obj.len\<^sub>f obj) \<Longrightarrow>
offs < offs + Obj.len\<^sub>f obj \<Longrightarrow>
otype\<^sub>f obj = 4 \<Longrightarrow>
\<exists>v. obj\<lparr>ounion\<^sub>f := v\<rparr> = pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs \<Longrightarrow>
pObjSuper (\<alpha>wa (data\<^sub>f buf)) (offs + bilbyFsObjHeaderSize) =
pObjSuper (take (unat (offs + Obj.len\<^sub>f obj)) (\<alpha>wa (data\<^sub>f buf))) (offs + bilbyFsObjHeaderSize)"
apply (simp add: pObjSuper_def)
apply (frule is_valid_ObjHeader_buf_len, clarify)
apply (subst ple64_take, ((simp add: otype_simps len_otype_ok bilbyFsObjHeaderSize_def, unat_arith)+)[2])
apply (subst ple32_take, ((simp add: otype_simps len_otype_ok bilbyFsObjHeaderSize_def, unat_arith)+)[2])+
apply simp
done
lemma pObjInode_take:
"is_valid_ObjHeader (pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs) (bounded buf) \<Longrightarrow>
offs + Obj.len\<^sub>f obj \<le> bound\<^sub>f buf \<Longrightarrow>
is_len_and_type_ok (otype\<^sub>f obj, Obj.len\<^sub>f obj) \<Longrightarrow>
offs < offs + Obj.len\<^sub>f obj \<Longrightarrow>
otype\<^sub>f obj = 0 \<Longrightarrow>
\<exists>v. obj\<lparr>ounion\<^sub>f := v\<rparr> = pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs \<Longrightarrow>
pObjInode (\<alpha>wa (data\<^sub>f buf)) (offs + bilbyFsObjHeaderSize) =
pObjInode (take (unat (offs + Obj.len\<^sub>f obj)) (\<alpha>wa (data\<^sub>f buf))) (offs + bilbyFsObjHeaderSize)"
apply (simp add: pObjInode_def)
apply (frule is_valid_ObjHeader_buf_len, clarify)
apply (subst ple64_take, ((simp add: otype_simps len_otype_ok bilbyFsObjHeaderSize_def, unat_arith)+)[2])+
apply (subst ple32_take, ((simp add: otype_simps len_otype_ok bilbyFsObjHeaderSize_def, unat_arith)+)[2])+
apply simp
done
lemma pObjDentarr_take:
"is_valid_ObjHeader (pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs) (bounded buf) \<Longrightarrow>
offs + Obj.len\<^sub>f obj \<le> bound\<^sub>f buf \<Longrightarrow>
is_len_and_type_ok (otype\<^sub>f obj, Obj.len\<^sub>f obj) \<Longrightarrow>
offs < offs + Obj.len\<^sub>f obj \<Longrightarrow>
otype\<^sub>f obj = 2 \<Longrightarrow>
\<exists>v. obj\<lparr>ounion\<^sub>f := v\<rparr> = pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs \<Longrightarrow>
pObjDentarr (\<alpha>wa (data\<^sub>f buf)) (offs + bilbyFsObjHeaderSize) (Obj.len\<^sub>f obj) =
pObjDentarr (take (unat (offs + Obj.len\<^sub>f obj)) (\<alpha>wa (data\<^sub>f buf))) (offs + bilbyFsObjHeaderSize) (Obj.len\<^sub>f obj)"
apply (simp add: pObjDentarr_def)
apply (frule is_valid_ObjHeader_buf_len, clarify)
apply (subst ple64_take, ((simp add: otype_simps len_otype_ok bilbyFsObjHeaderSize_def, unat_arith)+)[2])+
apply (subst ple32_take, ((simp add: otype_simps len_otype_ok bilbyFsObjHeaderSize_def, unat_arith)+)[2])+
apply (simp add: Let_def)
done
lemma pObjData_take:
"is_valid_ObjHeader (pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs) (bounded buf) \<Longrightarrow>
offs + Obj.len\<^sub>f obj \<le> bound\<^sub>f buf \<Longrightarrow>
is_len_and_type_ok (otype\<^sub>f obj, Obj.len\<^sub>f obj) \<Longrightarrow>
offs < offs + Obj.len\<^sub>f obj \<Longrightarrow>
otype\<^sub>f obj = 1 \<Longrightarrow>
\<exists>v. obj\<lparr>ounion\<^sub>f := v\<rparr> = pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs \<Longrightarrow>
pObjData (\<alpha>wa (data\<^sub>f buf)) (offs + bilbyFsObjHeaderSize) (Obj.len\<^sub>f obj) =
pObjData (take (unat (offs + Obj.len\<^sub>f obj)) (\<alpha>wa (data\<^sub>f buf))) (offs + bilbyFsObjHeaderSize)
(Obj.len\<^sub>f obj)"
apply (simp add: pObjData_def)
apply (subst ple64_take, ((simp add: otype_simps len_otype_ok bilbyFsObjHeaderSize_def, unat_arith)+)[2])+
apply (simp add: otype_simps len_otype_ok)
apply (subst slice_take)
apply (frule is_valid_ObjHeader_len)
apply (subgoal_tac " unat (Obj.len\<^sub>f obj - bilbyFsObjHeaderSize - bilbyFsObjDataHeaderSize) = unat (Obj.len\<^sub>f obj) - unat bilbyFsObjHeaderSize - unat bilbyFsObjDataHeaderSize")
apply (subgoal_tac "unat (offs + Obj.len\<^sub>f obj) = unat offs + unat ( Obj.len\<^sub>f obj)")
apply simp
apply (simp add: bilbyFsObjHeaderSize_def bilbyFsObjDataHeaderSize_def)
apply unat_arith
apply (simp add: word_less_nat_alt unat_plus_simple[symmetric], unat_arith)
apply (subst unat_sub, simp add: bilbyFsObjHeaderSize_def bilbyFsObjDataHeaderSize_def, unat_arith)+
apply simp+
done
lemma pObjUnion_take:
"is_valid_ObjHeader (pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs) (bounded buf) \<Longrightarrow>
offs + Obj.len\<^sub>f obj \<le> bound\<^sub>f buf \<Longrightarrow>
is_len_and_type_ok (otype\<^sub>f obj, Obj.len\<^sub>f obj) \<Longrightarrow>
offs < offs + Obj.len\<^sub>f obj \<Longrightarrow>
\<exists>v. obj\<lparr>ounion\<^sub>f := v\<rparr> = pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs \<Longrightarrow>
pObjUnion (\<alpha>wa (data\<^sub>f buf)) (otype\<^sub>f obj) (Obj.len\<^sub>f obj) (offs + bilbyFsObjHeaderSize) =
pObjUnion (take (unat (offs + Obj.len\<^sub>f obj)) (\<alpha>wa (data\<^sub>f buf))) (otype\<^sub>f obj) (Obj.len\<^sub>f obj) (offs + bilbyFsObjHeaderSize)"
apply (simp add: pObjUnion_def')
apply (case_tac "otype\<^sub>f obj = 0")
apply (simp add: pObjInode_take)
apply (case_tac "otype\<^sub>f obj = 1")
apply (simp add: pObjData_take)
apply (case_tac "otype\<^sub>f obj = 2")
apply (simp add: pObjDentarr_take)
apply (case_tac "otype\<^sub>f obj = 3")
apply (simp add: pObjDel_take)
apply (case_tac "otype\<^sub>f obj = 4")
apply (simp add: pObjSuper_take)
apply simp
done
lemmas Obj_ext_eq_expand = trans[OF _ Obj.ext_inject,
OF arg_cong2[where f="(=)"], OF refl Obj.surjective]
lemma deserialise_Obj_ret:
assumes wf: "wellformed_buf buf"
assumes buf_len: "length (\<alpha>wa $ data\<^sub>f buf) \<le> unat bilbyFsMaxEbSize"
assumes bound: "offs + bilbyFsObjHeaderSize \<le> bound\<^sub>f buf"
assumes no_of: "offs < offs + bilbyFsObjHeaderSize"
assumes err: "\<And>ex e. e \<in> {eInval, eNoMem} \<Longrightarrow> P (Error (e, ex))"
assumes suc:
"\<And>ex obj offs'. \<lbrakk>
is_valid_ObjHeader (pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs) (\<alpha>wa (data\<^sub>f buf)) ;
let end_offs = offs + (Obj.len\<^sub>f obj);
data = take (unat end_offs) (\<alpha>wa (data\<^sub>f buf));
nb_dentry = ple32 (\<alpha>wa (data\<^sub>f buf)) (offs+8) in
dentarr_otype_end_offs_pred (Obj.otype\<^sub>f obj) data (offs + bilbyFsObjHeaderSize) end_offs \<and>
dentarr_otype_drop_end_offs_st_pred (Obj.otype\<^sub>f obj) data (offs + bilbyFsObjHeaderSize) offs end_offs;
obj = pObj (\<alpha>wa (data\<^sub>f buf)) offs;
offs' \<le> offs + Obj.len\<^sub>f obj \<rbrakk> \<Longrightarrow>
P (Success (ex, obj, offs'))"
notes bilbyFsObjHeaderSize_def[simp]
shows "P (deserialise_Obj (ex, buf, offs))"
unfolding deserialise_Obj_def[unfolded tuple_simps sanitizers]
apply (clarsimp simp: err eNoMem_def split: R.split)
apply (rule deserialise_ObjHeader_ret[OF wf bound no_of])
apply (simp add: err)
apply simp
apply (rule deserialise_ObjUnion_ret[OF wf buf_len])
apply (simp)
apply (clarsimp, drule sym[where t="pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs"])
apply (clarsimp simp add: is_valid_ObjHeader_def)
apply simp
apply (drule is_valid_ObjHeader_len)
apply (clarsimp, drule sym[where t="pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs"])
apply (drule arg_cong[where f=Obj.len\<^sub>f])
using no_of bound
apply simp
apply (simp only: word_le_nat_alt plus_no_overflow_unat_lift)
apply (drule is_valid_ObjHeader_len)
apply (clarsimp, drule sym[where t="pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs"])
apply (drule arg_cong[where f=Obj.len\<^sub>f])
apply (clarsimp simp add: )
apply unat_arith
apply (simp add: err)
apply simp
apply (rule suc)
apply (clarsimp simp add: is_valid_ObjHeader_def bounded_def)
apply simp
apply (clarsimp simp add: pObj_def Let_def)
apply (drule sym[where t="pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs"])
apply (subst pObjUnion_take[simplified], (fastforce simp add: is_valid_ObjHeader_def)+)
apply (rename_tac obj offs' v)
apply (subgoal_tac "pObjUnion (take (unat (offs + Obj.len\<^sub>f obj)) (\<alpha>wa (data\<^sub>f buf))) (otype\<^sub>f obj)
(Obj.len\<^sub>f obj) (offs + 0x18) = pObjUnion
(take (unat offs + unat (Obj.len\<^sub>f (pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs))) (\<alpha>wa (data\<^sub>f buf)))
(otype\<^sub>f (pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs))
(Obj.len\<^sub>f (pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs)) (offs + 0x18)")
apply simp
apply (case_tac "pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs", case_tac obj, simp)
apply (case_tac "pObjHeader (\<alpha>wa (data\<^sub>f buf)) offs", case_tac obj, simp)
apply (simp add: plus_no_overflow_unat_lift)+
done
lemma pObjHeader_take:
"is_valid_ObjHeader (pObjHeader xs (ObjAddr.offs\<^sub>f oaddr)) xs \<Longrightarrow>
is_obj_addr_consistent (pObj (take (unat (ObjAddr.offs\<^sub>f oaddr) + unat (ObjAddr.len\<^sub>f oaddr)) xs)
(ObjAddr.offs\<^sub>f oaddr)) oaddr \<Longrightarrow>
ObjAddr.offs\<^sub>f oaddr < ObjAddr.offs\<^sub>f oaddr + bilbyFsObjHeaderSize \<Longrightarrow>
bilbyFsObjHeaderSize \<le> ObjAddr.len\<^sub>f oaddr \<Longrightarrow>
pObjHeader xs (ObjAddr.offs\<^sub>f oaddr) = pObjHeader (take (unat (ObjAddr.offs\<^sub>f oaddr) + unat (ObjAddr.len\<^sub>f oaddr)) xs) (ObjAddr.offs\<^sub>f oaddr)"
apply (simp add: pObjHeader_def)
apply (subst ple32_take, ((simp add: bilbyFsObjHeaderSize_def, unat_arith, fastforce? )[2])+)+
apply (subst ple64_take, ((simp add: bilbyFsObjHeaderSize_def, unat_arith, fastforce? )[2])+)+
apply (subst nth_take, (simp add: bilbyFsObjHeaderSize_def, unat_arith))+
apply (rule refl)
done
end