summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile20
-rw-r--r--src/elf_model/Makefile68
-rw-r--r--src/elf_model/default_printing.lem27
-rw-r--r--src/elf_model/elf_executable_file3.lem296
-rw-r--r--src/elf_model/elf_file1.lem29
-rw-r--r--src/elf_model/elf_header.lem13
-rw-r--r--src/elf_model/elf_linking_file2.lem150
-rw-r--r--src/elf_model/elf_linking_file3.lem181
-rw-r--r--src/elf_model/elf_linking_file4.lem193
-rw-r--r--src/elf_model/elf_relocation.lem42
-rw-r--r--src/elf_model/elf_section_header.ml298
-rw-r--r--src/elf_model/elf_symbol_table.lem249
-rw-r--r--src/elf_model/elf_symbol_table.ml408
-rw-r--r--src/elf_model/elf_types.lem12
-rw-r--r--src/elf_model/libraries/Makefile23
-rw-r--r--src/elf_model/libraries/batteries-2.2.tar.gzbin0 -> 711616 bytes
-rw-r--r--src/elf_model/libraries/bitstring.tar.gzbin0 -> 163346 bytes
-rw-r--r--src/elf_model/libraries/uint.tar.gzbin0 -> 47759 bytes
-rw-r--r--src/elf_model/main.lem37
-rw-r--r--src/elf_model/missing_pervasives.lem23
-rw-r--r--src/elf_model/ml_bindings.ml1421
-rw-r--r--src/elf_model/ml_bindings_camlp4_sugared.ml323
-rw-r--r--src/elf_model/sail_interface.lem88
-rw-r--r--src/elf_model/show.lem14
-rw-r--r--src/elf_model/string_table.lem17
-rw-r--r--src/test/run_power.ml2
26 files changed, 3146 insertions, 788 deletions
diff --git a/src/Makefile b/src/Makefile
index 647df7f8..ab44b174 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -21,16 +21,22 @@ LEMLIB = ~/bitbucket/lem/ocaml-lib/_build/
install_elf:
cp -p ../../system-v-abi/src/*.lem elf_model/
cp -p ../../system-v-abi/src/*.ml elf_model/
+ cp -p -r ../../system-v-abi/src/libraries elf_model/libraries
-power: sail interpreter
- mkdir -p _build/test
+elf:
+ $(MAKE) -C elf_model ocaml_native
mkdir -p _build/elf_model
- cp -p test/* _build/test/
- cp -p elf_model/* _build/elf_model
+ cp -p elf_model/*.cmi _build/elf_model/
+ cp -p elf_model/*.cmx _build/elf_model/
+ cp -p elf_model/*.o _build/elf_model/
cd _build/elf_model ;\
- $(LEM) -ocaml -only_changed_output missing_pervasives.lem show.lem endianness.lem bitstring.lem elf_types.lem elf_interpreted_segment.lem elf_header.lem elf_file1.lem elf_program_header_table.lem elf_executable_file2.lem elf_section_header_table.lem elf_executable_file3.lem string_table.lem elf_executable_file4.lem elf_executable_file5.lem sail_interface.lem main.lem ;\
- ocamlfind ocamlopt -package bitstring.syntax -package batteries -package uint -package bitstring -syntax camlp4o -I $(LEMLIB) nat_num.cmx lem.cmx lem_function.cmx lem_list.cmx -linkpkg missing_pervasives.ml show.ml endianness.ml error.ml ml_bindings.ml bitstring_local.ml elf_types.ml elf_header.ml elf_file1.ml elf_program_header_table.ml elf_executable_file2.ml string_table.ml elf_section_header_table.ml elf_executable_file3.ml elf_executable_file4.ml elf_interpreted_segment.ml elf_executable_file5.ml sail_interface.ml main.ml ;\
- ocamlfind ocamlopt -package batteries -package uint -package bitstring -I $(LEMLIB) -a -o elf_extract.cmxa missing_pervasives.cmx show.cmx endianness.cmx error.cmx ml_bindings.cmx bitstring_local.cmx elf_types.cmx elf_header.cmx elf_file1.cmx elf_program_header_table.cmx elf_executable_file2.cmx string_table.cmx elf_section_header_table.cmx elf_executable_file3.cmx elf_executable_file4.cmx elf_interpreted_segment.cmx elf_executable_file5.cmx sail_interface.cmx
+ ocamlfind ocamlopt -package batteries -package uint -package bitstring -I $(LEMLIB) -a -o elf_extract.cmxa missing_pervasives.cmx \
+show.cmx endianness.cmx error.cmx ml_bindings.cmx default_printing.cmx bitstring_local.cmx elf_types.cmx elf_header.cmx elf_file1.cmx elf_program_header_table.cmx elf_executable_file2.cmx string_table.cmx elf_section_header_table.cmx elf_interpreted_segment.cmx elf_symbol_table.cmx elf_executable_file3.cmx elf_linking_file2.cmx elf_linking_file3.cmx elf_relocation.cmx sail_interface.cmx
+
+
+power: sail interpreter elf
+ mkdir -p _build/test
+ cp -p test/* _build/test/
cd _build/test ;\
../../sail.native -lem_ast power.sail ;\
$(LEM) -ocaml -only_changed_output -lib ../lem_interp/ power.lem;\
diff --git a/src/elf_model/Makefile b/src/elf_model/Makefile
index 42e17cce..dbf653f6 100644
--- a/src/elf_model/Makefile
+++ b/src/elf_model/Makefile
@@ -1,19 +1,76 @@
dummy: all
lem-model:
- ../../lem/lem -ocaml -only_changed_output missing_pervasives.lem show.lem endianness.lem bitstring.lem elf_types.lem elf_interpreted_segment.lem elf_header.lem elf_file1.lem elf_program_header_table.lem elf_executable_file2.lem elf_section_header_table.lem elf_executable_file3.lem string_table.lem elf_executable_file4.lem elf_executable_file5.lem sail_interface.lem main.lem
+ ../../lem/lem -ocaml -only_changed_output missing_pervasives.lem show.lem endianness.lem default_printing.lem bitstring.lem elf_types.lem elf_interpreted_segment.lem elf_symbol_table.lem elf_header.lem elf_file1.lem elf_program_header_table.lem elf_executable_file2.lem elf_section_header_table.lem elf_executable_file3.lem string_table.lem elf_linking_file2.lem elf_linking_file3.lem elf_relocation.lem sail_interface.lem main.lem
clean:
- rm missing_pervasives.ml show.ml endianness.ml bitstring_local.ml elf_types.ml elf_header.ml elf_file1.ml elf_program_header_table.ml elf_executable_file2.ml elf_section_header_table.ml elf_executable_file3.ml string_table.ml elf_executable_file4.ml elf_interpreted_segment.ml elf_executable_file5.ml sail_interface.ml main.ml
+ rm -rf missing_pervasives.ml show.ml endianness.ml bitstring_local.ml default_printing.ml elf_types.ml elf_header.ml elf_file1.ml elf_program_header_table.ml elf_executable_file2.ml elf_section_header_table.ml elf_executable_file3.ml string_table.ml elf_interpreted_segment.ml elf_symbol_table.ml elf_executable_file5.ml elf_linking_file2.ml elf_linking_file3.ml elf_relocation.ml elf_symbol_table.ml sail_interface.ml main.ml
+ make -C libraries clean
+ rm -rf elf_section_header.ml elf_symbol_table.ml
+ rm -rf *~
+ rm -rf *.cmi *.cmo
+
+camlp4:
+ camlp4 '-I' '/home/dpm/.opam/4.01.0/lib/ocaml/camlp4' '-I' '/home/dpm/.opam/4.01.0/lib/bitstring' '-parser' 'o' '-parser' 'op' '-printer' 'p' 'unix.cma' 'bitstring.cma' 'bitstring_persistent.cma' 'pa_bitstring.cmo' pa_o.cmo pr_o.cmo -oml_bindings.ml 'ml_bindings_camlp4_sugared.ml'
+
+
ocaml:
- ocamlfind ocamlc -package bitstring.syntax -package batteries -package uint -syntax camlp4o -I ../../lem/ocaml-lib/_build/ unix.cma bitstring.cma nums.cma nat_num.cmo lem.cmo lem_function.cmo lem_list.cmo -linkpkg missing_pervasives.ml show.ml endianness.ml error.ml ml_bindings.ml bitstring_local.ml elf_types.ml elf_header.ml elf_file1.ml elf_program_header_table.ml elf_executable_file2.ml string_table.ml elf_section_header_table.ml elf_executable_file3.ml elf_executable_file4.ml elf_interpreted_segment.ml elf_executable_file5.ml sail_interface.ml main.ml
+ ocamlfind ocamlc \
+-I libraries/batteries/_build/src \
+-I libraries/bitstring \
+-I libraries/uint/_build/lib \
+-I ../../lem/ocaml-lib/_build/ \
+unix.cma nums.cma batteries.cma uint.cma bitstring.cma nat_num.cmo \
+lem.cmo lem_function.cmo lem_list.cmo \
+missing_pervasives.ml \
+show.ml endianness.ml error.ml ml_bindings.ml default_printing.ml bitstring_local.ml elf_types.ml elf_header.ml elf_file1.ml elf_program_header_table.ml elf_executable_file2.ml string_table.ml elf_section_header_table.ml elf_interpreted_segment.ml elf_symbol_table.ml elf_executable_file3.ml elf_linking_file2.ml elf_linking_file3.ml elf_relocation.ml sail_interface.ml main.ml \
+-dllpath libraries/uint/_build/lib -dllpath libraries/bitstring -package bitstring -package uint -package batteries
+
+ocaml_native:
+ ocamlfind ocamlopt \
+-I ../../../lem/ocaml-lib/_build/ \
+-package bitstring -package uint -package batteries \
+nums.cmxa unix.cmxa batteries.cmxa uint.cmxa bitstring.cmxa ../../../lem/ocaml-lib/_build/extract.cmxa \
+missing_pervasives.ml \
+show.ml endianness.ml error.ml ml_bindings.ml default_printing.ml bitstring_local.ml elf_types.ml elf_header.ml elf_file1.ml elf_program_header_table.ml elf_executable_file2.ml string_table.ml elf_section_header_table.ml elf_interpreted_segment.ml elf_symbol_table.ml elf_executable_file3.ml elf_linking_file2.ml elf_linking_file3.ml elf_relocation.ml sail_interface.ml main.ml
+
+
+ocaml_with_ocamlbuild:
+ ocamlbuild -classic-display \
+ -X libraries -X ocaml-obsolete \
+ -cflag -g \
+ -cflags -I,libraries/batteries/_build_src \
+ -cflags -I,../libraries/bitstring \
+ -cflags -I,libraries/uint/_build/lib \
+ -cflags -dllpath,libraries/uint/_build/lib \
+ -cflags -dllpath,libraries/bitstring \
+ main.byte
+
+ocaml_with_ocamlbuild_native:
+ ocamlbuild -classic-display \
+ -X libraries -X ocaml-obsolete \
+ -cflag -g \
+ -cflags -I,../../../../lem/ocaml-lib/_build/ \
+ -cflags -I,libraries/batteries/_build_src \
+ -cflags -I,libraries/bitstring \
+ -cflags -I,libraries/uint/_build/lib \
+ -cflags -dllpath,libraries/uint/_build/lib \
+ -cflags -dllpath,libraries/bitstring \
+ main.native
+
+
+clean_with_ocamlbuild:
+ ocamlbuild -classic-display -clean
+
stacktrace:
export OCAMLRUNPARAM=b
- ocamlfind ocamlc -package bitstring.syntax -package batteries -syntax camlp4o -I ../../lem/ocaml-lib/_build/ unix.cma bitstring.cma nums.cma nat_num.cmo lem.cmo lem_function.cmo lem_list.cmo -linkpkg -g missing_pervasives.ml show.ml endianness.ml error.ml ml_bindings.ml bitstring_local.ml elf_types.ml elf_header.ml elf_file1.ml elf_program_header_table.ml elf_executable_file2.ml string_table.ml elf_section_header_table.ml elf_executable_file3.ml elf_executable_file4.ml elf_interpreted_segment.ml elf_executable_file5.ml sail_interface.ml main.ml
+ ocamlfind ocamlc -package bitstring -package batteries -I ../../lem/ocaml-lib/_build/ unix.cma bitstring.cma nums.cma nat_num.cmo lem.cmo lem_function.cmo lem_list.cmo -linkpkg -g missing_pervasives.ml show.ml endianness.ml error.ml ml_bindings.ml default_printing.ml bitstring_local.ml elf_types.ml elf_header.ml elf_file1.ml elf_program_header_table.ml elf_executable_file2.ml string_table.ml elf_section_header_table.ml elf_interpreted_segment.ml elf_symbol_table.ml elf_executable_file3.ml elf_executable_file5.ml elf_linking_file2.ml elf_linking_file3.ml elf_relocation.ml sail_interface.ml main.ml
+
+oldall: lem-model camlp4 ocaml
-all: lem-model ocaml
+all: ocaml
execute:
./a.out
@@ -21,4 +78,3 @@ execute:
go: all execute
go-debug: lem-model stacktrace execute
-
diff --git a/src/elf_model/default_printing.lem b/src/elf_model/default_printing.lem
new file mode 100644
index 00000000..d22e0fec
--- /dev/null
+++ b/src/elf_model/default_printing.lem
@@ -0,0 +1,27 @@
+(** [default_printing] module is a small utility module providing default
+ * printing functions for when ABI-specific functions are not available.
+ * These functions were constantly being redefined and reused all over the
+ * place hence their placement in this module.
+ *)
+open import Function
+
+(** [default_os_specific_print] is a default print function for OS specific
+ * functionality.
+ *)
+val default_os_specific_print : forall 'a. 'a -> string
+let default_os_specific_print =
+ (const "*Default OS specific print*")
+
+(** [default_proc_specific_print] is a default print function for processor specific
+ * functionality.
+ *)
+val default_proc_specific_print : forall 'a. 'a -> string
+let default_proc_specific_print =
+ (const "*Default processor specific print*")
+
+(** [default_user_specific_print] is a default print function for user specific
+ * functionality.
+ *)
+val default_user_specific_print : forall 'a. 'a -> string
+let default_user_specific_print =
+ (const "*Default user specific print*") \ No newline at end of file
diff --git a/src/elf_model/elf_executable_file3.lem b/src/elf_model/elf_executable_file3.lem
index 07a2fdc1..56b2b611 100644
--- a/src/elf_model/elf_executable_file3.lem
+++ b/src/elf_model/elf_executable_file3.lem
@@ -5,9 +5,12 @@ 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
@@ -208,4 +211,295 @@ let string_of_elf64_executable_file3 hdr_bdl pht_bdl sht_bdl f3 =
; sht
; "**Body:"
; "\tUninterpreted data of length " ^ show (Bitstring.length f3.elf64_executable_file3_body)
- ] \ No newline at end of file
+ ]
+
+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
diff --git a/src/elf_model/elf_file1.lem b/src/elf_model/elf_file1.lem
index ff2bba61..16ad63a3 100644
--- a/src/elf_model/elf_file1.lem
+++ b/src/elf_model/elf_file1.lem
@@ -1,4 +1,5 @@
open import Basic_classes
+open import Bool
open import String
open import Endianness
@@ -101,6 +102,34 @@ val is_shared_object_elf64_file1 : elf64_file1 -> bool
let is_shared_object_elf64_file1 f1 =
nat_of_elf64_half f1.elf64_file1_header.elf64_type = elf_ft_dyn
+(** [is_relocatable_elf32_file1] tests whether the ELF file is a relocatable
+* file type.
+*)
+val is_relocatable_elf32_file1 : elf32_file1 -> bool
+let is_relocatable_elf32_file1 f1 =
+ nat_of_elf32_half f1.elf32_file1_header.elf32_type = elf_ft_rel
+
+(** [is_relocatable_elf64_file1] tests whether the ELF file is a relocatable
+* file type.
+*)
+val is_relocatable_elf64_file1 : elf64_file1 -> bool
+let is_relocatable_elf64_file1 f1 =
+ nat_of_elf64_half f1.elf64_file1_header.elf64_type = elf_ft_rel
+
+(** [is_linkable_elf32_file1] tests whether the ELF file is a linkable (shared
+ * object or relocatable) file type.
+ *)
+val is_linkable_elf32_file1 : elf32_file1 -> bool
+let is_linkable_elf32_file1 f1 =
+ is_shared_object_elf32_file1 f1 || is_relocatable_elf32_file1 f1
+
+(** [is_linkable_elf64_file1] tests whether the ELF file is a linkable (shared
+ * object or relocatable) file type.
+ *)
+val is_linkable_elf64_file1 : elf64_file1 -> bool
+let is_linkable_elf64_file1 f1 =
+ is_shared_object_elf64_file1 f1 || is_relocatable_elf64_file1 f1
+
(** [read_elf32_file1 bs] lazily unfolds [bs] revealing the ELF file's header,
* leaving all other data uninterpreted.
*)
diff --git a/src/elf_model/elf_header.lem b/src/elf_model/elf_header.lem
index 35aa4a37..3fbe0af9 100644
--- a/src/elf_model/elf_header.lem
+++ b/src/elf_model/elf_header.lem
@@ -6,6 +6,7 @@ open import Maybe
open import Num
open import String
+open import Default_printing
open import Endianness
open import Elf_types
@@ -89,6 +90,8 @@ let elf_ma_386 : nat = 3
let elf_ma_ppc : nat = 20
(** IBM PowerPC 64 *)
let elf_ma_ppc64 : nat = 21
+(** AMD x86-64 *)
+let elf_ma_x86_64 : nat = 62
(** [string_of_elf_machine_architecture m] produces a string representation of
* the numeric encoding [m] of the ELF machine architecture.
@@ -101,6 +104,8 @@ let string_of_elf_machine_architecture m =
"IBM PowerPC"
else if m = elf_ma_ppc64 then
"IBM PowerPC 64"
+ else if m = elf_ma_x86_64 then
+ "AMD x86-64"
else
"Other architecture"
@@ -651,14 +656,14 @@ let string_of_elf64_header (os, proc) hdr =
val string_of_elf32_header_default : elf32_header -> string
let string_of_elf32_header_default =
string_of_elf32_header
- ((const "*Default OS specific print*"),
- (const "*Default processor specific print*"))
+ (default_os_specific_print,
+ default_proc_specific_print)
val string_of_elf64_header_default : elf64_header -> string
let string_of_elf64_header_default =
string_of_elf64_header
- ((const "*Default OS specific print*"),
- (const "*Default processor specific print*"))
+ (default_os_specific_print,
+ default_proc_specific_print)
instance (Show elf32_header)
let show = string_of_elf32_header_default
diff --git a/src/elf_model/elf_linking_file2.lem b/src/elf_model/elf_linking_file2.lem
index df69b5c9..4242f8d6 100644
--- a/src/elf_model/elf_linking_file2.lem
+++ b/src/elf_model/elf_linking_file2.lem
@@ -1,13 +1,149 @@
+open import Basic_classes
+open import Bool
+open import Maybe
+open import Num
+
open import Bitstring
+open import Error
+open import Missing_pervasives
+open import Show
+open import String
+open import Elf_file1
open import Elf_header
open import Elf_section_header_table
-
-open import Maybe
+open import Elf_types
type elf32_linking_file2 =
- <| elf32_executable_file2_header : elf32_header
- ; elf32_executable_file2_program_header_table : maybe elf32_program_header_table
- ; elf32_executable_file2_body : bitstring
- ; elf32_executable_file2_section_header_table : elf32_section_header_table
- |> \ No newline at end of file
+ <| elf32_linking_file2_header : elf32_header
+ ; elf32_linking_file2_body : bitstring
+ ; elf32_linking_file2_section_header_table : elf32_section_header_table
+ |>
+
+class (HasElf32LinkingFile2 'a)
+ val get_elf32_linking_file2 : 'a -> elf32_linking_file2
+end
+
+instance (HasElf32LinkingFile2 elf32_linking_file2)
+ let get_elf32_linking_file2 f2 = f2
+end
+
+instance (HasElf32File1 elf32_linking_file2)
+ let get_elf32_file1 f2 =
+ <| elf32_file1_header = f2.elf32_linking_file2_header;
+ elf32_file1_body = f2.elf32_linking_file2_body |>
+end
+
+instance (HasElf32Header elf32_linking_file2)
+ let get_elf32_header f2 = f2.elf32_linking_file2_header
+end
+
+instance (HasElf32SectionHeaderTable elf32_linking_file2)
+ let get_elf32_section_header_table f2 = Just f2.elf32_linking_file2_section_header_table
+end
+
+type elf64_linking_file2 =
+ <| elf64_linking_file2_header : elf64_header
+ ; elf64_linking_file2_body : bitstring
+ ; elf64_linking_file2_section_header_table : elf64_section_header_table
+ |>
+
+class (HasElf64LinkingFile2 'a)
+ val get_elf64_linking_file2 : 'a -> elf64_linking_file2
+end
+
+instance (HasElf64LinkingFile2 elf64_linking_file2)
+ let get_elf64_linking_file2 f2 = f2
+end
+
+instance (HasElf64File1 elf64_linking_file2)
+ let get_elf64_file1 f2 =
+ <| elf64_file1_header = f2.elf64_linking_file2_header;
+ elf64_file1_body = f2.elf64_linking_file2_body |>
+end
+
+instance (HasElf64Header elf64_linking_file2)
+ let get_elf64_header f2 = f2.elf64_linking_file2_header
+end
+
+instance (HasElf64SectionHeaderTable elf64_linking_file2)
+ let get_elf64_section_header_table f2 = Just f2.elf64_linking_file2_section_header_table
+end
+
+val refine_elf32_file1 : elf32_file1 -> error elf32_linking_file2
+let refine_elf32_file1 f1 =
+ if not (is_linkable_elf32_file1 f1) then
+ fail "refine_elf32_file1: not a linkable file"
+ else
+ let hdr = f1.elf32_file1_header in
+ let endian = get_elf32_header_endianness hdr in
+ let bs1 = f1.elf32_file1_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
+ fail "refine_elf32_file1: section header table not present"
+ 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_linking_file2_header = hdr;
+ elf32_linking_file2_body = bs1;
+ elf32_linking_file2_section_header_table = sht |>
+
+val read_elf32_linking_file2 : bitstring -> error elf32_linking_file2
+let read_elf32_linking_file2 bs0 =
+ read_elf32_file1 bs0 >>= refine_elf32_file1
+
+val string_of_elf32_linking_file2 : hdr_print_bundle -> sht_print_bundle -> elf32_linking_file2 -> string
+let string_of_elf32_linking_file2 hdr_bdl sht_bdl f2 =
+ unlines [
+ "\n*Type elf32_linking_file2:"
+ ; "**Header:"
+ ; string_of_elf32_header hdr_bdl f2.elf32_linking_file2_header
+ ; "**Program header table:"
+ ; string_of_elf32_section_header_table sht_bdl f2.elf32_linking_file2_section_header_table
+ ; "**Body:"
+ ; "\tUninterpreted data of length " ^ show (Bitstring.length f2.elf32_linking_file2_body)
+ ]
+
+val refine_elf64_file1 : elf64_file1 -> error elf64_linking_file2
+let refine_elf64_file1 f1 =
+ if not (is_linkable_elf64_file1 f1) then
+ fail "refine_elf64_file1: not a linkable file"
+ else
+ let hdr = f1.elf64_file1_header in
+ let endian = get_elf64_header_endianness hdr in
+ let bs1 = f1.elf64_file1_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
+ fail "refine_elf64_file1: section header table not present"
+ 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_linking_file2_header = hdr;
+ elf64_linking_file2_body = bs1;
+ elf64_linking_file2_section_header_table = sht |>
+
+val read_elf64_linking_file2 : bitstring -> error elf64_linking_file2
+let read_elf64_linking_file2 bs0 =
+ read_elf64_file1 bs0 >>= refine_elf64_file1
+
+val string_of_elf64_linking_file2 : hdr_print_bundle -> sht_print_bundle -> elf64_linking_file2 -> string
+let string_of_elf64_linking_file2 hdr_bdl sht_bdl f2 =
+ unlines [
+ "\n*Type elf64_linking_file2:"
+ ; "**Header:"
+ ; string_of_elf64_header hdr_bdl f2.elf64_linking_file2_header
+ ; "**Program header table:"
+ ; string_of_elf64_section_header_table sht_bdl f2.elf64_linking_file2_section_header_table
+ ; "**Body:"
+ ; "\tUninterpreted data of length " ^ show (Bitstring.length f2.elf64_linking_file2_body)
+ ] \ No newline at end of file
diff --git a/src/elf_model/elf_linking_file3.lem b/src/elf_model/elf_linking_file3.lem
new file mode 100644
index 00000000..edb97be4
--- /dev/null
+++ b/src/elf_model/elf_linking_file3.lem
@@ -0,0 +1,181 @@
+open import Basic_classes
+open import Maybe
+open import Num
+
+open import Bitstring
+open import Error
+open import Missing_pervasives
+open import Show
+open import String
+
+open import Elf_header
+open import Elf_linking_file2
+open import Elf_program_header_table
+open import Elf_section_header_table
+open import Elf_types
+
+type elf32_linking_file3 =
+ <| elf32_linking_file3_header : elf32_header
+ ; elf32_linking_file3_program_header_table : maybe elf32_program_header_table
+ ; elf32_linking_file3_body : bitstring
+ ; elf32_linking_file3_section_header_table : elf32_section_header_table
+ |>
+
+class (HasElf32LinkingFile3 'a)
+ val get_elf32_linking_file3 : 'a -> elf32_linking_file3
+end
+
+instance (HasElf32LinkingFile3 elf32_linking_file3)
+ let get_elf32_linking_file3 f3 = f3
+end
+
+instance (HasElf32LinkingFile2 elf32_linking_file3)
+ let get_elf32_linking_file2 f3 =
+ <| elf32_linking_file2_header = f3.elf32_linking_file3_header;
+ elf32_linking_file2_body = f3.elf32_linking_file3_body;
+ elf32_linking_file2_section_header_table = f3.elf32_linking_file3_section_header_table |>
+end
+
+instance (HasElf32Header elf32_linking_file3)
+ let get_elf32_header f3 = f3.elf32_linking_file3_header
+end
+
+instance (HasElf32SectionHeaderTable elf32_linking_file3)
+ let get_elf32_section_header_table f3 = Just f3.elf32_linking_file3_section_header_table
+end
+
+instance (HasElf32ProgramHeaderTable elf32_linking_file3)
+ let get_elf32_program_header_table f3 = f3.elf32_linking_file3_program_header_table
+end
+
+val refine_elf32_linking_file2 : elf32_linking_file2 -> error elf32_linking_file3
+let refine_elf32_linking_file2 f2 =
+ let hdr = f2.elf32_linking_file2_header in
+ let sht = f2.elf32_linking_file2_section_header_table in
+ let endian = get_elf32_header_endianness hdr in
+ let bs1 = f2.elf32_linking_file2_body in
+ let pentries = nat_of_elf32_half hdr.elf32_phnum in
+ let pentry_size = nat_of_elf32_half hdr.elf32_phentsize * 8 in
+ let psize = pentries * pentry_size in
+ if psize = 0 then
+ return <| elf32_linking_file3_header = hdr;
+ elf32_linking_file3_program_header_table = Nothing;
+ elf32_linking_file3_section_header_table = sht;
+ elf32_linking_file3_body = bs1 |>
+ else
+ let poffset = nat_of_elf32_off hdr.elf32_phoff * 8 in
+ let (_, pcut) = partition poffset bs1 in
+ let (pexact, _) = partition psize pcut in
+ (* Bitstring irrelevant below as exact size used... *)
+ read_elf32_program_header_table psize endian pexact >>= fun (pht, _) ->
+ return <| elf32_linking_file3_header = hdr;
+ elf32_linking_file3_program_header_table = Just pht;
+ elf32_linking_file3_section_header_table = sht;
+ elf32_linking_file3_body = bs1 |>
+
+val read_elf32_linking_file3 : bitstring -> error elf32_linking_file3
+let read_elf32_linking_file3 bs0 =
+ read_elf32_linking_file2 bs0 >>= refine_elf32_linking_file2
+
+val string_of_elf32_linking_file3 : hdr_print_bundle -> sht_print_bundle -> pht_print_bundle -> elf32_linking_file3 -> string
+let string_of_elf32_linking_file3 hdr_bdl sht_bdl pht_bdl f3 =
+ let pht =
+ match f3.elf32_linking_file3_program_header_table with
+ | Nothing -> "\tNo program header table present"
+ | Just pht -> string_of_elf32_program_header_table pht_bdl pht
+ end
+ in
+ unlines [
+ "\n*Type elf32_linking_file3:"
+ ; "**Header:"
+ ; string_of_elf32_header hdr_bdl f3.elf32_linking_file3_header
+ ; "**Program header table:"
+ ; pht
+ ; "**Section header table:"
+ ; string_of_elf32_section_header_table sht_bdl f3.elf32_linking_file3_section_header_table
+ ; "**Body:"
+ ; "\tUninterpreted data of length " ^ show (Bitstring.length f3.elf32_linking_file3_body)
+ ]
+
+type elf64_linking_file3 =
+ <| elf64_linking_file3_header : elf64_header
+ ; elf64_linking_file3_program_header_table : maybe elf64_program_header_table
+ ; elf64_linking_file3_body : bitstring
+ ; elf64_linking_file3_section_header_table : elf64_section_header_table
+ |>
+
+class (HasElf64LinkingFile3 'a)
+ val get_elf64_linking_file3 : 'a -> elf64_linking_file3
+end
+
+instance (HasElf64LinkingFile3 elf64_linking_file3)
+ let get_elf64_linking_file3 f3 = f3
+end
+
+instance (HasElf64LinkingFile2 elf64_linking_file3)
+ let get_elf64_linking_file2 f3 =
+ <| elf64_linking_file2_header = f3.elf64_linking_file3_header;
+ elf64_linking_file2_body = f3.elf64_linking_file3_body;
+ elf64_linking_file2_section_header_table = f3.elf64_linking_file3_section_header_table |>
+end
+
+instance (HasElf64Header elf64_linking_file3)
+ let get_elf64_header f3 = f3.elf64_linking_file3_header
+end
+
+instance (HasElf64SectionHeaderTable elf64_linking_file3)
+ let get_elf64_section_header_table f3 = Just f3.elf64_linking_file3_section_header_table
+end
+
+instance (HasElf64ProgramHeaderTable elf64_linking_file3)
+ let get_elf64_program_header_table f3 = f3.elf64_linking_file3_program_header_table
+end
+
+val refine_elf64_linking_file2 : elf64_linking_file2 -> error elf64_linking_file3
+let refine_elf64_linking_file2 f2 =
+ let hdr = f2.elf64_linking_file2_header in
+ let sht = f2.elf64_linking_file2_section_header_table in
+ let endian = get_elf64_header_endianness hdr in
+ let bs1 = f2.elf64_linking_file2_body in
+ let pentries = nat_of_elf64_half hdr.elf64_phnum in
+ let pentry_size = nat_of_elf64_half hdr.elf64_phentsize * 8 in
+ let psize = pentries * pentry_size in
+ if psize = 0 then
+ return <| elf64_linking_file3_header = hdr;
+ elf64_linking_file3_program_header_table = Nothing;
+ elf64_linking_file3_section_header_table = sht;
+ elf64_linking_file3_body = bs1 |>
+ else
+ let poffset = nat_of_elf64_off hdr.elf64_phoff * 8 in
+ let (_, pcut) = partition poffset bs1 in
+ let (pexact, _) = partition psize pcut in
+ (* Bitstring irrelevant below as exact size used... *)
+ read_elf64_program_header_table psize endian pexact >>= fun (pht, _) ->
+ return <| elf64_linking_file3_header = hdr;
+ elf64_linking_file3_program_header_table = Just pht;
+ elf64_linking_file3_section_header_table = sht;
+ elf64_linking_file3_body = bs1 |>
+
+val read_elf64_linking_file3 : bitstring -> error elf64_linking_file3
+let read_elf64_linking_file3 bs0 =
+ read_elf64_linking_file2 bs0 >>= refine_elf64_linking_file2
+
+val string_of_elf64_linking_file3 : hdr_print_bundle -> sht_print_bundle -> pht_print_bundle -> elf64_linking_file3 -> string
+let string_of_elf64_linking_file3 hdr_bdl sht_bdl pht_bdl f3 =
+ let pht =
+ match f3.elf64_linking_file3_program_header_table with
+ | Nothing -> "\tNo program header table present"
+ | Just pht -> string_of_elf64_program_header_table pht_bdl pht
+ end
+ in
+ unlines [
+ "\n*Type elf64_linking_file3:"
+ ; "**Header:"
+ ; string_of_elf64_header hdr_bdl f3.elf64_linking_file3_header
+ ; "**Program header table:"
+ ; pht
+ ; "**Section header table:"
+ ; string_of_elf64_section_header_table sht_bdl f3.elf64_linking_file3_section_header_table
+ ; "**Body:"
+ ; "\tUninterpreted data of length " ^ show (Bitstring.length f3.elf64_linking_file3_body)
+ ] \ No newline at end of file
diff --git a/src/elf_model/elf_linking_file4.lem b/src/elf_model/elf_linking_file4.lem
new file mode 100644
index 00000000..15528696
--- /dev/null
+++ b/src/elf_model/elf_linking_file4.lem
@@ -0,0 +1,193 @@
+open import Maybe
+open import Num
+
+open import Bitstring
+open import Error
+open import Missing_pervasives
+open import Show
+open import String
+
+open import Elf_header
+open import Elf_linking_file3
+open import Elf_types
+open import Elf_program_header_table
+open import Elf_section_header_table
+open import String_table
+
+type elf32_linking_file4 =
+ <| elf32_linking_file4_header : elf32_header
+ ; elf32_linking_file4_program_header_table : maybe elf32_program_header_table
+ ; elf32_linking_file4_body : bitstring
+ ; elf32_linking_file4_section_header_table : elf32_section_header_table
+ ; elf32_linking_file4_section_header_string_table : string_table
+ |>
+
+class (HasElf32LinkingFile4 'a)
+ val get_elf32_linking_file4 : 'a -> elf32_linking_file4
+end
+
+instance (HasElf32LinkingFile4 elf32_linking_file4)
+ let get_elf32_linking_file4 f4 = f4
+end
+
+instance (HasElf32LinkingFile3 elf32_linking_file4)
+ let get_elf32_linking_file3 f4 =
+ <| elf32_linking_file3_header = f4.elf32_linking_file4_header;
+ elf32_linking_file3_program_header_table = f4.elf32_linking_file4_program_header_table;
+ elf32_linking_file3_body = f4.elf32_linking_file4_body;
+ elf32_linking_file3_section_header_table = f4.elf32_linking_file4_section_header_table |>
+end
+
+instance (HasElf32Header elf32_linking_file4)
+ let get_elf32_header f4 = f4.elf32_linking_file4_header
+end
+
+instance (HasElf32ProgramHeaderTable elf32_linking_file4)
+ let get_elf32_program_header_table f4 = f4.elf32_linking_file4_program_header_table
+end
+
+instance (HasElf32SectionHeaderTable elf32_linking_file4)
+ let get_elf32_section_header_table f4 = Just f4.elf32_linking_file4_section_header_table
+end
+
+instance (HasElf32SectionHeaderStringTable elf32_linking_file4)
+ let get_elf32_section_header_string_table f4 = f4.elf32_linking_file4_section_header_string_table
+end
+
+val refine_elf32_linking_file3 : elf32_linking_file3 -> error elf32_linking_file4
+let refine_elf32_linking_file3 f3 =
+ let hdr = f3.elf32_linking_file3_header in
+ let pht = f3.elf32_linking_file3_program_header_table in
+ let sht = f3.elf32_linking_file3_section_header_table in
+ let bs0 = f3.elf32_linking_file3_body in
+ let idx = nat_of_elf32_half hdr.elf32_shstrndx in
+ let sect = List.index sht idx in
+ match sect with
+ | Nothing -> fail "refine_elf32_linking_file3: 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 <| elf32_linking_file4_header = hdr;
+ elf32_linking_file4_program_header_table = pht;
+ elf32_linking_file4_section_header_table = sht;
+ elf32_linking_file4_section_header_string_table = String_table.mk_string_table strings Missing_pervasives.null_char;
+ elf32_linking_file4_body = bs0 |>
+ end
+
+val read_elf32_linking_file4 : bitstring -> error elf32_linking_file4
+let read_elf32_linking_file4 bs0 =
+ read_elf32_linking_file3 bs0 >>= refine_elf32_linking_file3
+
+val string_of_elf32_linking_file4 : hdr_print_bundle -> sht_print_bundle -> pht_print_bundle -> elf32_linking_file4 -> string
+let string_of_elf32_linking_file4 hdr_bdl sht_bdl pht_bdl f4 =
+ let pht =
+ match f4.elf32_linking_file4_program_header_table with
+ | Nothing -> "\tNo program header table present"
+ | Just pht -> string_of_elf32_program_header_table pht_bdl pht
+ end
+ in
+ unlines [
+ "\n*Type elf32_linking_file4"
+ ; "**Header"
+ ; string_of_elf32_header hdr_bdl f4.elf32_linking_file4_header
+ ; "**Program header table:"
+ ; pht
+ ; "**Section header table:"
+ ; string_of_elf32_section_header_table' sht_bdl f4.elf32_linking_file4_section_header_string_table f4.elf32_linking_file4_section_header_table
+ ; "**Section header string table:"
+ ; unlines (List.map (fun x -> "\t" ^ x) (get_strings f4.elf32_linking_file4_section_header_string_table))
+ ; "**Body:"
+ ; "\tUninterpreted data of length " ^ show (Bitstring.length f4.elf32_linking_file4_body)
+ ]
+
+type elf64_linking_file4 =
+ <| elf64_linking_file4_header : elf64_header
+ ; elf64_linking_file4_program_header_table : maybe elf64_program_header_table
+ ; elf64_linking_file4_body : bitstring
+ ; elf64_linking_file4_section_header_table : elf64_section_header_table
+ ; elf64_linking_file4_section_header_string_table : string_table
+ |>
+
+class (HasElf64LinkingFile4 'a)
+ val get_elf64_linking_file4 : 'a -> elf64_linking_file4
+end
+
+instance (HasElf64LinkingFile4 elf64_linking_file4)
+ let get_elf64_linking_file4 f4 = f4
+end
+
+instance (HasElf64LinkingFile3 elf64_linking_file4)
+ let get_elf64_linking_file3 f4 =
+ <| elf64_linking_file3_header = f4.elf64_linking_file4_header;
+ elf64_linking_file3_program_header_table = f4.elf64_linking_file4_program_header_table;
+ elf64_linking_file3_body = f4.elf64_linking_file4_body;
+ elf64_linking_file3_section_header_table = f4.elf64_linking_file4_section_header_table |>
+end
+
+instance (HasElf64Header elf64_linking_file4)
+ let get_elf64_header f4 = f4.elf64_linking_file4_header
+end
+
+instance (HasElf64ProgramHeaderTable elf64_linking_file4)
+ let get_elf64_program_header_table f4 = f4.elf64_linking_file4_program_header_table
+end
+
+instance (HasElf64SectionHeaderTable elf64_linking_file4)
+ let get_elf64_section_header_table f4 = Just f4.elf64_linking_file4_section_header_table
+end
+
+instance (HasElf64SectionHeaderStringTable elf64_linking_file4)
+ let get_elf64_section_header_string_table f4 = f4.elf64_linking_file4_section_header_string_table
+end
+
+val refine_elf64_linking_file3 : elf64_linking_file3 -> error elf64_linking_file4
+let refine_elf64_linking_file3 f3 =
+ let hdr = f3.elf64_linking_file3_header in
+ let pht = f3.elf64_linking_file3_program_header_table in
+ let sht = f3.elf64_linking_file3_section_header_table in
+ let bs0 = f3.elf64_linking_file3_body in
+ let idx = nat_of_elf64_half hdr.elf64_shstrndx in
+ let sect = List.index sht idx in
+ match sect with
+ | Nothing -> fail "refine_elf64_linking_file3: 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 <| elf64_linking_file4_header = hdr;
+ elf64_linking_file4_program_header_table = pht;
+ elf64_linking_file4_section_header_table = sht;
+ elf64_linking_file4_section_header_string_table = String_table.mk_string_table strings Missing_pervasives.null_char;
+ elf64_linking_file4_body = bs0 |>
+ end
+
+val read_elf64_linking_file4 : bitstring -> error elf64_linking_file4
+let read_elf64_linking_file4 bs0 =
+ read_elf64_linking_file3 bs0 >>= refine_elf64_linking_file3
+
+val string_of_elf64_linking_file4 : hdr_print_bundle -> sht_print_bundle -> pht_print_bundle -> elf64_linking_file4 -> string
+let string_of_elf64_linking_file4 hdr_bdl sht_bdl pht_bdl f4 =
+ let pht =
+ match f4.elf64_linking_file4_program_header_table with
+ | Nothing -> "\tNo program header table present"
+ | Just pht -> string_of_elf64_program_header_table pht_bdl pht
+ end
+ in
+ unlines [
+ "\n*Type elf64_linking_file4"
+ ; "**Header"
+ ; string_of_elf64_header hdr_bdl f4.elf64_linking_file4_header
+ ; "**Program header table:"
+ ; pht
+ ; "**Section header table:"
+ ; string_of_elf64_section_header_table' sht_bdl f4.elf64_linking_file4_section_header_string_table f4.elf64_linking_file4_section_header_table
+ ; "**Section header string table:"
+ ; unlines (List.map (fun x -> "\t" ^ x) (get_strings f4.elf64_linking_file4_section_header_string_table))
+ ; "**Body:"
+ ; "\tUninterpreted data of length " ^ show (Bitstring.length f4.elf64_linking_file4_body)
+ ] \ No newline at end of file
diff --git a/src/elf_model/elf_relocation.lem b/src/elf_model/elf_relocation.lem
new file mode 100644
index 00000000..3bfdd54c
--- /dev/null
+++ b/src/elf_model/elf_relocation.lem
@@ -0,0 +1,42 @@
+open import Num
+
+open import Elf_types
+
+type elf32_relocation =
+ <| elf32_r_offset : elf32_addr (** Address at which to relocate *)
+ ; elf32_r_info : elf32_word (** Symbol table index/type of relocation to apply *)
+ |>
+
+type elf32_relocation_a =
+ <| elf32_ra_offset : elf32_addr (** Address at which to relocate *)
+ ; elf32_ra_info : elf32_word (** Symbol table index/type of reloation to apply *)
+ ; elf32_ra_addend : elf32_sword (** Addend used to compute value to be stored *)
+ |>
+
+type elf64_relocation =
+ <| elf64_r_offset : elf64_addr (** Address at which to relocate *)
+ ; elf64_r_info : elf64_xword (** Symbol table index/type of relocation to apply *)
+ |>
+
+type elf64_relocation_a =
+ <| elf64_ra_offset : elf64_addr (** Address at which to relocate *)
+ ; elf64_ra_info : elf64_xword (** Symbol table index/type of reloation to apply *)
+ ; elf64_ra_addend : elf64_sxword (** Addend used to compute value to be stored *)
+ |>
+
+val elf32_relocation_r_sym : elf32_word -> nat
+let elf32_relocation_r_sym w =
+ nat_of_elf32_word (elf32_word_rshift w 8)
+
+val elf32_relocation_r_type : elf32_word -> nat
+let elf32_relocation_r_type w =
+ nat_of_unsigned_char (unsigned_char_of_elf32_word w)
+
+val elf64_relocation_r_sym : elf64_xword -> nat
+let elf64_relocation_r_sym w =
+ nat_of_elf64_xword (elf64_xword_rshift w 32)
+
+val elf64_relocation_r_type : elf64_xword -> nat
+let elf64_relocation_r_type w =
+ let magic = (65536 * 65536) - 1 in (* 0xffffffffL *)
+ nat_of_elf64_xword (elf64_xword_land w (elf64_xword_of_int64 magic)) \ No newline at end of file
diff --git a/src/elf_model/elf_section_header.ml b/src/elf_model/elf_section_header.ml
deleted file mode 100644
index 1a73d35f..00000000
--- a/src/elf_model/elf_section_header.ml
+++ /dev/null
@@ -1,298 +0,0 @@
-(*Generated by Lem from elf_section_header.lem.*)
-open Lem_basic_classes
-open Lem_bool
-open Lem_list
-open Lem_num
-open Lem_string
-
-open Bitstring
-open Error
-open Elf_types
-open Show
-
-(** Special section indices. *)
-
-(** [shn_undef]: marks an undefined, missing or irrelevant section reference.
- *)
-let shn_undef : int =( 0)
-(** [shn_loreserve]: this specifies the lower bound of the range of reserved
- * indices.
- *)
-let shn_loreserve : int =( 65280) (* 0xff00 *)
-(** [shn_loproc]: start of the range reserved for processor-specific semantics.
- *)
-let shn_loproc : int =( 65280) (* 0xff00 *)
-(** [shn_hiproc]: end of the range reserved for processor-specific semantics.
- *)
-let shn_hiproc : int =( 65311) (* 0xff1f *)
-(** [shn_loos]: start of the range reserved for operating system-specific
- * semantics.
- *)
-let shn_loos : int =( 65312) (* 0xff20 *)
-(** [shn_hios]: end of the range reserved for operating system-specific
- * semantics.
- *)
-let shn_hios : int =( 65343) (* 0xff3f *)
-(** [shn_abs]: specifies the absolute values for the corresponding reference.
- * Symbols defined relative to section number [shn_abs] have absolute values
- * and are not affected by relocation.
- *)
-let shn_abs : int =( 65521) (* 0xfff1 *)
-(** [shn_common]: symbols defined relative to this index are common symbols,
- * such as unallocated C external variables.
- *)
-let shn_common : int =( 65522) (* 0xfff2 *)
-(** [shn_xindex]: an escape value. It indicates the actual section header index
- * is too large to fit in the containing field and is located in another
- * location (specific to the structure where it appears).
- *)
-let shn_xindex : int =( 65535) (* 0xffff *)
-(** [shn_hireserve]: specifies the upper-bound of reserved values.
- *)
-let shn_hireserve : int =( 65535) (* 0xffff *)
-
-(*val string_of_special_section_index : nat -> string*)
-let string_of_special_section_index i =
-(if i = shn_undef then
- "SHN_UNDEF"
- else if i = shn_loreserve then
- "SHN_LORESERVE"
- else if (i >= shn_loproc) && (i <= shn_hiproc) then
- "SHN_PROCESSOR_SPECIFIC"
- else if (i >= shn_loos) && (i <= shn_hios) then
- "SHN_OS_SPECIFIC"
- else if i = shn_abs then
- "SHN_ABS"
- else if i = shn_common then
- "SHN_COMMON"
- else if i = shn_xindex then
- "SHN_XINDEX"
- else if i = shn_hireserve then
- "SHN_HIRESERVE"
- else
- "SHN UNDEFINED")
-
-(** Section types. *)
-
-(** Marks the section header as being inactive. *)
-let sht_null : int =( 0)
-(** Section holds information defined by the program. *)
-let sht_progbits : int =( 1)
-(** The following two section types hold a symbol table. An object file may only
- * have one symbol table of each of the respective types. The symtab provides
- * a place for link editing, whereas the dynsym section holds a minimal set of
- * dynamic linking symbols
- *)
-let sht_symtab : int =( 2)
-let sht_dynsym : int =( 11)
-(** Section holds a string table *)
-let sht_strtab : int =( 3)
-(** Section holds relocation entries with explicit addends. An object file may
- * have multiple section of this type.
- *)
-let sht_rela : int =( 4)
-(** Section holds a symbol hash table. An object file may only have a single
- * hash table.
- *)
-let sht_hash : int =( 5)
-(** Section holds information for dynamic linking. An object file may only have
- * a single dynamic section.
- *)
-let sht_dynamic : int =( 6)
-(** Section holds information that marks the file in some way. *)
-let sht_note : int =( 7)
-(** Section occupies no space in the file but otherwise resembles a progbits
- * section.
- *)
-let sht_nobits : int =( 8)
-(** Section holds relocation entries without explicit addends. An object file
- * may have multiple section of this type.
- *)
-let sht_rel : int =( 9)
-(** Section type is reserved but has an unspecified meaning. *)
-let sht_shlib : int =( 10)
-(** Section contains an array of pointers to initialisation functions. Each
- * pointer is taken as a parameterless function with a void return type.
- *)
-let sht_init_array : int =( 14)
-(** Section contains an array of pointers to termination functions. Each
- * pointer is taken as a parameterless function with a void return type.
- *)
-let sht_fini_array : int =( 15)
-(** Section contains an array of pointers to initialisation functions that are
- * invoked before all other initialisation functions. Each
- * pointer is taken as a parameterless function with a void return type.
- *)
-let sht_preinit_array : int =( 16)
-(** Section defines a section group, i.e. a set of sections that are related and
- * must be treated especially by the linker. May only appear in relocatable
- * objects.
- *)
-let sht_group : int =( 17)
-(** Section is associated with sections of type SHT_SYMTAB and is required if
- * any of the section header indices referenced by that symbol table contains
- * the escape value SHN_XINDEX.
- *)
-let sht_symtab_shndx : int =( 18)
-(** XXX: broken for the time being due to Lem bug. *)
-let sht_loos : int =( 0)
-let sht_hios : int =( 0)
-let sht_loproc : int =( 0)
-let sht_hiproc : int =( 0)
-let sht_louser : int =( 0)
-let sht_hiuser : int =( 0)
-(* XXX: constants too big for Lem to parse, apparently!
-let sht_loos : nat = 1610612736 (* 0x60000000 *)
-let sht_hios : nat = 1879048191 (* 0x6fffffff *)
-let sht_loproc : nat = 1879048192 (* 0x70000000 *)
-let sht_hiproc : nat = 2147483647 (* 0x7fffffff *)
-let sht_louser : nat = 2147483648 (* 0x80000000 *)
-let sht_hiuser : nat = 2415919103 (* 0x8fffffff *)
-*)
-
-let string_of_section_type i =
-(if i = sht_null then
- "SHT_NULL"
- else if i = sht_progbits then
- "SHT_PROGBITS"
- else if i = sht_symtab then
- "SHT_SYMTAB"
- else if i = sht_strtab then
- "SHT_STRTAB"
- else if i = sht_rela then
- "SHT_RELA"
- else if i = sht_hash then
- "SHT_HASH"
- else if i = sht_dynamic then
- "SHT_DYNAMIC"
- else if i = sht_note then
- "SHT_NOTE"
- else if i = sht_nobits then
- "SHT_NOBITS"
- else if i = sht_rel then
- "SHT_REL"
- else if i = sht_shlib then
- "SHT_SHLIB"
- else if i = sht_dynsym then
- "SHT_DYNSYM"
- else if i = sht_init_array then
- "SHT_INIT_ARRAY"
- else if i = sht_fini_array then
- "SHT_FINI_ARRAY"
- else if i = sht_preinit_array then
- "SHT_PREINIT_ARRAY"
- else if i = sht_group then
- "SHT_GROUP"
- else if i = sht_symtab_shndx then
- "SHT_SYMTAB_SHNDX"
- else if (i >= sht_loos) && (i <= sht_hios) then
- "SHT_OS_SPECIFIC"
- else if (i >= sht_loproc) && (i <= sht_hiproc) then
- "SHT_PROCESSOR_SPECIFIC"
- else if (i >= sht_louser) && (i <= sht_hiuser) then
- "SHT_USER_SPECIFIC"
- else
- "SHT UNDEFINED")
-
-(** Section header table entry type. *)
-
-type elf32_section_header_table_entry =
- { elf32_sh_name : Int64.t
- ; elf32_sh_type : Int64.t
- ; elf32_sh_flags : Int64.t
- ; elf32_sh_addr : Int64.t
- ; elf32_sh_offset : Int64.t
- ; elf32_sh_size : Int64.t
- ; elf32_sh_link : Int64.t
- ; elf32_sh_info : Int64.t
- ; elf32_sh_addralign : Int64.t
- ; elf32_sh_entsize : Int64.t
- }
-
-let read_elf32_section_header_table_entry (bs : Bitstring.bitstring) =
-(Ml_bindings.read_elf32_word bs >>= (fun (sh_name, bs) ->
- Ml_bindings.read_elf32_word bs >>= (fun (sh_type, bs) ->
- Ml_bindings.read_elf32_word bs >>= (fun (sh_flags, bs) ->
- Ml_bindings.read_elf32_addr bs >>= (fun (sh_addr, bs) ->
- Ml_bindings.read_elf32_off bs >>= (fun (sh_offset, bs) ->
- Ml_bindings.read_elf32_word bs >>= (fun (sh_size, bs) ->
- Ml_bindings.read_elf32_word bs >>= (fun (sh_link, bs) ->
- Ml_bindings.read_elf32_word bs >>= (fun (sh_info, bs) ->
- Ml_bindings.read_elf32_word bs >>= (fun (sh_addralign, bs) ->
- Ml_bindings.read_elf32_word bs >>= (fun (sh_entsize, bs) ->
- return
- { elf32_sh_name = sh_name
- ; elf32_sh_type = sh_type
- ; elf32_sh_flags = sh_flags
- ; elf32_sh_addr = sh_addr
- ; elf32_sh_offset = sh_offset
- ; elf32_sh_size = sh_size
- ; elf32_sh_link = sh_link
- ; elf32_sh_info = sh_info
- ; elf32_sh_addralign = sh_addralign
- ; elf32_sh_entsize = sh_entsize
- })))))))))))
-
-let string_of_elf32_section_header_table_entry entry =
-(List.fold_right (^) [
- "\t"; "Name: "; Int64.to_string entry.elf32_sh_name
- ; "\t"; "Type: "; string_of_section_type (Int64.to_int entry.elf32_sh_type)
- ; "\n\t"; "Flags: "; Int64.to_string entry.elf32_sh_flags
- ; "\t"; "Address: "; Int64.to_string entry.elf32_sh_addr
- ; "\t"; "Size: "; Int64.to_string entry.elf32_sh_size; "\n\n"
- ] "")
-
-let instance_Show_Show_Elf_section_header_elf32_section_header_table_entry_dict =({
-
- show_method = string_of_elf32_section_header_table_entry})
-
-(** Section header table type. *)
-
-type elf32_section_header_table = elf32_section_header_table_entry list
-;;
-
-let rec read_elf32_section_header_table' entry_size bitstring0 =
-(if Bitstring.bitstring_length bitstring0 = 0 then
- return []
- else
- let (eat, rest) = (Utility.partition_bitstring entry_size bitstring0) in
- read_elf32_section_header_table_entry eat >>= (fun sect ->
- read_elf32_section_header_table' entry_size rest >>= (fun tail ->
- return (sect::tail))))
-
-(*val read_elf32_section_header_table : nat -> nat -> nat -> bitstring -> error (elf32_section_header_table * bitstring)*)
-let read_elf32_section_header_table size entry_size offset bitstring0 =
-(let (prefix, relevant) = (Utility.partition_bitstring offset bitstring0) in
- let (eat, rest) = (Utility.partition_bitstring (size * entry_size) relevant) in
- read_elf32_section_header_table' entry_size eat >>= (fun entries ->
- return (entries, rest)))
-;;
-
-(*val elf32_size_correct : elf32_section_header_table_entry -> elf32_section_header_table -> bool*)
-let elf32_size_correct hdr tbl =
-((match Int64.to_int hdr.elf32_sh_size with
- | 0 -> true
- | m -> m = List.length tbl
- ))
-;;
-
-(*val is_valid_elf32_section_header_table : elf32_section_header_table -> bool*)
-let is_valid_elf32_section_header_table tbl =
-((match tbl with
- | [] -> false
- | x::xs ->
-(Int64.to_int x.elf32_sh_name = 0) &&
- ((Int64.to_int x.elf32_sh_type = sht_null) &&
- ((Int64.to_int x.elf32_sh_flags = 0) &&
- ((Int64.to_int x.elf32_sh_addr = 0) &&
- ((Int64.to_int x.elf32_sh_offset = 0) &&
- ((Int64.to_int x.elf32_sh_info = 0) &&
- ((Int64.to_int x.elf32_sh_addralign = 0) &&
- ((Int64.to_int x.elf32_sh_entsize = 0) &&
- elf32_size_correct x tbl)))))))
- (* XXX: more correctness criteria in time *)
- ))
-
-let string_of_elf32_section_header_table (tbl : elf32_section_header_table) : string =
-("Section header table:" ^ ("\n" ^
- List.fold_right (^) (List.map string_of_elf32_section_header_table_entry tbl) ""))
diff --git a/src/elf_model/elf_symbol_table.lem b/src/elf_model/elf_symbol_table.lem
new file mode 100644
index 00000000..54521157
--- /dev/null
+++ b/src/elf_model/elf_symbol_table.lem
@@ -0,0 +1,249 @@
+open import Basic_classes
+open import Bool
+open import List
+open import Maybe
+open import String
+open import Tuple
+
+open import Bitstring
+open import Error
+open import Missing_pervasives
+open import Show
+
+open import Elf_types
+open import Endianness
+open import String_table
+
+(** Undefined symbol index *)
+
+let stn_undef : nat = 0
+
+(** Symbol binding *)
+
+let stb_local : nat = 0
+let stb_global : nat = 1
+let stb_weak : nat = 2
+let stb_loos : nat = 10
+let stb_hios : nat = 12
+let stb_loproc : nat = 13
+let stb_hiproc : nat = 15
+
+val string_of_symbol_binding : nat -> (nat -> string) -> (nat -> string) -> string
+let string_of_symbol_binding m os proc =
+ if m = stb_local then
+ "STB_LOCAL"
+ else if m = stb_global then
+ "STB_GLOBAL"
+ else if m = stb_weak then
+ "STB_WEAK"
+ else if m >= stb_loos && m <= stb_hios then
+ os m
+ else if m >= stb_loproc && m <= stb_hiproc then
+ proc m
+ else
+ "Invalid symbol binding"
+
+(** Symbol types *)
+
+let stt_notype : nat = 0
+let stt_object : nat = 1
+let stt_func : nat = 2
+let stt_section : nat = 3
+let stt_file : nat = 4
+let stt_common : nat = 5
+let stt_tls : nat = 6
+let stt_loos : nat = 10
+let stt_hios : nat = 12
+let stt_loproc : nat = 13
+let stt_hiproc : nat = 15
+
+val string_of_symbol_type : nat -> (nat -> string) -> (nat -> string) -> string
+let string_of_symbol_type m os proc =
+ if m = stt_notype then
+ "STT_NOTYPE"
+ else if m = stt_object then
+ "STT_OBJECT"
+ else if m = stt_func then
+ "STT_FUNC"
+ else if m = stt_section then
+ "STT_SECTION"
+ else if m = stt_file then
+ "STT_FILE"
+ else if m = stt_common then
+ "STT_COMMON"
+ else if m = stt_tls then
+ "STT_TLS"
+ else if m >= stt_loos && m <= stt_hios then
+ os m
+ else if m >= stt_loproc && m <= stt_hiproc then
+ proc m
+ else
+ "Invalid symbol type"
+
+(** Symbol visibility *)
+
+let stv_default : nat = 0
+let stv_internal : nat = 1
+let stv_hidden : nat = 2
+let stv_protected : nat = 3
+
+val string_of_symbol_visibility : nat -> string
+let string_of_symbol_visibility m =
+ if m = stv_default then
+ "STV_DEFAULT"
+ else if m = stv_internal then
+ "STV_INTERNAL"
+ else if m = stv_hidden then
+ "STV_HIDDEN"
+ else if m = stv_protected then
+ "STV_PROTECTED"
+ else
+ "Invalid symbol visibility"
+
+(** ELF32 symbol table type *)
+
+type elf32_symbol_table_entry =
+ <| elf32_st_name : elf32_word
+ ; elf32_st_value : elf32_addr
+ ; elf32_st_size : elf32_word
+ ; elf32_st_info : unsigned_char
+ ; elf32_st_other : unsigned_char
+ ; elf32_st_shndx : elf32_half
+ |>
+
+(** Extraction of symbol table data *)
+
+(* Functions below common to 32- and 64-bit! *)
+
+val get_symbol_binding : unsigned_char -> nat
+let get_symbol_binding entry =
+ nat_of_unsigned_char (unsigned_char_rshift entry 4)
+
+val get_symbol_type : unsigned_char -> nat
+let get_symbol_type entry =
+ nat_of_unsigned_char (unsigned_char_land entry (unsigned_char_of_nat 15)) (* 0xf *)
+
+val get_symbol_info : unsigned_char -> unsigned_char -> nat
+let get_symbol_info entry0 entry1 =
+ nat_of_unsigned_char (unsigned_char_plus
+ (unsigned_char_lshift entry0 4) (unsigned_char_land entry1
+ (unsigned_char_of_nat 15))) (*0xf*)
+
+val get_symbol_visibility : unsigned_char -> nat
+let get_symbol_visibility entry =
+ nat_of_unsigned_char (unsigned_char_land entry (unsigned_char_of_nat 3)) (* 0x3*)
+
+type symtab_print_bundle = (nat -> string) * (nat -> string)
+
+val string_of_elf32_symbol_table_entry : elf32_symbol_table_entry -> string
+let string_of_elf32_symbol_table_entry entry =
+ unlines [
+ "\t" ^ "Name: " ^ show entry.elf32_st_name
+ ; "\t" ^ "Value: " ^ show entry.elf32_st_value
+ ; "\t" ^ "Size: " ^ show entry.elf32_st_size
+ ; "\t" ^ "Info: " ^ show entry.elf32_st_info
+ ; "\t" ^ "Other: " ^ show entry.elf32_st_other
+ ; "\t" ^ "Shndx: " ^ show entry.elf32_st_shndx
+ ]
+
+type elf32_symbol_table = list elf32_symbol_table_entry
+
+val string_of_elf32_symbol_table : elf32_symbol_table -> string
+let string_of_elf32_symbol_table symtab =
+ unlines (List.map string_of_elf32_symbol_table_entry symtab)
+
+class (HasElf32SymbolTable 'a)
+ val get_elf32_symbol_table : 'a -> elf32_symbol_table
+end
+
+val read_elf32_symbol_table_entry : endianness -> bitstring -> error (elf32_symbol_table_entry * bitstring)
+let read_elf32_symbol_table_entry endian bs0 =
+ read_elf32_word endian bs0 >>= fun (st_name, bs0) ->
+ read_elf32_addr endian bs0 >>= fun (st_value, bs0) ->
+ read_elf32_word endian bs0 >>= fun (st_size, bs0) ->
+ read_unsigned_char endian bs0 >>= fun (st_info, bs0) ->
+ read_unsigned_char endian bs0 >>= fun (st_other, bs0) ->
+ read_elf32_half endian bs0 >>= fun (st_shndx, bs0) ->
+ return (<| elf32_st_name = st_name; elf32_st_value = st_value;
+ elf32_st_size = st_size; elf32_st_info = st_info;
+ elf32_st_other = st_other; elf32_st_shndx = st_shndx |>, bs0)
+
+val read_elf32_symbol_table : endianness -> bitstring -> error elf32_symbol_table
+let rec read_elf32_symbol_table endian bs0 =
+ if length bs0 = 0 then
+ return []
+ else
+ read_elf32_symbol_table_entry endian bs0 >>= fun (head, bs0) ->
+ read_elf32_symbol_table endian bs0 >>= fun tail ->
+ return (head::tail)
+
+(** ELF64 symbol table type *)
+
+type elf64_symbol_table_entry =
+ <| elf64_st_name : elf64_word
+ ; elf64_st_info : unsigned_char
+ ; elf64_st_other : unsigned_char
+ ; elf64_st_shndx : elf64_half
+ ; elf64_st_value : elf64_addr
+ ; elf64_st_size : elf64_xword
+ |>
+
+val string_of_elf64_symbol_table_entry : elf64_symbol_table_entry -> string
+let string_of_elf64_symbol_table_entry entry =
+ unlines [
+ "\t" ^ "Name: " ^ show entry.elf64_st_name
+ ; "\t" ^ "Info: " ^ show entry.elf64_st_info
+ ; "\t" ^ "Other: " ^ show entry.elf64_st_other
+ ; "\t" ^ "Shndx: " ^ show entry.elf64_st_shndx
+ ; "\t" ^ "Value: " ^ show entry.elf64_st_value
+ ; "\t" ^ "Size: " ^ show entry.elf64_st_size
+ ]
+
+type elf64_symbol_table = list elf64_symbol_table_entry
+
+val string_of_elf64_symbol_table : elf64_symbol_table -> string
+let string_of_elf64_symbol_table symtab =
+ unlines (List.map string_of_elf64_symbol_table_entry symtab)
+
+class (HasElf64SymbolTable 'a)
+ val get_elf64_symbol_table : 'a -> elf64_symbol_table
+end
+
+val read_elf64_symbol_table_entry : endianness -> bitstring -> error (elf64_symbol_table_entry * bitstring)
+let read_elf64_symbol_table_entry endian bs0 =
+ read_elf64_word endian bs0 >>= fun (st_name, bs0) ->
+ read_unsigned_char endian bs0 >>= fun (st_info, bs0) ->
+ read_unsigned_char endian bs0 >>= fun (st_other, bs0) ->
+ read_elf64_half endian bs0 >>= fun (st_shndx, bs0) ->
+ read_elf64_addr endian bs0 >>= fun (st_value, bs0) ->
+ read_elf64_xword endian bs0 >>= fun (st_size, bs0) ->
+ return (<| elf64_st_name = st_name; elf64_st_info = st_info;
+ elf64_st_other = st_other; elf64_st_shndx = st_shndx;
+ elf64_st_value = st_value; elf64_st_size = st_size |>, bs0)
+
+val read_elf64_symbol_table : endianness -> bitstring -> error elf64_symbol_table
+let rec read_elf64_symbol_table endian bs0 =
+ if length bs0 = 0 then
+ return []
+ else
+ read_elf64_symbol_table_entry endian bs0 >>= fun (head, bs0) ->
+ read_elf64_symbol_table endian bs0 >>= fun tail ->
+ return (head::tail)
+
+val get_elf32_symbol_image_address : elf32_symbol_table -> string_table -> error (list (string * nat))
+let get_elf32_symbol_image_address symtab strtab =
+ mapM (fun entry ->
+ let name = nat_of_elf32_word entry.elf32_st_name in
+ let addr = nat_of_elf32_addr entry.elf32_st_value in
+ String_table.get_string_at name strtab >>= fun str ->
+ return (str, addr)
+ ) symtab
+
+val get_elf64_symbol_image_address : elf64_symbol_table -> string_table -> error (list (string * nat))
+let get_elf64_symbol_image_address symtab strtab =
+ mapM (fun entry ->
+ let name = nat_of_elf64_word entry.elf64_st_name in
+ let addr = nat_of_elf64_addr entry.elf64_st_value in
+ String_table.get_string_at name strtab >>= fun str ->
+ return (str, addr)
+ ) symtab \ No newline at end of file
diff --git a/src/elf_model/elf_symbol_table.ml b/src/elf_model/elf_symbol_table.ml
index a2fed159..369629b0 100644
--- a/src/elf_model/elf_symbol_table.ml
+++ b/src/elf_model/elf_symbol_table.ml
@@ -2,245 +2,249 @@
open Lem_basic_classes
open Lem_bool
open Lem_list
-open Lem_num
+open Lem_maybe
open Lem_string
+open Lem_tuple
-open Bitstring
-open Elf_section_header
-open Elf_types
+open Bitstring_local
open Error
+open Missing_pervasives
open Show
-(** Symbol table indices *)
+open Elf_types
+open Endianness
+open String_table
+
+(** Undefined symbol index *)
-(** Symbol table index is a subscript into the symbol table, which holds
- * information needed to locate and relocate a program's symbolic definitions
- * and references. Index 0 designates both the first entry in the table and
- * serves as the undefined symbol index. [stn_undef] is a mnemonic for that
- * undefined symbol.
- *)
let stn_undef : int =( 0)
-(** Symbol bindings *)
-
-(** [elf32_st_bind] unpacks the binding information from the [st_info] field
- * in the record type below.
- *)
-let elf32_st_bind i =
-(Int64.to_int (Int64.shift_right i( 4)))
-(** [elf64_st_bind] unpacks the binding information from the [st_info] field
- * in the record type below.
- *)
-let elf64_st_bind i =
-(Int64.to_int (Int64.shift_right i( 4)))
-(** [elf32_st_type] unpacks the type information from the [e32_st_info] field
- * in the record type below.
- *)
-let elf32_st_type i =
-(Int64.to_int (Int64.logand i (Int64.of_int( 15)))) (* 0xf *)
-(** [elf64_st_type] unpacks the type information from the [e64_st_info] field
- * in the record type below.
- *)
-let elf64_st_type i =
-(Int64.to_int (Int64.logand i (Int64.of_int( 15)))) (* 0xf *)
-(** [elf32_st_info] unpacks other information from the [e32_st_info] field in the
- * record type below.
- *)
-let elf32_st_info b t =
-(let left = (Int64.shift_left b( 4)) in
- let right = (Int64.logand t (Int64.of_int( 15))) in (* 0xf *)
- let result = (Int64.add left right) in
- Int64.to_int result)
-(** [elf64_st_info] unpacks other information from the [e64_st_info] field in the
- * record type below.
- *)
-let elf64_st_info b t =
-(let left = (Int64.shift_left b( 4)) in
- let right = (Int64.logand t (Int64.of_int( 15))) in (* 0xf *)
- let result = (Int64.add left right) in
- Int64.to_int result)
-(** [stb_local]: local symbols are not visible outside the object file
- * containing their definition.
- *)
+(** Symbol binding *)
+
let stb_local : int =( 0)
-(** [stb_global]: global symbols are visible to all object files being combined.
- *)
let stb_global : int =( 1)
-(** [stb_weak]: weak symbols resemble global symbols but their definitions have
- * lower precedence.
- *)
let stb_weak : int =( 2)
-(** [stb_loos]: start of the range reserved for operating-system specific
- * semantics.
- *)
let stb_loos : int =( 10)
-(** [stb_hios]: end of the range reserved for operating-system specific
- * semantics.
- *)
let stb_hios : int =( 12)
-(** [stb_loproc]: start of the range reserved for processor specific semantics.
- *)
let stb_loproc : int =( 13)
-(** [stb_hiproc]: end of the range reserved for processor specific semantics.
- *)
let stb_hiproc : int =( 15)
-(** Symbol types. *)
+(*val string_of_symbol_binding : nat -> (nat -> string) -> (nat -> string) -> string*)
+let string_of_symbol_binding m os proc =
+(if m = stb_local then
+ "STB_LOCAL"
+ else if m = stb_global then
+ "STB_GLOBAL"
+ else if m = stb_weak then
+ "STB_WEAK"
+ else if (m >= stb_loos) && (m <= stb_hios) then
+ os m
+ else if (m >= stb_loproc) && (m <= stb_hiproc) then
+ proc m
+ else
+ "Invalid symbol binding")
+
+(** Symbol types *)
-(** [stt_notype]: the symbol's type is not specified.
- *)
let stt_notype : int =( 0)
-(** [stt_object]: the symbol is associated with a data object, such as a
- * variable, an array, and so on.
- *)
let stt_object : int =( 1)
-(** [stt_func]: the symbol is associated with a function or other executable
- * code.
- *)
let stt_func : int =( 2)
-(** [stt_section]: the symbol is associated with a section.
- *)
let stt_section : int =( 3)
-(** [stt_file]: the symbol's name gives the name of the source file associated
- * with the object file. Must have [stb_local] binding and its section index
- * must be [shn_abs]. It must also precede the other [stb_local] symbols for
- * the file, is present.
- *)
let stt_file : int =( 4)
-(** [stt_common]: labels an unitialised common block.
- *)
let stt_common : int =( 5)
-(** [stt_tls]: specifies a thread local storage (TLS) entity. Gives the
- * assigned offset of the symbol, not its address. TLS symbols may only be
- * referenced by special TLS relocations and TLS relocations may only reference
- * symbols with type [stt_tls].
- *)
let stt_tls : int =( 6)
-(** [stt_loos]: start of the range reserved for operating-system specific
- * semantics.
- *)
let stt_loos : int =( 10)
-(** [stt_hios]: end of the range reserved for operating-system specific
- * semantics.
- *)
let stt_hios : int =( 12)
-(** [stt_loproc]: start of the range reserved for processor specific
- * semantics.
- *)
let stt_loproc : int =( 13)
-(** [stt_hiproc]: end of the range reserved for processor specific semantics.
- *)
let stt_hiproc : int =( 15)
-(** Symbol visibility. *)
-
-(** [elf32_st_visibility] unpacks visibility information from the [e32_st_other]
- * field in the record type below.
- *)
-(*val elf32_st_visibility : unsigned_char -> nat*)
-let elf32_st_visibility o =
-(Int64.to_int (Int64.logand o (Int64.of_int( 3)))) (* 0x3 *)
-
-(** [stv_default]: symbol visibility is as specified by the symbol's binding
- * type. Global and weak symbols are visible outside their defining component
- * (executable or shared object file). Local symbols are hidden. Global and
- * weak symbols are also pre-emptable: they may be pre-empted by definitions
- * of the same name in another component.
- *)
+(*val string_of_symbol_type : nat -> (nat -> string) -> (nat -> string) -> string*)
+let string_of_symbol_type m os proc =
+(if m = stt_notype then
+ "STT_NOTYPE"
+ else if m = stt_object then
+ "STT_OBJECT"
+ else if m = stt_func then
+ "STT_FUNC"
+ else if m = stt_section then
+ "STT_SECTION"
+ else if m = stt_file then
+ "STT_FILE"
+ else if m = stt_common then
+ "STT_COMMON"
+ else if m = stt_tls then
+ "STT_TLS"
+ else if (m >= stt_loos) && (m <= stt_hios) then
+ os m
+ else if (m >= stt_loproc) && (m <= stt_hiproc) then
+ proc m
+ else
+ "Invalid symbol type")
+
+(** Symbol visibility *)
+
let stv_default : int =( 0)
-(** [stv_internal]: meaning may be further defined by processor supplements to
- * further constrain hidden symbols. An internal symbol in a relocatable file
- * must be either removed or converted to [stb_local] when the relocatable
- * object is included in an executable or shared object by the linker.
- *)
let stv_internal : int =( 1)
-(** [stv_hidden]: a symbol in the current component is hidden if its name is not
- * visible to other components, necessarily protecting the symbol. A hidden
- * object may still be referenced from another component if its address is
- * passed outside. A hidden symbol in a relocatable object must be either
- * removed or converted to [stb_local] when the relocatable file is included in
- * an executable or shared object by the linker.
- *)
let stv_hidden : int =( 2)
-(** [stv_protected]: a protected symbol is visible in other components but is
- * not pre-emptable, so that any reference to such a symbol from within the
- * defining component must be resolved to the definition in that component.
- * A symbol with [stb_local] binding must not have [stv_protected] visibility.
- * If a symbol definition with [stv_protected] visibility from a shared object
- * file is taken as resolving a reference from an executable or another shared
- * object, the [shn_undef] symbol table entry created has [stv_default]
- * visibility.
- *)
let stv_protected : int =( 3)
-(** The symbol table entry type. *)
+(*val string_of_symbol_visibility : nat -> string*)
+let string_of_symbol_visibility m =
+(if m = stv_default then
+ "STV_DEFAULT"
+ else if m = stv_internal then
+ "STV_INTERNAL"
+ else if m = stv_hidden then
+ "STV_HIDDEN"
+ else if m = stv_protected then
+ "STV_PROTECTED"
+ else
+ "Invalid symbol visibility")
+
+(** ELF32 symbol table type *)
type elf32_symbol_table_entry =
- { elf32_st_name : Int64.t
- ; elf32_st_value : Int64.t
- ; elf32_st_size : Int64.t
- ; elf32_st_info0 : Int64.t
- ; elf32_st_other : Int64.t
- ; elf32_st_shndx : Int64.t
+ { elf32_st_name : Uint32.t
+ ; elf32_st_value : Uint32.t
+ ; elf32_st_size : Uint32.t
+ ; elf32_st_info : Uint32.t
+ ; elf32_st_other : Uint32.t
+ ; elf32_st_shndx : Uint32.t
}
-
-let string_of_elf32_symbol_table_entry entry =
-(List.fold_right (^) [
- "\t"; "Name: "; Int64.to_string entry.elf32_st_name
- ; "\t"; "Size: "; Int64.to_string entry.elf32_st_size
- ; "\n\t"; "Value: "; Int64.to_string entry.elf32_st_value
- ; "\t"; "Info: "; Int64.to_string entry.elf32_st_info0; "\n\n"
- ] "")
-
-let read_elf32_symbol_table_entry bitstring6 : elf32_symbol_table_entry error =
-(Ml_bindings.read_elf32_word bitstring6 >>= (fun (name, bitstring5) ->
- Ml_bindings.read_elf32_addr bitstring5 >>= (fun (value, bitstring4) ->
- Ml_bindings.read_elf32_word bitstring4 >>= (fun (size, bitstring3) ->
- Ml_bindings.read_unsigned_char bitstring3 >>= (fun (info, bitstring2) ->
- Ml_bindings.read_unsigned_char bitstring2 >>= (fun (other, bitstring1) ->
- Ml_bindings.read_elf32_half bitstring1 >>= (fun (shndx, bitstring0) ->
- let entry = ({ elf32_st_name = name; elf32_st_value = value; elf32_st_size = size; elf32_st_info0 = info; elf32_st_other = other; elf32_st_shndx = shndx }) in
- return entry)))))))
-
-let rec read_elf32_symbol_table_entries bs : ( elf32_symbol_table_entry list) error =
-(if Bitstring.bitstring_length bs = 0 then
- return []
- else
- let (cut, rest) = (Utility.partition_bitstring( 128) bs) in
- read_elf32_symbol_table_entry cut >>= (fun head ->
- read_elf32_symbol_table_entries rest >>= (fun tail ->
- return (head::tail))))
-
-let rec read_elf32_symbol_tables' offset_sizes bs =
-((match offset_sizes with
- | [] -> return []
- | x::xs ->
- let (offset, size) = x in
- let (_, relevant) = (Utility.partition_bitstring offset bs) in
- let (cut, _) = (Utility.partition_bitstring size relevant) in
- read_elf32_symbol_table_entries cut >>= (fun head ->
- read_elf32_symbol_tables' xs bs >>= (fun tail ->
- return (head::tail)))
- ))
+
+(** Extraction of symbol table data *)
+
+(* Functions below common to 32- and 64-bit! *)
+
+(*val get_symbol_binding : unsigned_char -> nat*)
+let get_symbol_binding entry =
+(Uint32.to_int (Uint32.shift_right entry( 4)))
+
+(*val get_symbol_type : unsigned_char -> nat*)
+let get_symbol_type entry =
+(Uint32.to_int (Uint32.logand entry (Uint32.of_int( 15)))) (* 0xf *)
+
+(*val get_symbol_info : unsigned_char -> unsigned_char -> nat*)
+let get_symbol_info entry0 entry1 =
+(Uint32.to_int (Uint32.add
+ (Uint32.shift_left entry0( 4)) (Uint32.logand entry1
+ (Uint32.of_int( 15))))) (*0xf*)
+
+(*val get_symbol_visibility : unsigned_char -> nat*)
+let get_symbol_visibility entry =
+(Uint32.to_int (Uint32.logand entry (Uint32.of_int( 3)))) (* 0x3*)
+
+type symtab_print_bundle = (int -> string) * (int -> string)
+
+(*val string_of_elf32_symbol_table_entry : elf32_symbol_table_entry -> string*)
+let string_of_elf32_symbol_table_entry entry =
+(unlines [
+("\t" ^ ("Name: " ^ Uint32.to_string entry.elf32_st_name))
+ ; ("\t" ^ ("Value: " ^ Uint32.to_string entry.elf32_st_value))
+ ; ("\t" ^ ("Size: " ^ Uint32.to_string entry.elf32_st_size))
+ ; ("\t" ^ ("Info: " ^ Uint32.to_string entry.elf32_st_info))
+ ; ("\t" ^ ("Other: " ^ Uint32.to_string entry.elf32_st_other))
+ ; ("\t" ^ ("Shndx: " ^ Uint32.to_string entry.elf32_st_shndx))
+ ])
type elf32_symbol_table = elf32_symbol_table_entry list
-let read_elf32_symbol_tables sections bs : ( elf32_symbol_table list) error =
-(let symtabs = (List.filter (fun sect ->
- (Int64.to_int sect.elf32_sh_type = sht_symtab) ||
- (Int64.to_int sect.elf32_sh_type = sht_dynsym)) sections)
- in
- let _ = (print_endline ("Symtabs: " ^ natShow (List.length symtabs))) in
- let offsets_sizes = (List.map (fun sect ->
- let offset = ((Int64.to_int sect.elf32_sh_offset) * 8) in
- let size =
-(let _ = (print_endline ("YYY size: " ^ natShow (Int64.to_int sect.elf32_sh_size * 8))) in
- Int64.to_int sect.elf32_sh_size * 8)
- in
- (offset, size)) symtabs)
- in
- read_elf32_symbol_tables' offsets_sizes bs)
-
-let string_of_elf32_symbol_table tbl =
-("Symbol table contents:" ^ ("\n" ^
- List.fold_right (^) (List.map string_of_elf32_symbol_table_entry tbl) ""))
+(*val string_of_elf32_symbol_table : elf32_symbol_table -> string*)
+let string_of_elf32_symbol_table symtab =
+(unlines (List.map string_of_elf32_symbol_table_entry symtab))
+
+type 'a hasElf32SymbolTable_class={
+ get_elf32_symbol_table_method : 'a -> elf32_symbol_table
+}
+
+(*val read_elf32_symbol_table_entry : endianness -> bitstring -> error (elf32_symbol_table_entry * bitstring)*)
+let read_elf32_symbol_table_entry endian bs0 =
+(Ml_bindings.read_elf32_word endian bs0 >>= (fun (st_name, bs0) ->
+ Ml_bindings.read_elf32_addr endian bs0 >>= (fun (st_value, bs0) ->
+ Ml_bindings.read_elf32_word endian bs0 >>= (fun (st_size, bs0) ->
+ Ml_bindings.read_unsigned_char endian bs0 >>= (fun (st_info, bs0) ->
+ Ml_bindings.read_unsigned_char endian bs0 >>= (fun (st_other, bs0) ->
+ Ml_bindings.read_elf32_half endian bs0 >>= (fun (st_shndx, bs0) ->
+ return ({ elf32_st_name = st_name; elf32_st_value = st_value;
+ elf32_st_size = st_size; elf32_st_info = st_info;
+ elf32_st_other = st_other; elf32_st_shndx = st_shndx }, bs0))))))))
+
+(*val read_elf32_symbol_table : endianness -> bitstring -> error elf32_symbol_table*)
+let rec read_elf32_symbol_table endian bs0 =
+(if Bitstring.bitstring_length bs0 = 0 then
+ return []
+ else
+ read_elf32_symbol_table_entry endian bs0 >>= (fun (head, bs0) ->
+ read_elf32_symbol_table endian bs0 >>= (fun tail ->
+ return (head::tail))))
+
+(** ELF64 symbol table type *)
+
+type elf64_symbol_table_entry =
+ { elf64_st_name : Uint32.t
+ ; elf64_st_info : Uint32.t
+ ; elf64_st_other : Uint32.t
+ ; elf64_st_shndx : Uint32.t
+ ; elf64_st_value : Uint64.t
+ ; elf64_st_size : Uint64.t
+ }
+
+(*val string_of_elf64_symbol_table_entry : elf64_symbol_table_entry -> string*)
+let string_of_elf64_symbol_table_entry entry =
+(unlines [
+("\t" ^ ("Name: " ^ Uint32.to_string entry.elf64_st_name))
+ ; ("\t" ^ ("Info: " ^ Uint32.to_string entry.elf64_st_info))
+ ; ("\t" ^ ("Other: " ^ Uint32.to_string entry.elf64_st_other))
+ ; ("\t" ^ ("Shndx: " ^ Uint32.to_string entry.elf64_st_shndx))
+ ; ("\t" ^ ("Value: " ^ Uint64.to_string entry.elf64_st_value))
+ ; ("\t" ^ ("Size: " ^ Uint64.to_string entry.elf64_st_size))
+ ])
+
+type elf64_symbol_table = elf64_symbol_table_entry list
+
+(*val string_of_elf64_symbol_table : elf64_symbol_table -> string*)
+let string_of_elf64_symbol_table symtab =
+(unlines (List.map string_of_elf64_symbol_table_entry symtab))
+
+type 'a hasElf64SymbolTable_class={
+ get_elf64_symbol_table_method : 'a -> elf64_symbol_table
+}
+
+(*val read_elf64_symbol_table_entry : endianness -> bitstring -> error (elf64_symbol_table_entry * bitstring)*)
+let read_elf64_symbol_table_entry endian bs0 =
+(Ml_bindings.read_elf64_word endian bs0 >>= (fun (st_name, bs0) ->
+ Ml_bindings.read_unsigned_char endian bs0 >>= (fun (st_info, bs0) ->
+ Ml_bindings.read_unsigned_char endian bs0 >>= (fun (st_other, bs0) ->
+ Ml_bindings.read_elf64_half endian bs0 >>= (fun (st_shndx, bs0) ->
+ Ml_bindings.read_elf64_addr endian bs0 >>= (fun (st_value, bs0) ->
+ Ml_bindings.read_elf64_xword endian bs0 >>= (fun (st_size, bs0) ->
+ return ({ elf64_st_name = st_name; elf64_st_info = st_info;
+ elf64_st_other = st_other; elf64_st_shndx = st_shndx;
+ elf64_st_value = st_value; elf64_st_size = st_size }, bs0))))))))
+
+(*val read_elf64_symbol_table : endianness -> bitstring -> error elf64_symbol_table*)
+let rec read_elf64_symbol_table endian bs0 =
+(if Bitstring.bitstring_length bs0 = 0 then
+ return []
+ else
+ read_elf64_symbol_table_entry endian bs0 >>= (fun (head, bs0) ->
+ read_elf64_symbol_table endian bs0 >>= (fun tail ->
+ return (head::tail))))
+
+(*val get_elf32_symbol_image_address : elf32_symbol_table -> string_table -> error (list (string * nat))*)
+let get_elf32_symbol_image_address symtab strtab =
+(mapM (fun entry ->
+ let name = (Uint32.to_int entry.elf32_st_name) in
+ let addr = (Uint32.to_int entry.elf32_st_value) in
+ String_table.get_string_at name strtab >>= (fun str ->
+ return (str, addr))
+ ) symtab)
+
+(*val get_elf64_symbol_image_address : elf64_symbol_table -> string_table -> error (list (string * nat))*)
+let get_elf64_symbol_image_address symtab strtab =
+(mapM (fun entry ->
+ let name = (Uint32.to_int entry.elf64_st_name) in
+ let addr = (Uint64.to_int entry.elf64_st_value) in
+ String_table.get_string_at name strtab >>= (fun str ->
+ return (str, addr))
+ ) symtab) \ No newline at end of file
diff --git a/src/elf_model/elf_types.lem b/src/elf_model/elf_types.lem
index d35a9713..ec50346f 100644
--- a/src/elf_model/elf_types.lem
+++ b/src/elf_model/elf_types.lem
@@ -59,7 +59,7 @@ declare ocaml target_rep function nat_of_unsigned_char = `Uint32.to_int`
declare ocaml target_rep function unsigned_char_of_nat = `Uint32.of_int`
declare ocaml target_rep function unsigned_char_land = `Uint32.logand`
declare ocaml target_rep function unsigned_char_lshift = `Uint32.shift_left`
-declare ocaml target_rep function unsigned_char_rshift = `Uint64.shift_right`
+declare ocaml target_rep function unsigned_char_rshift = `Uint32.shift_right`
declare ocaml target_rep function unsigned_char_plus = `Uint32.add`
declare ocaml target_rep function read_unsigned_char = `Ml_bindings.read_unsigned_char`
@@ -185,13 +185,17 @@ val string_of_elf32_word : elf32_word -> string
val nat_of_elf32_word : elf32_word -> nat
val elf32_word_of_int32 : int32 -> elf32_word
val elf32_word_land : elf32_word -> elf32_word -> elf32_word
+val elf32_word_rshift : elf32_word -> nat -> elf32_word
val read_elf32_word : endianness -> bitstring -> error (elf32_word * bitstring)
+val unsigned_char_of_elf32_word : elf32_word -> unsigned_char
declare ocaml target_rep function string_of_elf32_word = `Uint32.to_string`
declare ocaml target_rep function read_elf32_word = `Ml_bindings.read_elf32_word`
declare ocaml target_rep function nat_of_elf32_word = `Uint32.to_int`
declare ocaml target_rep function elf32_word_of_int32 = `Uint32.of_int32`
declare ocaml target_rep function elf32_word_land = `Uint32.logand`
+declare ocaml target_rep function elf32_word_rshift = `Uint32.shift_right`
+declare ocaml target_rep function unsigned_char_of_elf32_word = ``
instance (Show elf32_word)
let show = string_of_elf32_word
@@ -264,10 +268,16 @@ declare ocaml target_rep type elf64_xword = `Uint64.t`
val string_of_elf64_xword : elf64_xword -> string
val nat_of_elf64_xword : elf64_xword -> nat
val read_elf64_xword : endianness -> bitstring -> error (elf64_xword * bitstring)
+val elf64_xword_rshift : elf64_xword -> nat -> elf64_xword
+val elf64_xword_land : elf64_xword -> elf64_xword -> elf64_xword
+val elf64_xword_of_int64 : int64 -> elf64_xword
declare ocaml target_rep function string_of_elf64_xword = `Uint64.to_string`
declare ocaml target_rep function read_elf64_xword = `Ml_bindings.read_elf64_xword`
declare ocaml target_rep function nat_of_elf64_xword = `Uint64.to_int`
+declare ocaml target_rep function elf64_xword_rshift = `Uint64.shift_right`
+declare ocaml target_rep function elf64_xword_land = `Uint64.logand`
+declare ocaml target_rep function elf64_xword_of_int64 = `Uint64.of_int64`
instance (Show elf64_xword)
let show = string_of_elf64_xword
diff --git a/src/elf_model/libraries/Makefile b/src/elf_model/libraries/Makefile
new file mode 100644
index 00000000..1745dbdd
--- /dev/null
+++ b/src/elf_model/libraries/Makefile
@@ -0,0 +1,23 @@
+dummy: all
+
+extract:
+ mkdir batteries bitstring uint
+ tar -zxvf batteries-2.2.tar.gz -C batteries --strip-components=1
+ tar -zxvf bitstring.tar.gz -C bitstring --strip-components=1
+ tar -zxvf uint.tar.gz -C uint --strip-components=1
+
+clean:
+ rm -rf batteries bitstring uint
+
+make-batteries:
+ make -C batteries all
+
+make-uint:
+ make -C uint configure
+ make -C uint all
+
+make-bitstring:
+ cd bitstring && ./configure
+ make -C bitstring
+
+all: extract make-batteries make-bitstring make-uint \ No newline at end of file
diff --git a/src/elf_model/libraries/batteries-2.2.tar.gz b/src/elf_model/libraries/batteries-2.2.tar.gz
new file mode 100644
index 00000000..d88b8c8f
--- /dev/null
+++ b/src/elf_model/libraries/batteries-2.2.tar.gz
Binary files differ
diff --git a/src/elf_model/libraries/bitstring.tar.gz b/src/elf_model/libraries/bitstring.tar.gz
new file mode 100644
index 00000000..42a2c19f
--- /dev/null
+++ b/src/elf_model/libraries/bitstring.tar.gz
Binary files differ
diff --git a/src/elf_model/libraries/uint.tar.gz b/src/elf_model/libraries/uint.tar.gz
new file mode 100644
index 00000000..21a3a379
--- /dev/null
+++ b/src/elf_model/libraries/uint.tar.gz
Binary files differ
diff --git a/src/elf_model/main.lem b/src/elf_model/main.lem
index a7e7a709..501657cc 100644
--- a/src/elf_model/main.lem
+++ b/src/elf_model/main.lem
@@ -3,6 +3,7 @@ open import String
open import Tuple
open import Bitstring
+open import Default_printing
open import Error
open import Missing_pervasives
open import Show
@@ -11,31 +12,31 @@ open import Elf_header
open import Elf_file1
open import Elf_executable_file2
open import Elf_executable_file3
-open import Elf_executable_file4
-open import Elf_executable_file5
+open import Elf_linking_file2
+open import Elf_linking_file3
open import Sail_interface
-let default_os _ =
- "*Default OS specific print*"
-
-let default_proc _ =
- "*Default processor specific print*"
-
-let default_user _ =
- "*Default user specific print*"
-
let default_hdr_bdl =
- (default_os, default_proc)
+ (default_os_specific_print, default_proc_specific_print)
let default_pht_bdl =
- (default_os, default_proc)
+ (default_os_specific_print, default_proc_specific_print)
let default_sht_bdl =
- (default_os, default_proc, default_user)
+ (default_os_specific_print, default_proc_specific_print, default_user_specific_print)
let _ =
- let (chunks_addr, entry) = Sail_interface.populate "test/power64-executable-1" in
- let _ = Missing_pervasives.print ("Entry point: " ^ show entry) in
- let _ = Missing_pervasives.print ("#Chunks: " ^ show (List.length chunks_addr)) in
- () \ No newline at end of file
+ let res =
+ Bitstring.acquire "test/power64-executable-2" >>= fun bs0 ->
+ Elf_executable_file3.read_elf64_executable_file3 bs0 >>= fun f1 ->
+ Elf_executable_file3.get_elf64_symbol_table f1 >>= fun symtab ->
+ Elf_executable_file3.get_elf64_symbol_string_table f1 >>= fun strtab ->
+ Elf_symbol_table.get_elf64_symbol_image_address symtab strtab >>= fun strs ->
+ let _ = Missing_pervasives.print (show strs) in
+ return f1
+ in
+ match res with
+ | Fail err -> Missing_pervasives.print ("[!]: " ^ err)
+ | Success _ -> Missing_pervasives.print "Success..."
+ end
diff --git a/src/elf_model/missing_pervasives.lem b/src/elf_model/missing_pervasives.lem
index 308c43c3..e0b493fe 100644
--- a/src/elf_model/missing_pervasives.lem
+++ b/src/elf_model/missing_pervasives.lem
@@ -14,6 +14,27 @@ let rec intercalate sep xs =
| x::xs -> x::sep::intercalate sep xs
end
+(** [mapMaybei f xs] maps a function expecting an index (the position in the list
+ * [xs] that it is currently viewing) and producing a [maybe] type across a list.
+ * Elements that produce [Nothing] under [f] are discarded in the output, whilst
+ * those producing [Just e] for some [e] are kept.
+ *)
+val mapMaybei' : forall 'a 'b. (nat -> 'a -> maybe 'b) -> nat -> list 'a -> list 'b
+let rec mapMaybei' f idx xs =
+ match xs with
+ | [] -> []
+ | x::xs ->
+ match f idx x with
+ | Nothing -> mapMaybei' f (1 + idx) xs
+ | Just e -> e :: mapMaybei' f (1 + idx) xs
+ end
+ end
+
+val mapMaybei : forall 'a 'b. (nat -> 'a -> maybe 'b) -> list 'a -> list 'b
+
+let mapMaybei f xs =
+ mapMaybei' f 0 xs
+
(** [unlines xs] concatenates a list of strings [xs], placing each entry
* on a new line.
*)
@@ -52,4 +73,4 @@ declare ocaml target_rep function string_of_nat = `string_of_int`
* Fails if the index is negative, or beyond the end of the string.
*)
val string_suffix : nat -> string -> maybe string
-declare ocaml target_rep function string_suffix = `Ml_bindings.string_suffix` \ No newline at end of file
+declare ocaml target_rep function string_suffix = `Ml_bindings.string_suffix`
diff --git a/src/elf_model/ml_bindings.ml b/src/elf_model/ml_bindings.ml
index 0dd4d152..c2923c2e 100644
--- a/src/elf_model/ml_bindings.ml
+++ b/src/elf_model/ml_bindings.ml
@@ -1,323 +1,1274 @@
open Endianness
+
open Error
-
-let decimal_string_of_int64 e =
- let i = Int64.to_int e in
- string_of_int i
-;;
-
+
+let decimal_string_of_int64 e = let i = Int64.to_int e in string_of_int i
+
let hex_string_of_int64 (e : Int64.t) : string =
- let i = Int64.to_int e in
- Printf.sprintf "0x%x" i
-;;
-
+ let i = Int64.to_int e in Printf.sprintf "0x%x" i
+
let partition_bitstring size bitstring =
- Bitstring.takebits size bitstring, Bitstring.dropbits size bitstring
-;;
-
+ ((Bitstring.takebits size bitstring), (Bitstring.dropbits size bitstring))
+
let acquire_bitstring path_to_target =
try
- let bitstring = Bitstring.bitstring_of_file path_to_target in
- return bitstring
- with _ ->
- Fail ("acquire_bitstring: cannot open file" ^ path_to_target)
-
+ let bitstring = Bitstring.bitstring_of_file path_to_target
+ in return bitstring
+ with | _ -> Fail ("acquire_bitstring: cannot open file" ^ path_to_target)
+
(** Unsigned char type *)
-
let read_unsigned_char_le bs rest =
- bitmatch bs with
- | { unsigned : 8 : littleendian } -> return (Uint32.of_int unsigned, rest)
- | { _ } -> Fail "read_unsigned_char_le"
-;;
-
+ let (__pabitstring_data_1001, __pabitstring_original_off_1004,
+ __pabitstring_original_len_1005) =
+ bs in
+ let __pabitstring_off_1002 = __pabitstring_original_off_1004
+ and __pabitstring_len_1003 = __pabitstring_original_len_1005 in
+ let __pabitstring_off_aligned_1006 = (__pabitstring_off_1002 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1006;
+ let __pabitstring_result_1007 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1003 >= 8
+ then
+ (let v =
+ if __pabitstring_off_aligned_1006
+ then
+ (let o = (__pabitstring_original_off_1004 lsr 3) + 0
+ in
+ Char.code (String.unsafe_get __pabitstring_data_1001 o))
+ else
+ Bitstring.extract_char_unsigned __pabitstring_data_1001
+ __pabitstring_off_1002 __pabitstring_len_1003 8 in
+ let __pabitstring_off_1002 = __pabitstring_off_1002 + 8
+ and __pabitstring_len_1003 = __pabitstring_len_1003 - 8
+ in
+ match v with
+ | unsigned when true ->
+ (__pabitstring_result_1007 :=
+ Some (return ((Uint32.of_int unsigned), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1007 := Some (Fail "read_unsigned_char_le");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1007 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 28, 2))))
+
let read_unsigned_char_be bs rest =
- bitmatch bs with
- | { unsigned : 8 : bigendian } -> return (Uint32.of_int unsigned, rest)
- | { _ } -> Fail "read_unsigned_char_be"
-;;
-
+ let (__pabitstring_data_1008, __pabitstring_original_off_1011,
+ __pabitstring_original_len_1012) =
+ bs in
+ let __pabitstring_off_1009 = __pabitstring_original_off_1011
+ and __pabitstring_len_1010 = __pabitstring_original_len_1012 in
+ let __pabitstring_off_aligned_1013 = (__pabitstring_off_1009 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1013;
+ let __pabitstring_result_1014 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1010 >= 8
+ then
+ (let v =
+ if __pabitstring_off_aligned_1013
+ then
+ (let o = (__pabitstring_original_off_1011 lsr 3) + 0
+ in
+ Char.code (String.unsafe_get __pabitstring_data_1008 o))
+ else
+ Bitstring.extract_char_unsigned __pabitstring_data_1008
+ __pabitstring_off_1009 __pabitstring_len_1010 8 in
+ let __pabitstring_off_1009 = __pabitstring_off_1009 + 8
+ and __pabitstring_len_1010 = __pabitstring_len_1010 - 8
+ in
+ match v with
+ | unsigned when true ->
+ (__pabitstring_result_1014 :=
+ Some (return ((Uint32.of_int unsigned), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1014 := Some (Fail "read_unsigned_char_be");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1014 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 34, 2))))
+
let read_unsigned_char endian bs =
- let cut, rest = partition_bitstring 8 bs in
+ let (cut, rest) = partition_bitstring 8 bs
+ in
match endian with
- | Little -> read_unsigned_char_le cut rest
- | Big -> read_unsigned_char_be cut rest
-;;
-
+ | Little -> read_unsigned_char_le cut rest
+ | Big -> read_unsigned_char_be cut rest
+
(** ELF address type:
* 4 byte unsigned type on 32-bit architectures.
* 8 byte unsigned type on 64-bit architectures.
*)
-
let read_elf32_addr_le bs rest =
- bitmatch bs with
- | { addr : 32 : littleendian } -> return (Uint32.of_int32 addr, rest)
- | { _ } -> Fail "read_elf32_addr_le"
-;;
-
+ let (__pabitstring_data_1015, __pabitstring_original_off_1018,
+ __pabitstring_original_len_1019) =
+ bs in
+ let __pabitstring_off_1016 = __pabitstring_original_off_1018
+ and __pabitstring_len_1017 = __pabitstring_original_len_1019 in
+ let __pabitstring_off_aligned_1020 = (__pabitstring_off_1016 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1020;
+ let __pabitstring_result_1021 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1017 >= 32
+ then
+ (let v =
+ if __pabitstring_off_aligned_1020
+ then
+ (let o = (__pabitstring_original_off_1018 lsr 3) + 0 in
+ let zero = Int32.of_int 0
+ in
+ Bitstring.extract_fastpath_int32_le_unsigned
+ __pabitstring_data_1015 o zero)
+ else
+ Bitstring.extract_int32_le_unsigned
+ __pabitstring_data_1015 __pabitstring_off_1016
+ __pabitstring_len_1017 32 in
+ let __pabitstring_off_1016 = __pabitstring_off_1016 + 32
+ and __pabitstring_len_1017 = __pabitstring_len_1017 - 32
+ in
+ match v with
+ | addr when true ->
+ (__pabitstring_result_1021 :=
+ Some (return ((Uint32.of_int32 addr), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1021 := Some (Fail "read_elf32_addr_le");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1021 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 52, 2))))
+
let read_elf32_addr_be bs rest =
- bitmatch bs with
- | { addr : 32 : bigendian } -> return (Uint32.of_int32 addr, rest)
- | { _ } -> Fail "read_elf32_addr_be"
-;;
-
+ let (__pabitstring_data_1022, __pabitstring_original_off_1025,
+ __pabitstring_original_len_1026) =
+ bs in
+ let __pabitstring_off_1023 = __pabitstring_original_off_1025
+ and __pabitstring_len_1024 = __pabitstring_original_len_1026 in
+ let __pabitstring_off_aligned_1027 = (__pabitstring_off_1023 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1027;
+ let __pabitstring_result_1028 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1024 >= 32
+ then
+ (let v =
+ if __pabitstring_off_aligned_1027
+ then
+ (let o = (__pabitstring_original_off_1025 lsr 3) + 0 in
+ let zero = Int32.of_int 0
+ in
+ Bitstring.extract_fastpath_int32_be_unsigned
+ __pabitstring_data_1022 o zero)
+ else
+ Bitstring.extract_int32_be_unsigned
+ __pabitstring_data_1022 __pabitstring_off_1023
+ __pabitstring_len_1024 32 in
+ let __pabitstring_off_1023 = __pabitstring_off_1023 + 32
+ and __pabitstring_len_1024 = __pabitstring_len_1024 - 32
+ in
+ match v with
+ | addr when true ->
+ (__pabitstring_result_1028 :=
+ Some (return ((Uint32.of_int32 addr), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1028 := Some (Fail "read_elf32_addr_be");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1028 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 58, 2))))
+
let read_elf32_addr endian bs =
- let cut, rest = partition_bitstring 32 bs in
- match endian with
- | Little -> read_elf32_addr_le cut rest
- | Big -> read_elf32_addr_be cut rest
-;;
-
+ let (cut, rest) = partition_bitstring 32 bs
+ in
+ match endian with
+ | Little -> read_elf32_addr_le cut rest
+ | Big -> read_elf32_addr_be cut rest
+
let read_elf64_addr_le bs rest =
- bitmatch bs with
- | { addr : 64 : littleendian } -> return (Uint64.of_int64 addr, rest)
- | { _ } -> Fail "read_elf64_addr_le"
-;;
-
+ let (__pabitstring_data_1029, __pabitstring_original_off_1032,
+ __pabitstring_original_len_1033) =
+ bs in
+ let __pabitstring_off_1030 = __pabitstring_original_off_1032
+ and __pabitstring_len_1031 = __pabitstring_original_len_1033 in
+ let __pabitstring_off_aligned_1034 = (__pabitstring_off_1030 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1034;
+ let __pabitstring_result_1035 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1031 >= 64
+ then
+ (let v =
+ if __pabitstring_off_aligned_1034
+ then
+ (let o = (__pabitstring_original_off_1032 lsr 3) + 0 in
+ let zero = Int64.of_int 0
+ in
+ Bitstring.extract_fastpath_int64_le_unsigned
+ __pabitstring_data_1029 o zero)
+ else
+ Bitstring.extract_int64_le_unsigned
+ __pabitstring_data_1029 __pabitstring_off_1030
+ __pabitstring_len_1031 64 in
+ let __pabitstring_off_1030 = __pabitstring_off_1030 + 64
+ and __pabitstring_len_1031 = __pabitstring_len_1031 - 64
+ in
+ match v with
+ | addr when true ->
+ (__pabitstring_result_1035 :=
+ Some (return ((Uint64.of_int64 addr), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1035 := Some (Fail "read_elf64_addr_le");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1035 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 71, 2))))
+
let read_elf64_addr_be bs rest =
- bitmatch bs with
- | { addr : 64 : bigendian } -> return (Uint64.of_int64 addr, rest)
- | { _ } -> Fail "read_elf64_addr_be"
-;;
-
+ let (__pabitstring_data_1036, __pabitstring_original_off_1039,
+ __pabitstring_original_len_1040) =
+ bs in
+ let __pabitstring_off_1037 = __pabitstring_original_off_1039
+ and __pabitstring_len_1038 = __pabitstring_original_len_1040 in
+ let __pabitstring_off_aligned_1041 = (__pabitstring_off_1037 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1041;
+ let __pabitstring_result_1042 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1038 >= 64
+ then
+ (let v =
+ if __pabitstring_off_aligned_1041
+ then
+ (let o = (__pabitstring_original_off_1039 lsr 3) + 0 in
+ let zero = Int64.of_int 0
+ in
+ Bitstring.extract_fastpath_int64_be_unsigned
+ __pabitstring_data_1036 o zero)
+ else
+ Bitstring.extract_int64_be_unsigned
+ __pabitstring_data_1036 __pabitstring_off_1037
+ __pabitstring_len_1038 64 in
+ let __pabitstring_off_1037 = __pabitstring_off_1037 + 64
+ and __pabitstring_len_1038 = __pabitstring_len_1038 - 64
+ in
+ match v with
+ | addr when true ->
+ (__pabitstring_result_1042 :=
+ Some (return ((Uint64.of_int64 addr), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1042 := Some (Fail "read_elf64_addr_be");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1042 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 77, 2))))
+
let read_elf64_addr endian bs =
- let cut, rest = partition_bitstring 64 bs in
+ let (cut, rest) = partition_bitstring 64 bs
+ in
match endian with
- | Little -> read_elf64_addr_le cut rest
- | Big -> read_elf64_addr_be cut rest
-;;
-
+ | Little -> read_elf64_addr_le cut rest
+ | Big -> read_elf64_addr_be cut rest
+
(** ELF offset type:
* 4 byte unsigned type on 32-bit architectures.
* 8 byte unsigned type on 64-bit architectures.
*)
let read_elf32_off_le bs rest =
- bitmatch bs with
- | { off : 32 : littleendian } -> return (Uint32.of_int32 off, rest)
- | { _ } -> Fail "read_elf32_off_le"
-;;
-
+ let (__pabitstring_data_1043, __pabitstring_original_off_1046,
+ __pabitstring_original_len_1047) =
+ bs in
+ let __pabitstring_off_1044 = __pabitstring_original_off_1046
+ and __pabitstring_len_1045 = __pabitstring_original_len_1047 in
+ let __pabitstring_off_aligned_1048 = (__pabitstring_off_1044 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1048;
+ let __pabitstring_result_1049 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1045 >= 32
+ then
+ (let v =
+ if __pabitstring_off_aligned_1048
+ then
+ (let o = (__pabitstring_original_off_1046 lsr 3) + 0 in
+ let zero = Int32.of_int 0
+ in
+ Bitstring.extract_fastpath_int32_le_unsigned
+ __pabitstring_data_1043 o zero)
+ else
+ Bitstring.extract_int32_le_unsigned
+ __pabitstring_data_1043 __pabitstring_off_1044
+ __pabitstring_len_1045 32 in
+ let __pabitstring_off_1044 = __pabitstring_off_1044 + 32
+ and __pabitstring_len_1045 = __pabitstring_len_1045 - 32
+ in
+ match v with
+ | off when true ->
+ (__pabitstring_result_1049 :=
+ Some (return ((Uint32.of_int32 off), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1049 := Some (Fail "read_elf32_off_le");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1049 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 94, 2))))
+
let read_elf32_off_be bs rest =
- bitmatch bs with
- | { off : 32 : bigendian } -> return (Uint32.of_int32 off, rest)
- | { _ } -> Fail "read_elf32_off_be"
-;;
-
+ let (__pabitstring_data_1050, __pabitstring_original_off_1053,
+ __pabitstring_original_len_1054) =
+ bs in
+ let __pabitstring_off_1051 = __pabitstring_original_off_1053
+ and __pabitstring_len_1052 = __pabitstring_original_len_1054 in
+ let __pabitstring_off_aligned_1055 = (__pabitstring_off_1051 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1055;
+ let __pabitstring_result_1056 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1052 >= 32
+ then
+ (let v =
+ if __pabitstring_off_aligned_1055
+ then
+ (let o = (__pabitstring_original_off_1053 lsr 3) + 0 in
+ let zero = Int32.of_int 0
+ in
+ Bitstring.extract_fastpath_int32_be_unsigned
+ __pabitstring_data_1050 o zero)
+ else
+ Bitstring.extract_int32_be_unsigned
+ __pabitstring_data_1050 __pabitstring_off_1051
+ __pabitstring_len_1052 32 in
+ let __pabitstring_off_1051 = __pabitstring_off_1051 + 32
+ and __pabitstring_len_1052 = __pabitstring_len_1052 - 32
+ in
+ match v with
+ | off when true ->
+ (__pabitstring_result_1056 :=
+ Some (return ((Uint32.of_int32 off), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1056 := Some (Fail "read_elf32_off_be");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1056 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 100, 2))))
+
let read_elf32_off endian bs =
- let cut, rest = partition_bitstring 32 bs in
+ let (cut, rest) = partition_bitstring 32 bs
+ in
match endian with
- | Little -> read_elf32_off_le cut rest
- | Big -> read_elf32_off_be cut rest
-;;
-
+ | Little -> read_elf32_off_le cut rest
+ | Big -> read_elf32_off_be cut rest
+
let read_elf64_off_le bs rest =
- bitmatch bs with
- | { off : 64 : littleendian } -> return (Uint64.of_int64 off, rest)
- | { _ } -> Fail "read_elf64_off_le"
-;;
-
+ let (__pabitstring_data_1057, __pabitstring_original_off_1060,
+ __pabitstring_original_len_1061) =
+ bs in
+ let __pabitstring_off_1058 = __pabitstring_original_off_1060
+ and __pabitstring_len_1059 = __pabitstring_original_len_1061 in
+ let __pabitstring_off_aligned_1062 = (__pabitstring_off_1058 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1062;
+ let __pabitstring_result_1063 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1059 >= 64
+ then
+ (let v =
+ if __pabitstring_off_aligned_1062
+ then
+ (let o = (__pabitstring_original_off_1060 lsr 3) + 0 in
+ let zero = Int64.of_int 0
+ in
+ Bitstring.extract_fastpath_int64_le_unsigned
+ __pabitstring_data_1057 o zero)
+ else
+ Bitstring.extract_int64_le_unsigned
+ __pabitstring_data_1057 __pabitstring_off_1058
+ __pabitstring_len_1059 64 in
+ let __pabitstring_off_1058 = __pabitstring_off_1058 + 64
+ and __pabitstring_len_1059 = __pabitstring_len_1059 - 64
+ in
+ match v with
+ | off when true ->
+ (__pabitstring_result_1063 :=
+ Some (return ((Uint64.of_int64 off), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1063 := Some (Fail "read_elf64_off_le");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1063 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 113, 2))))
+
let read_elf64_off_be bs rest =
- bitmatch bs with
- | { off : 64: bigendian } -> return (Uint64.of_int64 off, rest)
- | { _ } -> Fail "read_elf64_off_be"
-;;
-
+ let (__pabitstring_data_1064, __pabitstring_original_off_1067,
+ __pabitstring_original_len_1068) =
+ bs in
+ let __pabitstring_off_1065 = __pabitstring_original_off_1067
+ and __pabitstring_len_1066 = __pabitstring_original_len_1068 in
+ let __pabitstring_off_aligned_1069 = (__pabitstring_off_1065 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1069;
+ let __pabitstring_result_1070 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1066 >= 64
+ then
+ (let v =
+ if __pabitstring_off_aligned_1069
+ then
+ (let o = (__pabitstring_original_off_1067 lsr 3) + 0 in
+ let zero = Int64.of_int 0
+ in
+ Bitstring.extract_fastpath_int64_be_unsigned
+ __pabitstring_data_1064 o zero)
+ else
+ Bitstring.extract_int64_be_unsigned
+ __pabitstring_data_1064 __pabitstring_off_1065
+ __pabitstring_len_1066 64 in
+ let __pabitstring_off_1065 = __pabitstring_off_1065 + 64
+ and __pabitstring_len_1066 = __pabitstring_len_1066 - 64
+ in
+ match v with
+ | off when true ->
+ (__pabitstring_result_1070 :=
+ Some (return ((Uint64.of_int64 off), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1070 := Some (Fail "read_elf64_off_be");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1070 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 119, 2))))
+
let read_elf64_off endian bs =
- let cut, rest = partition_bitstring 64 bs in
+ let (cut, rest) = partition_bitstring 64 bs
+ in
match endian with
- | Little -> read_elf64_off_le cut rest
- | Big -> read_elf64_off_be cut rest
-;;
-
+ | Little -> read_elf64_off_le cut rest
+ | Big -> read_elf64_off_be cut rest
+
(** ELF half word type:
* 2 byte unsigned type on 32-bit architectures.
* 2 byte unsigned type on 64-bit architecutres.
*)
-
let read_elf32_half_le bs rest =
- bitmatch bs with
- | { half : 16 : littleendian } -> return (Uint32.of_int half, rest)
- | { _ } -> Fail "read_elf32_half_le"
-;;
-
+ let (__pabitstring_data_1071, __pabitstring_original_off_1074,
+ __pabitstring_original_len_1075) =
+ bs in
+ let __pabitstring_off_1072 = __pabitstring_original_off_1074
+ and __pabitstring_len_1073 = __pabitstring_original_len_1075 in
+ let __pabitstring_off_aligned_1076 = (__pabitstring_off_1072 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1076;
+ let __pabitstring_result_1077 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1073 >= 16
+ then
+ (let v =
+ if __pabitstring_off_aligned_1076
+ then
+ (let o = (__pabitstring_original_off_1074 lsr 3) + 0
+ in
+ Bitstring.extract_fastpath_int16_le_unsigned
+ __pabitstring_data_1071 o)
+ else
+ Bitstring.extract_int_le_unsigned __pabitstring_data_1071
+ __pabitstring_off_1072 __pabitstring_len_1073 16 in
+ let __pabitstring_off_1072 = __pabitstring_off_1072 + 16
+ and __pabitstring_len_1073 = __pabitstring_len_1073 - 16
+ in
+ match v with
+ | half when true ->
+ (__pabitstring_result_1077 :=
+ Some (return ((Uint32.of_int half), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1077 := Some (Fail "read_elf32_half_le");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1077 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 137, 2))))
+
let read_elf32_half_be bs rest =
- bitmatch bs with
- | { half : 16 : bigendian } -> return (Uint32.of_int half, rest)
- | { _ } -> Fail "read_elf32_half_be"
-;;
-
+ let (__pabitstring_data_1078, __pabitstring_original_off_1081,
+ __pabitstring_original_len_1082) =
+ bs in
+ let __pabitstring_off_1079 = __pabitstring_original_off_1081
+ and __pabitstring_len_1080 = __pabitstring_original_len_1082 in
+ let __pabitstring_off_aligned_1083 = (__pabitstring_off_1079 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1083;
+ let __pabitstring_result_1084 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1080 >= 16
+ then
+ (let v =
+ if __pabitstring_off_aligned_1083
+ then
+ (let o = (__pabitstring_original_off_1081 lsr 3) + 0
+ in
+ Bitstring.extract_fastpath_int16_be_unsigned
+ __pabitstring_data_1078 o)
+ else
+ Bitstring.extract_int_be_unsigned __pabitstring_data_1078
+ __pabitstring_off_1079 __pabitstring_len_1080 16 in
+ let __pabitstring_off_1079 = __pabitstring_off_1079 + 16
+ and __pabitstring_len_1080 = __pabitstring_len_1080 - 16
+ in
+ match v with
+ | half when true ->
+ (__pabitstring_result_1084 :=
+ Some (return ((Uint32.of_int half), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1084 := Some (Fail "read_elf32_half_be");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1084 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 143, 2))))
+
let read_elf32_half endian bs =
- let cut, rest = partition_bitstring 16 bs in
+ let (cut, rest) = partition_bitstring 16 bs
+ in
match endian with
- | Little -> read_elf32_half_le cut rest
- | Big -> read_elf32_half_be cut rest
-;;
-
+ | Little -> read_elf32_half_le cut rest
+ | Big -> read_elf32_half_be cut rest
+
let read_elf64_half_le bs rest =
- bitmatch bs with
- | { half : 16 : littleendian } -> return (Uint32.of_int half, rest)
- | { _ } -> Fail "read_elf64_half_le"
-;;
-
+ let (__pabitstring_data_1085, __pabitstring_original_off_1088,
+ __pabitstring_original_len_1089) =
+ bs in
+ let __pabitstring_off_1086 = __pabitstring_original_off_1088
+ and __pabitstring_len_1087 = __pabitstring_original_len_1089 in
+ let __pabitstring_off_aligned_1090 = (__pabitstring_off_1086 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1090;
+ let __pabitstring_result_1091 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1087 >= 16
+ then
+ (let v =
+ if __pabitstring_off_aligned_1090
+ then
+ (let o = (__pabitstring_original_off_1088 lsr 3) + 0
+ in
+ Bitstring.extract_fastpath_int16_le_unsigned
+ __pabitstring_data_1085 o)
+ else
+ Bitstring.extract_int_le_unsigned __pabitstring_data_1085
+ __pabitstring_off_1086 __pabitstring_len_1087 16 in
+ let __pabitstring_off_1086 = __pabitstring_off_1086 + 16
+ and __pabitstring_len_1087 = __pabitstring_len_1087 - 16
+ in
+ match v with
+ | half when true ->
+ (__pabitstring_result_1091 :=
+ Some (return ((Uint32.of_int half), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1091 := Some (Fail "read_elf64_half_le");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1091 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 156, 2))))
+
let read_elf64_half_be bs rest =
- bitmatch bs with
- | { half : 16 : bigendian } -> return (Uint32.of_int half, rest)
- | { _ } -> Fail "read_elf64_half_be"
-;;
-
+ let (__pabitstring_data_1092, __pabitstring_original_off_1095,
+ __pabitstring_original_len_1096) =
+ bs in
+ let __pabitstring_off_1093 = __pabitstring_original_off_1095
+ and __pabitstring_len_1094 = __pabitstring_original_len_1096 in
+ let __pabitstring_off_aligned_1097 = (__pabitstring_off_1093 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1097;
+ let __pabitstring_result_1098 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1094 >= 16
+ then
+ (let v =
+ if __pabitstring_off_aligned_1097
+ then
+ (let o = (__pabitstring_original_off_1095 lsr 3) + 0
+ in
+ Bitstring.extract_fastpath_int16_be_unsigned
+ __pabitstring_data_1092 o)
+ else
+ Bitstring.extract_int_be_unsigned __pabitstring_data_1092
+ __pabitstring_off_1093 __pabitstring_len_1094 16 in
+ let __pabitstring_off_1093 = __pabitstring_off_1093 + 16
+ and __pabitstring_len_1094 = __pabitstring_len_1094 - 16
+ in
+ match v with
+ | half when true ->
+ (__pabitstring_result_1098 :=
+ Some (return ((Uint32.of_int half), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1098 := Some (Fail "read_elf64_half_be");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1098 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 162, 2))))
+
let read_elf64_half endian bs =
- let cut, rest = partition_bitstring 16 bs in
+ let (cut, rest) = partition_bitstring 16 bs
+ in
match endian with
- | Little -> read_elf64_half_le cut rest
- | Big -> read_elf64_half_be cut rest
-;;
-
+ | Little -> read_elf64_half_le cut rest
+ | Big -> read_elf64_half_be cut rest
+
(** ELF word type:
* 4 byte unsigned type on 32-bit architectures.
* 4 byte unsigned type on 32-bit architectures.
*)
-
let read_elf32_word_le bs rest =
- bitmatch bs with
- | { word : 32 : littleendian } -> return (Uint32.of_int32 word, rest)
- | { _ } -> Fail "read_elf32_word_le"
-;;
-
+ let (__pabitstring_data_1099, __pabitstring_original_off_1102,
+ __pabitstring_original_len_1103) =
+ bs in
+ let __pabitstring_off_1100 = __pabitstring_original_off_1102
+ and __pabitstring_len_1101 = __pabitstring_original_len_1103 in
+ let __pabitstring_off_aligned_1104 = (__pabitstring_off_1100 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1104;
+ let __pabitstring_result_1105 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1101 >= 32
+ then
+ (let v =
+ if __pabitstring_off_aligned_1104
+ then
+ (let o = (__pabitstring_original_off_1102 lsr 3) + 0 in
+ let zero = Int32.of_int 0
+ in
+ Bitstring.extract_fastpath_int32_le_unsigned
+ __pabitstring_data_1099 o zero)
+ else
+ Bitstring.extract_int32_le_unsigned
+ __pabitstring_data_1099 __pabitstring_off_1100
+ __pabitstring_len_1101 32 in
+ let __pabitstring_off_1100 = __pabitstring_off_1100 + 32
+ and __pabitstring_len_1101 = __pabitstring_len_1101 - 32
+ in
+ match v with
+ | word when true ->
+ (__pabitstring_result_1105 :=
+ Some (return ((Uint32.of_int32 word), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1105 := Some (Fail "read_elf32_word_le");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1105 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 180, 2))))
+
let read_elf32_word_be bs rest =
- bitmatch bs with
- | { word : 32 : bigendian } -> return (Uint32.of_int32 word, rest)
- | { _ } -> Fail "read_elf32_word_be"
-;;
-
+ let (__pabitstring_data_1106, __pabitstring_original_off_1109,
+ __pabitstring_original_len_1110) =
+ bs in
+ let __pabitstring_off_1107 = __pabitstring_original_off_1109
+ and __pabitstring_len_1108 = __pabitstring_original_len_1110 in
+ let __pabitstring_off_aligned_1111 = (__pabitstring_off_1107 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1111;
+ let __pabitstring_result_1112 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1108 >= 32
+ then
+ (let v =
+ if __pabitstring_off_aligned_1111
+ then
+ (let o = (__pabitstring_original_off_1109 lsr 3) + 0 in
+ let zero = Int32.of_int 0
+ in
+ Bitstring.extract_fastpath_int32_be_unsigned
+ __pabitstring_data_1106 o zero)
+ else
+ Bitstring.extract_int32_be_unsigned
+ __pabitstring_data_1106 __pabitstring_off_1107
+ __pabitstring_len_1108 32 in
+ let __pabitstring_off_1107 = __pabitstring_off_1107 + 32
+ and __pabitstring_len_1108 = __pabitstring_len_1108 - 32
+ in
+ match v with
+ | word when true ->
+ (__pabitstring_result_1112 :=
+ Some (return ((Uint32.of_int32 word), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1112 := Some (Fail "read_elf32_word_be");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1112 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 186, 2))))
+
let read_elf32_word endian bs =
- let cut, rest = partition_bitstring 32 bs in
+ let (cut, rest) = partition_bitstring 32 bs
+ in
match endian with
- | Little -> read_elf32_word_le cut rest
- | Big -> read_elf32_word_be cut rest
-;;
-
+ | Little -> read_elf32_word_le cut rest
+ | Big -> read_elf32_word_be cut rest
+
let read_elf64_word_le bs rest =
- bitmatch bs with
- | { word : 32 : littleendian } -> return (Uint32.of_int32 word, rest)
- | { _ } -> Fail "read_elf64_word_le"
-;;
-
+ let (__pabitstring_data_1113, __pabitstring_original_off_1116,
+ __pabitstring_original_len_1117) =
+ bs in
+ let __pabitstring_off_1114 = __pabitstring_original_off_1116
+ and __pabitstring_len_1115 = __pabitstring_original_len_1117 in
+ let __pabitstring_off_aligned_1118 = (__pabitstring_off_1114 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1118;
+ let __pabitstring_result_1119 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1115 >= 32
+ then
+ (let v =
+ if __pabitstring_off_aligned_1118
+ then
+ (let o = (__pabitstring_original_off_1116 lsr 3) + 0 in
+ let zero = Int32.of_int 0
+ in
+ Bitstring.extract_fastpath_int32_le_unsigned
+ __pabitstring_data_1113 o zero)
+ else
+ Bitstring.extract_int32_le_unsigned
+ __pabitstring_data_1113 __pabitstring_off_1114
+ __pabitstring_len_1115 32 in
+ let __pabitstring_off_1114 = __pabitstring_off_1114 + 32
+ and __pabitstring_len_1115 = __pabitstring_len_1115 - 32
+ in
+ match v with
+ | word when true ->
+ (__pabitstring_result_1119 :=
+ Some (return ((Uint32.of_int32 word), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1119 := Some (Fail "read_elf64_word_le");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1119 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 199, 2))))
+
let read_elf64_word_be bs rest =
- bitmatch bs with
- | { word : 32 : bigendian } -> return (Uint32.of_int32 word, rest)
- | { _ } -> Fail "read_elf64_word_be"
-;;
-
+ let (__pabitstring_data_1120, __pabitstring_original_off_1123,
+ __pabitstring_original_len_1124) =
+ bs in
+ let __pabitstring_off_1121 = __pabitstring_original_off_1123
+ and __pabitstring_len_1122 = __pabitstring_original_len_1124 in
+ let __pabitstring_off_aligned_1125 = (__pabitstring_off_1121 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1125;
+ let __pabitstring_result_1126 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1122 >= 32
+ then
+ (let v =
+ if __pabitstring_off_aligned_1125
+ then
+ (let o = (__pabitstring_original_off_1123 lsr 3) + 0 in
+ let zero = Int32.of_int 0
+ in
+ Bitstring.extract_fastpath_int32_be_unsigned
+ __pabitstring_data_1120 o zero)
+ else
+ Bitstring.extract_int32_be_unsigned
+ __pabitstring_data_1120 __pabitstring_off_1121
+ __pabitstring_len_1122 32 in
+ let __pabitstring_off_1121 = __pabitstring_off_1121 + 32
+ and __pabitstring_len_1122 = __pabitstring_len_1122 - 32
+ in
+ match v with
+ | word when true ->
+ (__pabitstring_result_1126 :=
+ Some (return ((Uint32.of_int32 word), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1126 := Some (Fail "read_elf64_word_be");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1126 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 205, 2))))
+
let read_elf64_word endian bs =
- let cut, rest = partition_bitstring 32 bs in
+ let (cut, rest) = partition_bitstring 32 bs
+ in
match endian with
- | Little -> read_elf64_word_le cut rest
- | Big -> read_elf64_word_be cut rest
-;;
-
+ | Little -> read_elf64_word_le cut rest
+ | Big -> read_elf64_word_be cut rest
+
(** ELF signed word type:
* 4 byte signed type on 32-bit architectures
* 4 byte signed type on 64-bit architectures
*)
-
let read_elf32_sword_le bs rest =
- bitmatch bs with
- | { word : 32 : littleendian } -> return (word, rest)
- | { _ } -> Fail "read_elf32_sword_le"
-;;
-
+ let (__pabitstring_data_1127, __pabitstring_original_off_1130,
+ __pabitstring_original_len_1131) =
+ bs in
+ let __pabitstring_off_1128 = __pabitstring_original_off_1130
+ and __pabitstring_len_1129 = __pabitstring_original_len_1131 in
+ let __pabitstring_off_aligned_1132 = (__pabitstring_off_1128 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1132;
+ let __pabitstring_result_1133 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1129 >= 32
+ then
+ (let v =
+ if __pabitstring_off_aligned_1132
+ then
+ (let o = (__pabitstring_original_off_1130 lsr 3) + 0 in
+ let zero = Int32.of_int 0
+ in
+ Bitstring.extract_fastpath_int32_le_unsigned
+ __pabitstring_data_1127 o zero)
+ else
+ Bitstring.extract_int32_le_unsigned
+ __pabitstring_data_1127 __pabitstring_off_1128
+ __pabitstring_len_1129 32 in
+ let __pabitstring_off_1128 = __pabitstring_off_1128 + 32
+ and __pabitstring_len_1129 = __pabitstring_len_1129 - 32
+ in
+ match v with
+ | word when true ->
+ (__pabitstring_result_1133 := Some (return (word, rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1133 := Some (Fail "read_elf32_sword_le");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1133 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 223, 2))))
+
let read_elf32_sword_be bs rest =
- bitmatch bs with
- | { word : 32 : bigendian } -> return (word, rest)
- | { _ } -> Fail "read_elf32_sword_be"
-;;
-
+ let (__pabitstring_data_1134, __pabitstring_original_off_1137,
+ __pabitstring_original_len_1138) =
+ bs in
+ let __pabitstring_off_1135 = __pabitstring_original_off_1137
+ and __pabitstring_len_1136 = __pabitstring_original_len_1138 in
+ let __pabitstring_off_aligned_1139 = (__pabitstring_off_1135 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1139;
+ let __pabitstring_result_1140 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1136 >= 32
+ then
+ (let v =
+ if __pabitstring_off_aligned_1139
+ then
+ (let o = (__pabitstring_original_off_1137 lsr 3) + 0 in
+ let zero = Int32.of_int 0
+ in
+ Bitstring.extract_fastpath_int32_be_unsigned
+ __pabitstring_data_1134 o zero)
+ else
+ Bitstring.extract_int32_be_unsigned
+ __pabitstring_data_1134 __pabitstring_off_1135
+ __pabitstring_len_1136 32 in
+ let __pabitstring_off_1135 = __pabitstring_off_1135 + 32
+ and __pabitstring_len_1136 = __pabitstring_len_1136 - 32
+ in
+ match v with
+ | word when true ->
+ (__pabitstring_result_1140 := Some (return (word, rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1140 := Some (Fail "read_elf32_sword_be");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1140 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 229, 2))))
+
let read_elf32_sword endian bs =
- let cut, rest = partition_bitstring 32 bs in
+ let (cut, rest) = partition_bitstring 32 bs
+ in
match endian with
- | Little -> read_elf32_sword_le cut rest
- | Big -> read_elf32_sword_be cut rest
-;;
-
+ | Little -> read_elf32_sword_le cut rest
+ | Big -> read_elf32_sword_be cut rest
+
let read_elf64_sword_le bs rest =
- bitmatch bs with
- | { word : 32 : littleendian } -> return (word, rest)
- | { _ } -> Fail "read_elf64_sword_le"
-;;
-
+ let (__pabitstring_data_1141, __pabitstring_original_off_1144,
+ __pabitstring_original_len_1145) =
+ bs in
+ let __pabitstring_off_1142 = __pabitstring_original_off_1144
+ and __pabitstring_len_1143 = __pabitstring_original_len_1145 in
+ let __pabitstring_off_aligned_1146 = (__pabitstring_off_1142 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1146;
+ let __pabitstring_result_1147 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1143 >= 32
+ then
+ (let v =
+ if __pabitstring_off_aligned_1146
+ then
+ (let o = (__pabitstring_original_off_1144 lsr 3) + 0 in
+ let zero = Int32.of_int 0
+ in
+ Bitstring.extract_fastpath_int32_le_unsigned
+ __pabitstring_data_1141 o zero)
+ else
+ Bitstring.extract_int32_le_unsigned
+ __pabitstring_data_1141 __pabitstring_off_1142
+ __pabitstring_len_1143 32 in
+ let __pabitstring_off_1142 = __pabitstring_off_1142 + 32
+ and __pabitstring_len_1143 = __pabitstring_len_1143 - 32
+ in
+ match v with
+ | word when true ->
+ (__pabitstring_result_1147 := Some (return (word, rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1147 := Some (Fail "read_elf64_sword_le");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1147 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 242, 2))))
+
let read_elf64_sword_be bs rest =
- bitmatch bs with
- | { word : 32 : bigendian } -> return (word, rest)
- | { _ } -> Fail "read_elf64_sword_be"
-;;
-
+ let (__pabitstring_data_1148, __pabitstring_original_off_1151,
+ __pabitstring_original_len_1152) =
+ bs in
+ let __pabitstring_off_1149 = __pabitstring_original_off_1151
+ and __pabitstring_len_1150 = __pabitstring_original_len_1152 in
+ let __pabitstring_off_aligned_1153 = (__pabitstring_off_1149 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1153;
+ let __pabitstring_result_1154 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1150 >= 32
+ then
+ (let v =
+ if __pabitstring_off_aligned_1153
+ then
+ (let o = (__pabitstring_original_off_1151 lsr 3) + 0 in
+ let zero = Int32.of_int 0
+ in
+ Bitstring.extract_fastpath_int32_be_unsigned
+ __pabitstring_data_1148 o zero)
+ else
+ Bitstring.extract_int32_be_unsigned
+ __pabitstring_data_1148 __pabitstring_off_1149
+ __pabitstring_len_1150 32 in
+ let __pabitstring_off_1149 = __pabitstring_off_1149 + 32
+ and __pabitstring_len_1150 = __pabitstring_len_1150 - 32
+ in
+ match v with
+ | word when true ->
+ (__pabitstring_result_1154 := Some (return (word, rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1154 := Some (Fail "read_elf64_sword_be");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1154 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 248, 2))))
+
let read_elf64_sword endian bs =
- let cut, rest = partition_bitstring 32 bs in
+ let (cut, rest) = partition_bitstring 32 bs
+ in
match endian with
- | Little -> read_elf64_sword_le cut rest
- | Big -> read_elf64_sword_be cut rest
-;;
-
+ | Little -> read_elf64_sword_le cut rest
+ | Big -> read_elf64_sword_be cut rest
+
(** ELF extra wide word type:
* 8 byte unsigned type on 64-bit architectures.
*)
-
let read_elf64_xword_le bs rest =
- bitmatch bs with
- | { addr : 64 : littleendian } -> return (Uint64.of_int64 addr, rest)
- | { _ } -> Fail "read_elf64_xword_le"
-;;
-
+ let (__pabitstring_data_1155, __pabitstring_original_off_1158,
+ __pabitstring_original_len_1159) =
+ bs in
+ let __pabitstring_off_1156 = __pabitstring_original_off_1158
+ and __pabitstring_len_1157 = __pabitstring_original_len_1159 in
+ let __pabitstring_off_aligned_1160 = (__pabitstring_off_1156 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1160;
+ let __pabitstring_result_1161 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1157 >= 64
+ then
+ (let v =
+ if __pabitstring_off_aligned_1160
+ then
+ (let o = (__pabitstring_original_off_1158 lsr 3) + 0 in
+ let zero = Int64.of_int 0
+ in
+ Bitstring.extract_fastpath_int64_le_unsigned
+ __pabitstring_data_1155 o zero)
+ else
+ Bitstring.extract_int64_le_unsigned
+ __pabitstring_data_1155 __pabitstring_off_1156
+ __pabitstring_len_1157 64 in
+ let __pabitstring_off_1156 = __pabitstring_off_1156 + 64
+ and __pabitstring_len_1157 = __pabitstring_len_1157 - 64
+ in
+ match v with
+ | addr when true ->
+ (__pabitstring_result_1161 :=
+ Some (return ((Uint64.of_int64 addr), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1161 := Some (Fail "read_elf64_xword_le");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1161 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 265, 2))))
+
let read_elf64_xword_be bs rest =
- bitmatch bs with
- | { addr : 64 : bigendian } -> return (Uint64.of_int64 addr, rest)
- | { _ } -> Fail "read_elf64_xword_be"
-;;
-
+ let (__pabitstring_data_1162, __pabitstring_original_off_1165,
+ __pabitstring_original_len_1166) =
+ bs in
+ let __pabitstring_off_1163 = __pabitstring_original_off_1165
+ and __pabitstring_len_1164 = __pabitstring_original_len_1166 in
+ let __pabitstring_off_aligned_1167 = (__pabitstring_off_1163 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1167;
+ let __pabitstring_result_1168 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1164 >= 64
+ then
+ (let v =
+ if __pabitstring_off_aligned_1167
+ then
+ (let o = (__pabitstring_original_off_1165 lsr 3) + 0 in
+ let zero = Int64.of_int 0
+ in
+ Bitstring.extract_fastpath_int64_be_unsigned
+ __pabitstring_data_1162 o zero)
+ else
+ Bitstring.extract_int64_be_unsigned
+ __pabitstring_data_1162 __pabitstring_off_1163
+ __pabitstring_len_1164 64 in
+ let __pabitstring_off_1163 = __pabitstring_off_1163 + 64
+ and __pabitstring_len_1164 = __pabitstring_len_1164 - 64
+ in
+ match v with
+ | addr when true ->
+ (__pabitstring_result_1168 :=
+ Some (return ((Uint64.of_int64 addr), rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1168 := Some (Fail "read_elf64_xword_be");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1168 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 271, 2))))
+
let read_elf64_xword endian bs =
- let cut, rest = partition_bitstring 64 bs in
+ let (cut, rest) = partition_bitstring 64 bs
+ in
match endian with
- | Little -> read_elf64_xword_le cut rest
- | Big -> read_elf64_xword_be cut rest
-;;
-
+ | Little -> read_elf64_xword_le cut rest
+ | Big -> read_elf64_xword_be cut rest
+
(** ELF signed extra wide word type:
* 8 byte signed type on 64-bit architectures.
*)
-
let read_elf64_sxword_le bs rest =
- bitmatch bs with
- | { addr : 64 : littleendian } -> return (addr, rest)
- | { _ } -> Fail "read_elf64_sxword_le"
-;;
-
+ let (__pabitstring_data_1169, __pabitstring_original_off_1172,
+ __pabitstring_original_len_1173) =
+ bs in
+ let __pabitstring_off_1170 = __pabitstring_original_off_1172
+ and __pabitstring_len_1171 = __pabitstring_original_len_1173 in
+ let __pabitstring_off_aligned_1174 = (__pabitstring_off_1170 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1174;
+ let __pabitstring_result_1175 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1171 >= 64
+ then
+ (let v =
+ if __pabitstring_off_aligned_1174
+ then
+ (let o = (__pabitstring_original_off_1172 lsr 3) + 0 in
+ let zero = Int64.of_int 0
+ in
+ Bitstring.extract_fastpath_int64_le_unsigned
+ __pabitstring_data_1169 o zero)
+ else
+ Bitstring.extract_int64_le_unsigned
+ __pabitstring_data_1169 __pabitstring_off_1170
+ __pabitstring_len_1171 64 in
+ let __pabitstring_off_1170 = __pabitstring_off_1170 + 64
+ and __pabitstring_len_1171 = __pabitstring_len_1171 - 64
+ in
+ match v with
+ | addr when true ->
+ (__pabitstring_result_1175 := Some (return (addr, rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1175 := Some (Fail "read_elf64_sxword_le");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1175 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 288, 2))))
+
let read_elf64_sxword_be bs rest =
- bitmatch bs with
- | { addr : 64 : bigendian } -> return (addr, rest)
- | { _ } -> Fail "read_elf64_sxword_be"
-;;
-
+ let (__pabitstring_data_1176, __pabitstring_original_off_1179,
+ __pabitstring_original_len_1180) =
+ bs in
+ let __pabitstring_off_1177 = __pabitstring_original_off_1179
+ and __pabitstring_len_1178 = __pabitstring_original_len_1180 in
+ let __pabitstring_off_aligned_1181 = (__pabitstring_off_1177 land 7) = 0
+ in
+ (ignore __pabitstring_off_aligned_1181;
+ let __pabitstring_result_1182 = ref None
+ in
+ ((try
+ (if __pabitstring_len_1178 >= 64
+ then
+ (let v =
+ if __pabitstring_off_aligned_1181
+ then
+ (let o = (__pabitstring_original_off_1179 lsr 3) + 0 in
+ let zero = Int64.of_int 0
+ in
+ Bitstring.extract_fastpath_int64_be_unsigned
+ __pabitstring_data_1176 o zero)
+ else
+ Bitstring.extract_int64_be_unsigned
+ __pabitstring_data_1176 __pabitstring_off_1177
+ __pabitstring_len_1178 64 in
+ let __pabitstring_off_1177 = __pabitstring_off_1177 + 64
+ and __pabitstring_len_1178 = __pabitstring_len_1178 - 64
+ in
+ match v with
+ | addr when true ->
+ (__pabitstring_result_1182 := Some (return (addr, rest));
+ raise Exit)
+ | _ -> ())
+ else ();
+ __pabitstring_result_1182 := Some (Fail "read_elf64_sxword_be");
+ raise Exit)
+ with | Exit -> ());
+ match !__pabitstring_result_1182 with
+ | Some x -> x
+ | None ->
+ raise (Match_failure ("ml_bindings_camlp4_sugared.ml", 294, 2))))
+
let read_elf64_sxword endian bs =
- let cut, rest = partition_bitstring 64 bs in
+ let (cut, rest) = partition_bitstring 64 bs
+ in
match endian with
- | Little -> read_elf64_sxword_le cut rest
- | Big -> read_elf64_sxword_be cut rest
-;;
-
+ | Little -> read_elf64_sxword_le cut rest
+ | Big -> read_elf64_sxword_be cut rest
+
(** Misc. string operations. *)
-
let split_string_on_char strings c =
- let enum = BatString.enum strings in
- let groups = BatEnum.group (fun char -> char <> c) enum in
- let enums = BatEnum.map BatString.of_enum groups in
- BatList.of_enum enums
-;;
-
+ let enum = BatString.enum strings in
+ let groups = BatEnum.group (fun char -> char <> c) enum in
+ let enums = BatEnum.map BatString.of_enum groups in BatList.of_enum enums
+
let string_suffix index str =
- if index < 0 || index > String.length str then
- None
+ if (index < 0) || (index > (String.length str))
+ then None
else
- try
- Some (String.sub str index (String.length str - index))
- with
- | _ -> None
-;; \ No newline at end of file
+ (try Some (String.sub str index ((String.length str) - index))
+ with | _ -> None)
+
+
diff --git a/src/elf_model/ml_bindings_camlp4_sugared.ml b/src/elf_model/ml_bindings_camlp4_sugared.ml
new file mode 100644
index 00000000..0dd4d152
--- /dev/null
+++ b/src/elf_model/ml_bindings_camlp4_sugared.ml
@@ -0,0 +1,323 @@
+open Endianness
+open Error
+
+let decimal_string_of_int64 e =
+ let i = Int64.to_int e in
+ string_of_int i
+;;
+
+let hex_string_of_int64 (e : Int64.t) : string =
+ let i = Int64.to_int e in
+ Printf.sprintf "0x%x" i
+;;
+
+let partition_bitstring size bitstring =
+ Bitstring.takebits size bitstring, Bitstring.dropbits size bitstring
+;;
+
+let acquire_bitstring path_to_target =
+ try
+ let bitstring = Bitstring.bitstring_of_file path_to_target in
+ return bitstring
+ with _ ->
+ Fail ("acquire_bitstring: cannot open file" ^ path_to_target)
+
+(** Unsigned char type *)
+
+let read_unsigned_char_le bs rest =
+ bitmatch bs with
+ | { unsigned : 8 : littleendian } -> return (Uint32.of_int unsigned, rest)
+ | { _ } -> Fail "read_unsigned_char_le"
+;;
+
+let read_unsigned_char_be bs rest =
+ bitmatch bs with
+ | { unsigned : 8 : bigendian } -> return (Uint32.of_int unsigned, rest)
+ | { _ } -> Fail "read_unsigned_char_be"
+;;
+
+let read_unsigned_char endian bs =
+ let cut, rest = partition_bitstring 8 bs in
+ match endian with
+ | Little -> read_unsigned_char_le cut rest
+ | Big -> read_unsigned_char_be cut rest
+;;
+
+(** ELF address type:
+ * 4 byte unsigned type on 32-bit architectures.
+ * 8 byte unsigned type on 64-bit architectures.
+ *)
+
+let read_elf32_addr_le bs rest =
+ bitmatch bs with
+ | { addr : 32 : littleendian } -> return (Uint32.of_int32 addr, rest)
+ | { _ } -> Fail "read_elf32_addr_le"
+;;
+
+let read_elf32_addr_be bs rest =
+ bitmatch bs with
+ | { addr : 32 : bigendian } -> return (Uint32.of_int32 addr, rest)
+ | { _ } -> Fail "read_elf32_addr_be"
+;;
+
+let read_elf32_addr endian bs =
+ let cut, rest = partition_bitstring 32 bs in
+ match endian with
+ | Little -> read_elf32_addr_le cut rest
+ | Big -> read_elf32_addr_be cut rest
+;;
+
+let read_elf64_addr_le bs rest =
+ bitmatch bs with
+ | { addr : 64 : littleendian } -> return (Uint64.of_int64 addr, rest)
+ | { _ } -> Fail "read_elf64_addr_le"
+;;
+
+let read_elf64_addr_be bs rest =
+ bitmatch bs with
+ | { addr : 64 : bigendian } -> return (Uint64.of_int64 addr, rest)
+ | { _ } -> Fail "read_elf64_addr_be"
+;;
+
+let read_elf64_addr endian bs =
+ let cut, rest = partition_bitstring 64 bs in
+ match endian with
+ | Little -> read_elf64_addr_le cut rest
+ | Big -> read_elf64_addr_be cut rest
+;;
+
+(** ELF offset type:
+ * 4 byte unsigned type on 32-bit architectures.
+ * 8 byte unsigned type on 64-bit architectures.
+ *)
+let read_elf32_off_le bs rest =
+ bitmatch bs with
+ | { off : 32 : littleendian } -> return (Uint32.of_int32 off, rest)
+ | { _ } -> Fail "read_elf32_off_le"
+;;
+
+let read_elf32_off_be bs rest =
+ bitmatch bs with
+ | { off : 32 : bigendian } -> return (Uint32.of_int32 off, rest)
+ | { _ } -> Fail "read_elf32_off_be"
+;;
+
+let read_elf32_off endian bs =
+ let cut, rest = partition_bitstring 32 bs in
+ match endian with
+ | Little -> read_elf32_off_le cut rest
+ | Big -> read_elf32_off_be cut rest
+;;
+
+let read_elf64_off_le bs rest =
+ bitmatch bs with
+ | { off : 64 : littleendian } -> return (Uint64.of_int64 off, rest)
+ | { _ } -> Fail "read_elf64_off_le"
+;;
+
+let read_elf64_off_be bs rest =
+ bitmatch bs with
+ | { off : 64: bigendian } -> return (Uint64.of_int64 off, rest)
+ | { _ } -> Fail "read_elf64_off_be"
+;;
+
+let read_elf64_off endian bs =
+ let cut, rest = partition_bitstring 64 bs in
+ match endian with
+ | Little -> read_elf64_off_le cut rest
+ | Big -> read_elf64_off_be cut rest
+;;
+
+(** ELF half word type:
+ * 2 byte unsigned type on 32-bit architectures.
+ * 2 byte unsigned type on 64-bit architecutres.
+ *)
+
+let read_elf32_half_le bs rest =
+ bitmatch bs with
+ | { half : 16 : littleendian } -> return (Uint32.of_int half, rest)
+ | { _ } -> Fail "read_elf32_half_le"
+;;
+
+let read_elf32_half_be bs rest =
+ bitmatch bs with
+ | { half : 16 : bigendian } -> return (Uint32.of_int half, rest)
+ | { _ } -> Fail "read_elf32_half_be"
+;;
+
+let read_elf32_half endian bs =
+ let cut, rest = partition_bitstring 16 bs in
+ match endian with
+ | Little -> read_elf32_half_le cut rest
+ | Big -> read_elf32_half_be cut rest
+;;
+
+let read_elf64_half_le bs rest =
+ bitmatch bs with
+ | { half : 16 : littleendian } -> return (Uint32.of_int half, rest)
+ | { _ } -> Fail "read_elf64_half_le"
+;;
+
+let read_elf64_half_be bs rest =
+ bitmatch bs with
+ | { half : 16 : bigendian } -> return (Uint32.of_int half, rest)
+ | { _ } -> Fail "read_elf64_half_be"
+;;
+
+let read_elf64_half endian bs =
+ let cut, rest = partition_bitstring 16 bs in
+ match endian with
+ | Little -> read_elf64_half_le cut rest
+ | Big -> read_elf64_half_be cut rest
+;;
+
+(** ELF word type:
+ * 4 byte unsigned type on 32-bit architectures.
+ * 4 byte unsigned type on 32-bit architectures.
+ *)
+
+let read_elf32_word_le bs rest =
+ bitmatch bs with
+ | { word : 32 : littleendian } -> return (Uint32.of_int32 word, rest)
+ | { _ } -> Fail "read_elf32_word_le"
+;;
+
+let read_elf32_word_be bs rest =
+ bitmatch bs with
+ | { word : 32 : bigendian } -> return (Uint32.of_int32 word, rest)
+ | { _ } -> Fail "read_elf32_word_be"
+;;
+
+let read_elf32_word endian bs =
+ let cut, rest = partition_bitstring 32 bs in
+ match endian with
+ | Little -> read_elf32_word_le cut rest
+ | Big -> read_elf32_word_be cut rest
+;;
+
+let read_elf64_word_le bs rest =
+ bitmatch bs with
+ | { word : 32 : littleendian } -> return (Uint32.of_int32 word, rest)
+ | { _ } -> Fail "read_elf64_word_le"
+;;
+
+let read_elf64_word_be bs rest =
+ bitmatch bs with
+ | { word : 32 : bigendian } -> return (Uint32.of_int32 word, rest)
+ | { _ } -> Fail "read_elf64_word_be"
+;;
+
+let read_elf64_word endian bs =
+ let cut, rest = partition_bitstring 32 bs in
+ match endian with
+ | Little -> read_elf64_word_le cut rest
+ | Big -> read_elf64_word_be cut rest
+;;
+
+(** ELF signed word type:
+ * 4 byte signed type on 32-bit architectures
+ * 4 byte signed type on 64-bit architectures
+ *)
+
+let read_elf32_sword_le bs rest =
+ bitmatch bs with
+ | { word : 32 : littleendian } -> return (word, rest)
+ | { _ } -> Fail "read_elf32_sword_le"
+;;
+
+let read_elf32_sword_be bs rest =
+ bitmatch bs with
+ | { word : 32 : bigendian } -> return (word, rest)
+ | { _ } -> Fail "read_elf32_sword_be"
+;;
+
+let read_elf32_sword endian bs =
+ let cut, rest = partition_bitstring 32 bs in
+ match endian with
+ | Little -> read_elf32_sword_le cut rest
+ | Big -> read_elf32_sword_be cut rest
+;;
+
+let read_elf64_sword_le bs rest =
+ bitmatch bs with
+ | { word : 32 : littleendian } -> return (word, rest)
+ | { _ } -> Fail "read_elf64_sword_le"
+;;
+
+let read_elf64_sword_be bs rest =
+ bitmatch bs with
+ | { word : 32 : bigendian } -> return (word, rest)
+ | { _ } -> Fail "read_elf64_sword_be"
+;;
+
+let read_elf64_sword endian bs =
+ let cut, rest = partition_bitstring 32 bs in
+ match endian with
+ | Little -> read_elf64_sword_le cut rest
+ | Big -> read_elf64_sword_be cut rest
+;;
+
+(** ELF extra wide word type:
+ * 8 byte unsigned type on 64-bit architectures.
+ *)
+
+let read_elf64_xword_le bs rest =
+ bitmatch bs with
+ | { addr : 64 : littleendian } -> return (Uint64.of_int64 addr, rest)
+ | { _ } -> Fail "read_elf64_xword_le"
+;;
+
+let read_elf64_xword_be bs rest =
+ bitmatch bs with
+ | { addr : 64 : bigendian } -> return (Uint64.of_int64 addr, rest)
+ | { _ } -> Fail "read_elf64_xword_be"
+;;
+
+let read_elf64_xword endian bs =
+ let cut, rest = partition_bitstring 64 bs in
+ match endian with
+ | Little -> read_elf64_xword_le cut rest
+ | Big -> read_elf64_xword_be cut rest
+;;
+
+(** ELF signed extra wide word type:
+ * 8 byte signed type on 64-bit architectures.
+ *)
+
+let read_elf64_sxword_le bs rest =
+ bitmatch bs with
+ | { addr : 64 : littleendian } -> return (addr, rest)
+ | { _ } -> Fail "read_elf64_sxword_le"
+;;
+
+let read_elf64_sxword_be bs rest =
+ bitmatch bs with
+ | { addr : 64 : bigendian } -> return (addr, rest)
+ | { _ } -> Fail "read_elf64_sxword_be"
+;;
+
+let read_elf64_sxword endian bs =
+ let cut, rest = partition_bitstring 64 bs in
+ match endian with
+ | Little -> read_elf64_sxword_le cut rest
+ | Big -> read_elf64_sxword_be cut rest
+;;
+
+(** Misc. string operations. *)
+
+let split_string_on_char strings c =
+ let enum = BatString.enum strings in
+ let groups = BatEnum.group (fun char -> char <> c) enum in
+ let enums = BatEnum.map BatString.of_enum groups in
+ BatList.of_enum enums
+;;
+
+let string_suffix index str =
+ if index < 0 || index > String.length str then
+ None
+ else
+ try
+ Some (String.sub str index (String.length str - index))
+ with
+ | _ -> None
+;; \ No newline at end of file
diff --git a/src/elf_model/sail_interface.lem b/src/elf_model/sail_interface.lem
index 7bfad805..6c474fa7 100644
--- a/src/elf_model/sail_interface.lem
+++ b/src/elf_model/sail_interface.lem
@@ -12,10 +12,14 @@ open import Missing_pervasives
open import Show
open import Elf_header
-open import Elf_executable_file5
+open import Elf_executable_file3
open import Elf_types
-val populate : string -> list (bitstring * nat) * nat
+type elf_class
+ = ELF_Class_32
+ | ELF_Class_64
+
+val populate : string -> executable_process_image * elf_class
let populate fname =
let res =
(* Acquire the data from the file... *)
@@ -29,11 +33,13 @@ let populate fname =
* what we have read...
*)
if nat_of_unsigned_char c = Elf_header.elf_class_32 then
- Elf_executable_file5.read_elf32_executable_file5 bs0 >>=
- Elf_executable_file5.elf32_construct_image
+ Elf_executable_file3.read_elf32_executable_file3 bs0 >>= fun ef5 ->
+ Elf_executable_file3.get_elf32_executable_image ef5 >>= fun (chunks, entry) ->
+ return ((chunks, entry), ELF_Class_32)
else if nat_of_unsigned_char c = Elf_header.elf_class_64 then
- Elf_executable_file5.read_elf64_executable_file5 bs0 >>=
- Elf_executable_file5.elf64_construct_image
+ Elf_executable_file3.read_elf64_executable_file3 bs0 >>= fun ef5 ->
+ Elf_executable_file3.get_elf64_executable_image ef5 >>= fun (chunks, entry) ->
+ return ((chunks, entry), ELF_Class_64)
else
fail "populate: ELF class unrecognised"
end
@@ -41,4 +47,74 @@ let populate fname =
match res with
| Fail err -> failwith err
| Success chunks -> chunks
+ end
+
+val obtain_symbol_to_address_mapping : string -> list (string * nat)
+let obtain_symbol_to_address_mapping fname =
+ let res =
+ (* Acquire the data from the file... *)
+ Bitstring.acquire fname >>= fun bs0 ->
+ (* Read the magic number and the flags in the header... *)
+ repeatM' Elf_header.ei_nident bs0 (read_unsigned_char Endianness.default_endianness) >>= fun (ident, bs) ->
+ match List.index ident 4 with
+ | Nothing -> fail "populate: ELF ident transcription error"
+ | Just c ->
+ (* Calculate whether we are dealing with a 32- or 64-bit file based on
+ * what we have read...
+ *)
+ if nat_of_unsigned_char c = Elf_header.elf_class_32 then
+ Elf_executable_file3.read_elf32_executable_file3 bs0 >>= fun f1 ->
+ Elf_executable_file3.get_elf32_symbol_table f1 >>= fun symtab ->
+ Elf_executable_file3.get_elf32_symbol_string_table f1 >>= fun strtab ->
+ Elf_symbol_table.get_elf32_symbol_image_address symtab strtab >>= fun strs ->
+ return strs
+ else if nat_of_unsigned_char c = Elf_header.elf_class_64 then
+ Elf_executable_file3.read_elf64_executable_file3 bs0 >>= fun f1 ->
+ Elf_executable_file3.get_elf64_symbol_table f1 >>= fun symtab ->
+ Elf_executable_file3.get_elf64_symbol_string_table f1 >>= fun strtab ->
+ Elf_symbol_table.get_elf64_symbol_image_address symtab strtab >>= fun strs ->
+ return strs
+ else
+ fail "obtain_symbol_to_address_mapping: ELF class unrecognised"
+ end
+ in
+ match res with
+ | Fail err -> failwith err
+ | Success strs -> strs
+ end
+
+val populate_and_obtain_symbol_to_address_mapping : string -> ((executable_process_image * elf_class) * list (string * nat))
+let populate_and_obtain_symbol_to_address_mapping fname =
+ let res =
+ (* Acquire the data from the file... *)
+ Bitstring.acquire fname >>= fun bs0 ->
+ (* Read the magic number and the flags in the header... *)
+ repeatM' Elf_header.ei_nident bs0 (read_unsigned_char Endianness.default_endianness) >>= fun (ident, bs) ->
+ match List.index ident 4 with
+ | Nothing -> fail "populate: ELF ident transcription error"
+ | Just c ->
+ (* Calculate whether we are dealing with a 32- or 64-bit file based on
+ * what we have read...
+ *)
+ if nat_of_unsigned_char c = Elf_header.elf_class_32 then
+ Elf_executable_file3.read_elf32_executable_file3 bs0 >>= fun f1 ->
+ Elf_executable_file3.get_elf32_symbol_table f1 >>= fun symtab ->
+ Elf_executable_file3.get_elf32_symbol_string_table f1 >>= fun strtab ->
+ Elf_symbol_table.get_elf32_symbol_image_address symtab strtab >>= fun strs ->
+ Elf_executable_file3.get_elf32_executable_image f1 >>= fun (chunks, entry) ->
+ return (((chunks, entry), ELF_Class_32), strs)
+ else if nat_of_unsigned_char c = Elf_header.elf_class_64 then
+ Elf_executable_file3.read_elf64_executable_file3 bs0 >>= fun f1 ->
+ Elf_executable_file3.get_elf64_symbol_table f1 >>= fun symtab ->
+ Elf_executable_file3.get_elf64_symbol_string_table f1 >>= fun strtab ->
+ Elf_symbol_table.get_elf64_symbol_image_address symtab strtab >>= fun strs ->
+ Elf_executable_file3.get_elf64_executable_image f1 >>= fun (chunks, entry) ->
+ return (((chunks, entry), ELF_Class_64), strs)
+ else
+ fail "populate_and_obtain_symbol_to_address_mapping: ELF class unrecognised"
+ end
+ in
+ match res with
+ | Fail err -> failwith err
+ | Success res -> res
end \ No newline at end of file
diff --git a/src/elf_model/show.lem b/src/elf_model/show.lem
index b9d45f08..95a3b648 100644
--- a/src/elf_model/show.lem
+++ b/src/elf_model/show.lem
@@ -4,6 +4,7 @@
open import Function
open import List
+open import Maybe
open import Num
open import String
@@ -44,7 +45,7 @@ end
*)
val string_of_list : forall 'a. Show 'a => list 'a -> string
let string_of_list l =
- let result = intercalate "," (map show l) in
+ let result = intercalate "," (List.map show l) in
let folded = foldr (^) "" result in
"[" ^ folded ^ "]"
@@ -52,6 +53,17 @@ instance forall 'a. Show 'a => (Show (list 'a))
let show = string_of_list
end
+val string_of_maybe : forall 'a. Show 'a => maybe 'a -> string
+let string_of_maybe m =
+ match m with
+ | Nothing -> "Nothing"
+ | Just e -> "Just " ^ show e
+ end
+
+instance forall 'a. Show 'a => (Show (maybe 'a))
+ let show = string_of_maybe
+end
+
instance (Show nat)
let show = string_of_nat
end
diff --git a/src/elf_model/string_table.lem b/src/elf_model/string_table.lem
index 8cfe5056..105c5f43 100644
--- a/src/elf_model/string_table.lem
+++ b/src/elf_model/string_table.lem
@@ -1,3 +1,4 @@
+open import Basic_classes
open import List
open import Maybe
open import Num
@@ -40,6 +41,22 @@ let get_base_string tbl =
| Strings (sep, base) -> base
end
+(** [concat xs] concatenates several string tables into one providing they all
+ * have the same delimiting character.
+ *)
+val concat : list string_table -> error string_table
+let concat xs =
+ match xs with
+ | [] -> return empty
+ | x::xs ->
+ let delim = get_delimiting_character x in
+ if (List.all (fun x -> get_delimiting_character x = delim) (x::xs)) then
+ let base = List.foldr (^) "" (List.map get_base_string (x::xs)) in
+ return (mk_string_table base delim)
+ else
+ fail "concat: string tables must have same delimiting characters"
+ end
+
(** [get_strings tbl] obtains the strings stored in the table, separated using
* the designated separator as a delimiting character.
*)
diff --git a/src/test/run_power.ml b/src/test/run_power.ml
index 83f6549c..96f64efe 100644
--- a/src/test/run_power.ml
+++ b/src/test/run_power.ml
@@ -277,7 +277,7 @@ let run () =
end;
if !eager_eval then Run_interp_model.debug := true;
if !test_format then Run_interp_model.debug := false;
- let (locations,start_address) = populate !file in
+ let ((locations,start_address),_) = populate !file in
let total_size = (List.length locations) in
if not(!test_format)
then eprintf "Loading binary into memory (%d sections)... %!" total_size;