summaryrefslogtreecommitdiff
path: root/src/elf_model/elf_executable_file3.lem
diff options
context:
space:
mode:
Diffstat (limited to 'src/elf_model/elf_executable_file3.lem')
-rw-r--r--src/elf_model/elf_executable_file3.lem505
1 files changed, 0 insertions, 505 deletions
diff --git a/src/elf_model/elf_executable_file3.lem b/src/elf_model/elf_executable_file3.lem
deleted file mode 100644
index 56b2b611..00000000
--- a/src/elf_model/elf_executable_file3.lem
+++ /dev/null
@@ -1,505 +0,0 @@
-open import Basic_classes
-open import Num
-open import Maybe
-open import String
-
-open import Elf_executable_file2
-open import Elf_header
-open import Elf_interpreted_segment
-open import Elf_types
-open import Elf_section_header_table
-open import Elf_symbol_table
-open import Elf_program_header_table
-open import String_table
-
-open import Bitstring
-open import Error
-open import Missing_pervasives
-open import Show
-
-(** Type [elf32_executable_file3] represents the lazy unfolding of a 32-bit ELF
- * file where the header, program header table and optional section header table
- * have been filled in, with all other data being left uninterpreted.
- *)
-type elf32_executable_file3 =
- <| elf32_executable_file3_header : elf32_header (** The ELF header (mandatory) *)
- ; elf32_executable_file3_program_header_table : elf32_program_header_table (** The program header table (mandatory) *)
- ; elf32_executable_file3_section_header_table : maybe elf32_section_header_table (** The section header table (optional) *)
- ; elf32_executable_file3_body : bitstring (** Uninterpreted body *)
- |>
-
-class (HasElf32ExecutableFile3 'a)
- val get_elf32_executable_file3 : 'a -> elf32_executable_file3
-end
-
-instance (HasElf32ExecutableFile3 elf32_executable_file3)
- let get_elf32_executable_file3 f3 = f3
-end
-
-instance (HasElf32ExecutableFile2 elf32_executable_file3)
- let get_elf32_executable_file2 f3 =
- <| elf32_executable_file2_header = f3.elf32_executable_file3_header;
- elf32_executable_file2_program_header_table = f3.elf32_executable_file3_program_header_table;
- elf32_executable_file2_body = f3.elf32_executable_file3_body |>
-end
-
-instance (HasElf32Header elf32_executable_file3)
- let get_elf32_header f3 = f3.elf32_executable_file3_header
-end
-
-instance (HasElf32ProgramHeaderTable elf32_executable_file3)
- let get_elf32_program_header_table f3 =
- Just (f3.elf32_executable_file3_program_header_table)
-end
-
-instance (HasElf32SectionHeaderTable elf32_executable_file3)
- let get_elf32_section_header_table f3 =
- f3.elf32_executable_file3_section_header_table
-end
-
-(** Type [elf64_executable_file3] represents the lazy unfolding of a 64-bit ELF
- * file where the header, program header table and optional section header table
- * have been filled in, with all other data being left uninterpreted.
- *)
-type elf64_executable_file3 =
- <| elf64_executable_file3_header : elf64_header (** The ELF header (mandatory) *)
- ; elf64_executable_file3_program_header_table : elf64_program_header_table (** The program header table (mandatory) *)
- ; elf64_executable_file3_section_header_table : maybe elf64_section_header_table (** The section header table (optional) *)
- ; elf64_executable_file3_body : bitstring (** Uninterpreted body *)
- |>
-
-class (HasElf64ExecutableFile3 'a)
- val get_elf64_executable_file3 : 'a -> elf64_executable_file3
-end
-
-instance (HasElf64ExecutableFile3 elf64_executable_file3)
- let get_elf64_executable_file3 f3 = f3
-end
-
-instance (HasElf64ExecutableFile2 elf64_executable_file3)
- let get_elf64_executable_file2 f3 =
- <| elf64_executable_file2_header = f3.elf64_executable_file3_header;
- elf64_executable_file2_program_header_table = f3.elf64_executable_file3_program_header_table;
- elf64_executable_file2_body = f3.elf64_executable_file3_body |>
-end
-
-instance (HasElf64Header elf64_executable_file3)
- let get_elf64_header f3 = f3.elf64_executable_file3_header
-end
-
-instance (HasElf64ProgramHeaderTable elf64_executable_file3)
- let get_elf64_program_header_table f3 =
- Just (f3.elf64_executable_file3_program_header_table)
-end
-
-instance (HasElf64SectionHeaderTable elf64_executable_file3)
- let get_elf64_section_header_table f3 =
- f3.elf64_executable_file3_section_header_table
-end
-
-(** [refine_elf32_executable_file2 f2] refines an elf32_executable_file2 [f2] into
- * an elf32_executable_file3 by adding the optional section header table.
- *)
-val refine_elf32_executable_file2 : elf32_executable_file2 -> error elf32_executable_file3
-let refine_elf32_executable_file2 f2 =
- let hdr = f2.elf32_executable_file2_header in
- let pht = f2.elf32_executable_file2_program_header_table in
- let endian = get_elf32_header_endianness hdr in
- let bs1 = f2.elf32_executable_file2_body in
- let sentries = nat_of_elf32_half hdr.elf32_shnum in
- let sentry_size = nat_of_elf32_half hdr.elf32_shentsize * 8 in
- let ssize = sentries * sentry_size in
- if ssize = 0 then
- return <| elf32_executable_file3_header = hdr;
- elf32_executable_file3_program_header_table = pht;
- elf32_executable_file3_section_header_table = Nothing;
- elf32_executable_file3_body = bs1 |>
- else
- let soffset = nat_of_elf32_off hdr.elf32_shoff * 8 in
- let (_, scut) = partition soffset bs1 in
- let (sexact, _) = partition ssize scut in
- (* Bitstring irrelevant below as exact size used... *)
- read_elf32_section_header_table ssize endian sexact >>= fun (sht, _) ->
- return <| elf32_executable_file3_header = hdr;
- elf32_executable_file3_program_header_table = pht;
- elf32_executable_file3_section_header_table = Just sht;
- elf32_executable_file3_body = bs1 |>
-
-(** [refine_elf64_executable_file2 f2] refines an elf64_executable_file2 [f2] into
- * an elf64_executable_file3 by adding the optional section header table.
- *)
-val refine_elf64_executable_file2 : elf64_executable_file2 -> error elf64_executable_file3
-let refine_elf64_executable_file2 f2 =
- let hdr = f2.elf64_executable_file2_header in
- let pht = f2.elf64_executable_file2_program_header_table in
- let endian = get_elf64_header_endianness hdr in
- let bs1 = f2.elf64_executable_file2_body in
- let sentries = nat_of_elf64_half hdr.elf64_shnum in
- let sentry_size = nat_of_elf64_half hdr.elf64_shentsize * 8 in
- let ssize = sentries * sentry_size in
- if ssize = 0 then
- return <| elf64_executable_file3_header = hdr;
- elf64_executable_file3_program_header_table = pht;
- elf64_executable_file3_section_header_table = Nothing;
- elf64_executable_file3_body = bs1 |>
- else
- let soffset = nat_of_elf64_off hdr.elf64_shoff * 8 in
- let (_, scut) = partition soffset bs1 in
- let (sexact, _) = partition ssize scut in
- (* Bitstring irrelevant below as exact size used... *)
- read_elf64_section_header_table ssize endian sexact >>= fun (sht, _) ->
- return <| elf64_executable_file3_header = hdr;
- elf64_executable_file3_program_header_table = pht;
- elf64_executable_file3_section_header_table = Just sht;
- elf64_executable_file3_body = bs1 |>
-
-(** [read_elf32_executable_file3 bs0] reads an elf32_executable_file3 from
- * bitstring [bs0].
- *)
-val read_elf32_executable_file3 : bitstring -> error elf32_executable_file3
-let read_elf32_executable_file3 bs0 =
- read_elf32_executable_file2 bs0 >>= refine_elf32_executable_file2
-
-(** [read_elf64_executable_file3 bs0] reads an elf64_executable_file3 from
- * bitstring [bs0].
- *)
-val read_elf64_executable_file3 : bitstring -> error elf64_executable_file3
-let read_elf64_executable_file3 bs0 =
- read_elf64_executable_file2 bs0 >>= refine_elf64_executable_file2
-
-(** string_of_elf32_executable_file3 hdr_os hdr_proc pht_os pht_proc sht_oc sht_proc sht_user f3]
- * creates a string representation of [f3].
- *)
-val string_of_elf32_executable_file3 : hdr_print_bundle -> pht_print_bundle -> sht_print_bundle -> elf32_executable_file3 -> string
-let string_of_elf32_executable_file3 hdr_bdl pht_bdl sht_bdl f3 =
- let sht =
- match f3.elf32_executable_file3_section_header_table with
- | Nothing -> "\tNo section header table present"
- | Just sht -> string_of_elf32_section_header_table sht_bdl sht
- end
- in
- unlines [
- "\n*Type elf32_executable_file3:"
- ; "**Header:"
- ; string_of_elf32_header hdr_bdl f3.elf32_executable_file3_header
- ; "**Program header table:"
- ; string_of_elf32_program_header_table pht_bdl f3.elf32_executable_file3_program_header_table
- ; "**Section header table:"
- ; sht
- ; "**Body:"
- ; "\tUninterpreted data of length " ^ show (Bitstring.length f3.elf32_executable_file3_body)
- ]
-
-(** string_of_elf64_executable_file3 hdr_os hdr_proc pht_os pht_proc sht_oc sht_proc sht_user f3]
- * creates a string representation of [f3].
- *)
-val string_of_elf64_executable_file3 : hdr_print_bundle -> pht_print_bundle -> sht_print_bundle -> elf64_executable_file3 -> string
-let string_of_elf64_executable_file3 hdr_bdl pht_bdl sht_bdl f3 =
- let sht =
- match f3.elf64_executable_file3_section_header_table with
- | Nothing -> "\tNo section header table present"
- | Just sht -> string_of_elf64_section_header_table sht_bdl sht
- end
- in
- unlines [
- "\n*Type elf64_executable_file3:"
- ; "**Header:"
- ; string_of_elf64_header hdr_bdl f3.elf64_executable_file3_header
- ; "**Program header table:"
- ; string_of_elf64_program_header_table pht_bdl f3.elf64_executable_file3_program_header_table
- ; "**Section header table:"
- ; sht
- ; "**Body:"
- ; "\tUninterpreted data of length " ^ show (Bitstring.length f3.elf64_executable_file3_body)
- ]
-
-val get_elf32_section_header_string_table : elf32_executable_file3 -> error string_table
-let get_elf32_section_header_string_table f3 =
- let bs0 = f3.elf32_executable_file3_body in
- match f3.elf32_executable_file3_section_header_table with
- | Nothing -> return String_table.empty
- | Just sht ->
- let idx = nat_of_elf32_half f3.elf32_executable_file3_header.elf32_shstrndx in
- match List.index sht idx with
- | Nothing -> fail "get_elf32_string_table: invalid offset into section header table"
- | Just sect ->
- let offset = nat_of_elf32_off sect.elf32_sh_offset * 8 in
- let size = nat_of_elf32_word sect.elf32_sh_size * 8 in
- let (_, cut) = Bitstring.partition offset bs0 in
- let (rel, _) = Bitstring.partition size cut in
- let strings = Bitstring.string_of_bitstring rel in
- return (String_table.mk_string_table strings Missing_pervasives.null_char)
- end
- end
-
-val get_elf64_section_header_string_table : elf64_executable_file3 -> error string_table
-let get_elf64_section_header_string_table f3 =
- let bs0 = f3.elf64_executable_file3_body in
- match f3.elf64_executable_file3_section_header_table with
- | Nothing -> return String_table.empty
- | Just sht ->
- let idx = nat_of_elf64_half f3.elf64_executable_file3_header.elf64_shstrndx in
- match List.index sht idx with
- | Nothing -> fail "get_elf64_string_table: invalid offset into section header table"
- | Just sect ->
- let offset = nat_of_elf64_off sect.elf64_sh_offset * 8 in
- let size = nat_of_elf64_xword sect.elf64_sh_size * 8 in
- let (_, cut) = Bitstring.partition offset bs0 in
- let (rel, _) = Bitstring.partition size cut in
- let strings = Bitstring.string_of_bitstring rel in
- return (String_table.mk_string_table strings Missing_pervasives.null_char)
- end
- end
-
-val get_elf32_symbol_string_table : elf32_executable_file3 -> error string_table
-let get_elf32_symbol_string_table f3 =
- let bs0 = f3.elf32_executable_file3_body in
- let hdr = f3.elf32_executable_file3_header in
- match f3.elf32_executable_file3_section_header_table with
- | Nothing -> return String_table.empty
- | Just sht ->
- let strtabs = Missing_pervasives.mapMaybei (fun index sect ->
- if nat_of_elf32_word sect.elf32_sh_type = sht_strtab then
- if index = nat_of_elf32_half hdr.elf32_shstrndx then
- Nothing
- else
- Just sect
- else
- Nothing) sht
- in
- let strings = List.map (fun sect ->
- let offset = nat_of_elf32_off sect.elf32_sh_offset * 8 in
- let size = nat_of_elf32_word sect.elf32_sh_size * 8 in
- let bs1 = Bitstring.offset_and_cut offset size bs0 in
- let strings = Bitstring.string_of_bitstring bs1 in
- String_table.mk_string_table strings Missing_pervasives.null_char) strtabs
- in
- String_table.concat strings
- end
-
-val get_elf64_symbol_string_table : elf64_executable_file3 -> error string_table
-let get_elf64_symbol_string_table f3 =
- let bs0 = f3.elf64_executable_file3_body in
- let hdr = f3.elf64_executable_file3_header in
- match f3.elf64_executable_file3_section_header_table with
- | Nothing -> return String_table.empty
- | Just sht ->
- let strtabs = Missing_pervasives.mapMaybei (fun index sect ->
- if nat_of_elf64_word sect.elf64_sh_type = sht_strtab then
- if index = nat_of_elf64_half hdr.elf64_shstrndx then
- Nothing
- else
- Just sect
- else
- Nothing) sht
- in
- let strings = List.map (fun sect ->
- let offset = nat_of_elf64_off sect.elf64_sh_offset * 8 in
- let size = nat_of_elf64_xword sect.elf64_sh_size * 8 in
- let bs1 = Bitstring.offset_and_cut offset size bs0 in
- let strings = Bitstring.string_of_bitstring bs1 in
- String_table.mk_string_table strings Missing_pervasives.null_char) strtabs
- in
- String_table.concat strings
- end
-
-val get_elf32_interpreted_segments : elf32_executable_file3 -> error (list elf32_interpreted_segment)
-let get_elf32_interpreted_segments f3 =
- let pht = f3.elf32_executable_file3_program_header_table in
- let bdy = f3.elf32_executable_file3_body in
- let segs =
- List.map (fun ph ->
- let offset = nat_of_elf32_off ph.elf32_p_offset * 8 in
- let size = nat_of_elf32_word ph.elf32_p_filesz * 8 in
- let relevant = Bitstring.offset_and_cut offset size bdy in
- let vaddr = nat_of_elf32_addr ph.elf32_p_vaddr in
- let memsz = nat_of_elf32_word ph.elf32_p_memsz * 8 in
- let typ = nat_of_elf32_word ph.elf32_p_type in
- let flags = elf32_interpret_program_header_flags ph.elf32_p_flags in
- <| elf32_segment_body = relevant; elf32_segment_type = typ;
- elf32_segment_size = size; elf32_segment_memsz = memsz;
- elf32_segment_base = vaddr; elf32_segment_flags = flags |>
- ) pht
- in
- mapM (fun sg ->
- if sg.elf32_segment_memsz < sg.elf32_segment_size then
- fail "get_elf32_interpreted_segments: memory size of segment cannot be less than file size"
- else
- return sg) segs
-
-val get_elf64_interpreted_segments : elf64_executable_file3 -> error (list elf64_interpreted_segment)
-let get_elf64_interpreted_segments f3 =
- let pht = f3.elf64_executable_file3_program_header_table in
- let bdy = f3.elf64_executable_file3_body in
- let segs =
- List.map (fun ph ->
- let offset = nat_of_elf64_off ph.elf64_p_offset * 8 in
- let size = nat_of_elf64_xword ph.elf64_p_filesz * 8 in
- let relevant = Bitstring.offset_and_cut offset size bdy in
- let vaddr = nat_of_elf64_addr ph.elf64_p_vaddr in
- let memsz = nat_of_elf64_xword ph.elf64_p_memsz * 8 in
- let typ = nat_of_elf64_word ph.elf64_p_type in
- let flags = elf64_interpret_program_header_flags ph.elf64_p_flags in
- <| elf64_segment_body = relevant; elf64_segment_type = typ;
- elf64_segment_size = size; elf64_segment_memsz = memsz;
- elf64_segment_base = vaddr; elf64_segment_flags = flags |>
- ) pht
- in
- mapM (fun sg ->
- if sg.elf64_segment_memsz < sg.elf64_segment_size then
- fail "get_elf64_interpreted_segments: memory size of segment cannot be less than file size"
- else
- return sg) segs
-
-type executable_process_image =
- list (bitstring * nat) * nat
-
-val get_elf32_executable_image : elf32_executable_file3 -> error executable_process_image
-let get_elf32_executable_image f3 =
- let entr = f3.elf32_executable_file3_header.elf32_entry in
- get_elf32_interpreted_segments f3 >>= fun segs ->
- match List.filter (fun sg -> sg.elf32_segment_type = elf_pt_load) segs with
- | [] -> fail "get_elf32_executable_image: an executable ELF file must have at least one loadable segment"
- | load ->
- mapM (fun sg ->
- if sg.elf32_segment_memsz = 0 then
- return []
- else if sg.elf32_segment_memsz = sg.elf32_segment_size then
- return [(sg.elf32_segment_body, sg.elf32_segment_base)]
- else if sg.elf32_segment_size < sg.elf32_segment_memsz then
- (* Cannot be negative due to check in constructing [segs]. *)
- let diff = sg.elf32_segment_memsz - sg.elf32_segment_size in
- let zeros = Bitstring.zeros diff in
- let addr = sg.elf32_segment_base + sg.elf32_segment_size in
- return [(sg.elf32_segment_body, sg.elf32_segment_base); (zeros, addr)]
- else
- fail "get_elf32_executable_image: invariant invalidated") load >>= fun bs_base ->
- return (List.concat bs_base, nat_of_elf32_addr entr)
- end
-
-val get_elf64_executable_image : elf64_executable_file3 -> error executable_process_image
-let get_elf64_executable_image f3 =
- let entr = f3.elf64_executable_file3_header.elf64_entry in
- get_elf64_interpreted_segments f3 >>= fun segs ->
- match List.filter (fun sg -> sg.elf64_segment_type = elf_pt_load) segs with
- | [] -> fail "get_elf64_executable_image: an executable ELF file must have at least one loadable segment"
- | load ->
- mapM (fun sg ->
- if sg.elf64_segment_memsz = 0 then
- return []
- else if sg.elf64_segment_memsz = sg.elf64_segment_size then
- return [(sg.elf64_segment_body, sg.elf64_segment_base)]
- else if sg.elf64_segment_size < sg.elf64_segment_memsz then
- (* Cannot be negative due to check in constructing [segs]. *)
- let diff = sg.elf64_segment_memsz - sg.elf64_segment_size in
- let zeros = Bitstring.zeros diff in
- let addr = sg.elf64_segment_base + sg.elf64_segment_size in
- return [(sg.elf64_segment_body, sg.elf64_segment_base); (zeros, addr)]
- else
- fail "get_elf64_executable_image: invariant invalidated") load >>= fun bs_base ->
- return (List.concat bs_base, nat_of_elf64_addr entr)
- end
-
-val get_elf32_symbol_table : elf32_executable_file3 -> error elf32_symbol_table
-let get_elf32_symbol_table f3 =
- let bs0 = f3.elf32_executable_file3_body in
- let hdr = f3.elf32_executable_file3_header in
- let endian = get_elf32_header_endianness hdr in
- match f3.elf32_executable_file3_section_header_table with
- | Nothing -> return []
- | Just sects ->
- let symtabs = List.filter (fun sect ->
- nat_of_elf32_word sect.elf32_sh_type = sht_symtab) sects
- in
- if List.length symtabs = 0 then
- return []
- else if List.length symtabs = 1 then
- match List.index symtabs 0 with
- | Nothing -> fail "get_elf32_symbol_table: invariant failed"
- | Just symtab ->
- let offset = nat_of_elf32_off symtab.elf32_sh_offset * 8 in
- let size = nat_of_elf32_word symtab.elf32_sh_size * 8 in
- let relevant = Bitstring.offset_and_cut offset size bs0 in
- read_elf32_symbol_table endian relevant
- end
- else
- fail "get_elf32_symbol_table: an ELF file may only have one symbol table of type SHT_SYMTAB"
- end
-
-val get_elf64_symbol_table : elf64_executable_file3 -> error elf64_symbol_table
-let get_elf64_symbol_table f3 =
- let bs0 = f3.elf64_executable_file3_body in
- let hdr = f3.elf64_executable_file3_header in
- let endian = get_elf64_header_endianness hdr in
- match f3.elf64_executable_file3_section_header_table with
- | Nothing -> return []
- | Just sects ->
- let symtabs = List.filter (fun sect ->
- nat_of_elf64_word sect.elf64_sh_type = sht_symtab) sects
- in
- if List.length symtabs = 0 then
- return []
- else if List.length symtabs = 1 then
- match List.index symtabs 0 with
- | Nothing -> fail "get_elf64_symbol_table: invariant failed"
- | Just symtab ->
- let offset = nat_of_elf64_off symtab.elf64_sh_offset * 8 in
- let size = nat_of_elf64_xword symtab.elf64_sh_size * 8 in
- let relevant = Bitstring.offset_and_cut offset size bs0 in
- read_elf64_symbol_table endian relevant
- end
- else
- fail "get_elf64_symbol_table: an ELF file may only have one symbol table of type SHT_SYMTAB"
- end
-
-val get_elf32_dynamic_symbol_table : elf32_executable_file3 -> error elf32_symbol_table
-let get_elf32_dynamic_symbol_table f3 =
- let bs0 = f3.elf32_executable_file3_body in
- let hdr = f3.elf32_executable_file3_header in
- let endian = get_elf32_header_endianness hdr in
- match f3.elf32_executable_file3_section_header_table with
- | Nothing -> return []
- | Just sects ->
- let symtabs = List.filter (fun sect ->
- nat_of_elf32_word sect.elf32_sh_type = sht_dynsym) sects
- in
- if List.length symtabs = 0 then
- return []
- else if List.length symtabs = 1 then
- match List.index symtabs 0 with
- | Nothing -> fail "get_elf32_symbol_table: invariant failed"
- | Just symtab ->
- let offset = nat_of_elf32_off symtab.elf32_sh_offset * 8 in
- let size = nat_of_elf32_word symtab.elf32_sh_size * 8 in
- let relevant = Bitstring.offset_and_cut offset size bs0 in
- read_elf32_symbol_table endian relevant
- end
- else
- fail "get_elf32_symbol_table: an ELF file may only have one symbol table of type SHT_DYNSYM"
- end
-
-val get_elf64_dynamic_symbol_table : elf64_executable_file3 -> error elf64_symbol_table
-let get_elf64_dynamic_symbol_table f3 =
- let bs0 = f3.elf64_executable_file3_body in
- let hdr = f3.elf64_executable_file3_header in
- let endian = get_elf64_header_endianness hdr in
- match f3.elf64_executable_file3_section_header_table with
- | Nothing -> return []
- | Just sects ->
- let symtabs = List.filter (fun sect ->
- nat_of_elf64_word sect.elf64_sh_type = sht_dynsym) sects
- in
- if List.length symtabs = 0 then
- return []
- else if List.length symtabs = 1 then
- match List.index symtabs 0 with
- | Nothing -> fail "get_elf64_symbol_table: invariant failed"
- | Just symtab ->
- let offset = nat_of_elf64_off symtab.elf64_sh_offset * 8 in
- let size = nat_of_elf64_xword symtab.elf64_sh_size * 8 in
- let relevant = Bitstring.offset_and_cut offset size bs0 in
- read_elf64_symbol_table endian relevant
- end
- else
- fail "get_elf64_symbol_table: an ELF file may only have one symbol table of type SHT_DYNSYM"
- end \ No newline at end of file