Get rid of cstruct
And update opam file
This commit is contained in:
parent
bf003875b9
commit
04cc6350b1
3 changed files with 30 additions and 34 deletions
2
lib/dune
2
lib/dune
|
@ -1,4 +1,4 @@
|
|||
(library
|
||||
(public_name solo5-elftool)
|
||||
(name solo5_elftool)
|
||||
(libraries owee cstruct cachet fmt))
|
||||
(libraries owee cachet fmt))
|
||||
|
|
|
@ -70,43 +70,41 @@ let guard m b = if not b then Error (`Msg m) else Ok ()
|
|||
let sizeof_mft_entry = 104
|
||||
let mft_max_entries = 64l
|
||||
|
||||
let parse_mft_entry buf =
|
||||
let parse_mft_entry s =
|
||||
(* invariant: Cstruct.length buf = sizeof_mft_entry *)
|
||||
let name_raw = Cstruct.sub buf 0 68 in
|
||||
let typ = Cstruct.LE.get_uint32 buf 68 in
|
||||
let u = Cstruct.sub buf 72 16 in
|
||||
let b = Cstruct.sub buf 88 8 in
|
||||
let attached = Cstruct.get_uint8 buf 96 <> 0 in
|
||||
let name_raw = String.sub s 0 68 in
|
||||
let typ = String.get_int32_le s 68 in
|
||||
let u = String.sub s 72 16 in
|
||||
let b = String.sub s 88 8 in
|
||||
let attached = String.get_uint8 s 96 <> 0 in
|
||||
let* name =
|
||||
Cstruct.cut ~sep:(Cstruct.create 1) name_raw
|
||||
|> Option.map (fun (name, _) -> Cstruct.to_string name)
|
||||
String.index_opt name_raw '\000'
|
||||
|> Option.map (fun idx -> String.sub name_raw 0 idx)
|
||||
|> Option.to_result ~none:(`Msg "unterminated device name")
|
||||
in
|
||||
let* () = guard "non-zero mft_entry.u" (Cstruct.for_all ((=) '\000') u) in
|
||||
let* () = guard "non-zero mft_entry.b" (Cstruct.for_all ((=) '\000') b) in
|
||||
let* () = guard "non-zero mft_entry.u" (String.for_all ((=) '\000') u) in
|
||||
let* () = guard "non-zero mft_entry.b" (String.for_all ((=) '\000') b) in
|
||||
let* () = guard "non-zero mft_entry.attached" (not attached) in
|
||||
let* typ = mft_type_of_int typ in
|
||||
match typ with
|
||||
| Reserved_first ->
|
||||
let* () = guard "non-zero RESERVED_FIRST" (Cstruct.for_all ((=) '\000') name_raw) in
|
||||
let* () = guard "non-zero RESERVED_FIRST" (String.for_all ((=) '\000') name_raw) in
|
||||
Ok `Reserved_first
|
||||
| Dev_block_basic ->
|
||||
Ok (`Dev_block_basic name)
|
||||
| Dev_net_basic ->
|
||||
Ok (`Dev_net_basic name)
|
||||
|
||||
let parse_mft buf =
|
||||
let buf = Cstruct.of_string buf in
|
||||
let parse_mft s =
|
||||
let* () = guard "manifest too small"
|
||||
(Cstruct.length buf >= 4 + 8 + sizeof_mft_entry)
|
||||
(String.length s >= 4 + 8 + sizeof_mft_entry)
|
||||
in
|
||||
(* Solo5 defines a struct mft1_note consisting of the ELF note header
|
||||
* followed by a struct mft for reading and writing the ELF note. The note
|
||||
* header is 20 bytes long, so to get 8-byte alignment the note header is
|
||||
* padded with 4 bytes. See {[solo5/mft_abi.h]}. *)
|
||||
let buf = Cstruct.shift buf 4 in
|
||||
let version = Cstruct.LE.get_uint32 buf 0
|
||||
and entries = Cstruct.LE.get_uint32 buf 4
|
||||
let version = String.get_int32_le s 4
|
||||
and entries = String.get_int32_le s 8
|
||||
in
|
||||
let* () = guard "unsupported manifest version" (version = 1l) in
|
||||
let* () = guard "zero manifest entries" (Int32.unsigned_compare entries 0l > 0) in
|
||||
|
@ -118,25 +116,25 @@ let parse_mft buf =
|
|||
* mft_max_entries, so this is safely equivalent to:
|
||||
* (Option.get (Int32.unsigned_to_int entries) *)
|
||||
let entries = Int32.to_int entries in
|
||||
let buf = Cstruct.shift buf 8 in
|
||||
let off = 12 in
|
||||
let* () = guard "unexpected note size"
|
||||
(Cstruct.length buf = entries * sizeof_mft_entry)
|
||||
(String.length s = entries * sizeof_mft_entry + 12)
|
||||
in
|
||||
let* () =
|
||||
match parse_mft_entry (Cstruct.sub buf 0 sizeof_mft_entry) with
|
||||
match parse_mft_entry (String.sub s off sizeof_mft_entry) with
|
||||
| Ok `Reserved_first -> Ok ()
|
||||
| _ -> Error (`Msg "expected RESERVED_FIRST")
|
||||
in
|
||||
let buf = Cstruct.shift buf sizeof_mft_entry in
|
||||
let off = off + sizeof_mft_entry in
|
||||
let entries =
|
||||
Array.init (entries - 1)
|
||||
(fun i -> Cstruct.sub buf (i * sizeof_mft_entry) sizeof_mft_entry)
|
||||
(fun i -> String.sub s (off + i * sizeof_mft_entry) sizeof_mft_entry)
|
||||
in
|
||||
let* entries =
|
||||
Array.fold_left
|
||||
(fun r buf ->
|
||||
(fun r s ->
|
||||
let* acc = r in
|
||||
let* mft_entry = parse_mft_entry buf in
|
||||
let* mft_entry = parse_mft_entry s in
|
||||
match mft_entry with
|
||||
| `Dev_block_basic name -> Ok (Dev_block_basic name :: acc)
|
||||
| `Dev_net_basic name -> Ok (Dev_net_basic name :: acc)
|
||||
|
@ -147,13 +145,12 @@ let parse_mft buf =
|
|||
in
|
||||
Ok { version = Int32.to_int version; entries }
|
||||
|
||||
let parse_abi buf =
|
||||
let buf = Cstruct.of_string buf in
|
||||
let* () = guard "abi manifest size mismatch" (Cstruct.length buf = 4 * 4) in
|
||||
let target = Cstruct.LE.get_uint32 buf 0 in
|
||||
let version = Cstruct.LE.get_uint32 buf 4 in
|
||||
let reserved0 = Cstruct.LE.get_uint32 buf 8 in
|
||||
let reserved1 = Cstruct.LE.get_uint32 buf 12 in
|
||||
let parse_abi s =
|
||||
let* () = guard "abi manifest size mismatch" (String.length s = 4 * 4) in
|
||||
let target = String.get_int32_le s 0 in
|
||||
let version = String.get_int32_le s 4 in
|
||||
let reserved0 = String.get_int32_le s 8 in
|
||||
let reserved1 = String.get_int32_le s 12 in
|
||||
let* target = abi_target_of_int target in
|
||||
let* () = guard "non-zero reserved0" (reserved0 = 0l) in
|
||||
let* () = guard "non-zero reserved1" (reserved1 = 0l) in
|
||||
|
|
|
@ -15,8 +15,7 @@ build: [
|
|||
depends: [
|
||||
"ocaml" {>= "4.08.0"}
|
||||
"dune" {>= "2.9"}
|
||||
"owee" {>= "0.4"}
|
||||
"cstruct" {>= "6.0.0"}
|
||||
"cachet"
|
||||
"fmt" {>= "0.8.7"}
|
||||
"cmdliner" {>= "1.1.0"}
|
||||
]
|
||||
|
|
Loading…
Reference in a new issue