diff options
| author | Alasdair Armstrong | 2018-01-18 18:16:45 +0000 |
|---|---|---|
| committer | Alasdair Armstrong | 2018-01-18 18:31:26 +0000 |
| commit | 0fa42d315e20f819af93c2a822ab1bc032dc4535 (patch) | |
| tree | 7ef4ea3444ba5938457e7c852f9ad9957055fe41 /lib/ocaml_rts | |
| parent | 24dc13511053ab79ccb66ae24e3b8ffb9cad0690 (diff) | |
Modified ocaml backend to use ocamlfind for linksem and lem
Fixed test cases for ocaml backend and interpreter
Diffstat (limited to 'lib/ocaml_rts')
131 files changed, 0 insertions, 39277 deletions
diff --git a/lib/ocaml_rts/Makefile b/lib/ocaml_rts/Makefile deleted file mode 100644 index 52b8841b..00000000 --- a/lib/ocaml_rts/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -########################################################################## -# Sail # -# # -# Copyright (c) 2013-2017 # -# Kathyrn Gray # -# Shaked Flur # -# Stephen Kell # -# Gabriel Kerneis # -# Robert Norton-Wright # -# Christopher Pulte # -# Peter Sewell # -# Alasdair Armstrong # -# # -# All rights reserved. # -# # -# This software was developed by the University of Cambridge Computer # -# Laboratory as part of the Rigorous Engineering of Mainstream Systems # -# (REMS) project, funded by EPSRC grant EP/K008528/1. # -# # -# Redistribution and use in source and binary forms, with or without # -# modification, are permitted provided that the following conditions # -# are met: # -# 1. Redistributions of source code must retain the above copyright # -# notice, this list of conditions and the following disclaimer. # -# 2. Redistributions in binary form must reproduce the above copyright # -# notice, this list of conditions and the following disclaimer in # -# the documentation and/or other materials provided with the # -# distribution. # -# # -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' # -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # -# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A # -# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR # -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # -# SUCH DAMAGE. # -########################################################################## - -.PHONY: all main import clean - -THIS_MAKEFILE=$(realpath $(lastword $(MAKEFILE_LIST))) -BITBUCKET_ROOT=$(realpath $(dir $(THIS_MAKEFILE))../../..) - -all: main - -import: - rsync -rv --include "*/" --include="*.ml" --include="*.mli" --exclude="*" $(BITBUCKET_ROOT)/linksem/src/ linksem - -main: import - ocamlbuild -pkg uint -pkg zarith main.native -use-ocamlfind - -clean: - rm -r linksem - rm -r lem - ocamlbuild -clean diff --git a/lib/ocaml_rts/_tags b/lib/ocaml_rts/_tags deleted file mode 100644 index db11bf77..00000000 --- a/lib/ocaml_rts/_tags +++ /dev/null @@ -1,5 +0,0 @@ -true: use_lem, debug -<main.{byte,native}>: use_nums, use_str, use_unix, debug -<linksem>: include -<linksem/adaptors>: include -<linksem/src_lem_library>: -traverse diff --git a/lib/ocaml_rts/elf_loader.ml b/lib/ocaml_rts/elf_loader.ml deleted file mode 100644 index b5ecce24..00000000 --- a/lib/ocaml_rts/elf_loader.ml +++ /dev/null @@ -1,135 +0,0 @@ -(**************************************************************************) -(* Sail *) -(* *) -(* Copyright (c) 2013-2017 *) -(* Kathyrn Gray *) -(* Shaked Flur *) -(* Stephen Kell *) -(* Gabriel Kerneis *) -(* Robert Norton-Wright *) -(* Christopher Pulte *) -(* Peter Sewell *) -(* Alasdair Armstrong *) -(* *) -(* All rights reserved. *) -(* *) -(* This software was developed by the University of Cambridge Computer *) -(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *) -(* (REMS) project, funded by EPSRC grant EP/K008528/1. *) -(* *) -(* Redistribution and use in source and binary forms, with or without *) -(* modification, are permitted provided that the following conditions *) -(* are met: *) -(* 1. Redistributions of source code must retain the above copyright *) -(* notice, this list of conditions and the following disclaimer. *) -(* 2. Redistributions in binary form must reproduce the above copyright *) -(* notice, this list of conditions and the following disclaimer in *) -(* the documentation and/or other materials provided with the *) -(* distribution. *) -(* *) -(* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' *) -(* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *) -(* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *) -(* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR *) -(* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *) -(* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *) -(* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *) -(* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *) -(* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *) -(* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT *) -(* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *) -(* SUCH DAMAGE. *) -(**************************************************************************) - -open Big_int - -let opt_file_arguments = ref ([] : string list) -let opt_elf_threads = ref 1 -let opt_elf_entry = ref zero_big_int - -let options = Arg.align [] - -let usage_msg = "Sail OCaml RTS options:" - -let () = - Arg.parse options (fun s -> opt_file_arguments := !opt_file_arguments @ [s]) usage_msg - -type word8 = int - -let escape_char c = - if int_of_char c <= 31 then '.' - else if int_of_char c >= 127 then '.' - else c - -let hex_line bs = - let hex_char i c = - (if i mod 2 == 0 && i <> 0 then " " else "") ^ Printf.sprintf "%02x" (int_of_char c) - in - String.concat "" (List.mapi hex_char bs) ^ " " ^ String.concat "" (List.map (fun c -> Printf.sprintf "%c" (escape_char c)) bs) - -let rec break n = function - | [] -> [] - | (_ :: _ as xs) -> [Lem_list.take n xs] @ break n (Lem_list.drop n xs) - -let print_segment seg = - let (Byte_sequence.Sequence bs) = seg.Elf_interpreted_segment.elf64_segment_body in - prerr_endline "0011 2233 4455 6677 8899 aabb ccdd eeff 0123456789abcdef"; - List.iter (fun bs -> prerr_endline (hex_line bs)) (break 16 bs) - -let read name = - let info = Sail_interface.populate_and_obtain_global_symbol_init_info name in - - prerr_endline "Elf read:"; - let (elf_file, elf_epi, symbol_map) = - begin match info with - | Error.Fail s -> failwith (Printf.sprintf "populate_and_obtain_global_symbol_init_info: %s" s) - | Error.Success ((elf_file: Elf_file.elf_file), - (elf_epi: Sail_interface.executable_process_image), - (symbol_map: Elf_file.global_symbol_init_info)) - -> - prerr_endline (Sail_interface.string_of_executable_process_image elf_epi); - (elf_file, elf_epi, symbol_map) - end - in - - prerr_endline "\nElf segments:"; - let (segments, e_entry, e_machine) = - begin match elf_epi, elf_file with - | (Sail_interface.ELF_Class_32 _, _) -> failwith "cannot handle ELF_Class_32" - | (_, Elf_file.ELF_File_32 _) -> failwith "cannot handle ELF_File_32" - | (Sail_interface.ELF_Class_64 (segments, e_entry, e_machine), Elf_file.ELF_File_64 f1) -> - (* remove all the auto generated segments (they contain only 0s) *) - let segments = - Lem_list.mapMaybe - (fun (seg, prov) -> if prov = Elf_file.FromELF then Some seg else None) - segments - in - (segments, big_int_of_string (Nat_big_num.to_string e_entry),e_machine) - end - in - (segments, e_entry) - -let load_segment seg = - let open Elf_interpreted_segment in - let (Byte_sequence.Sequence bs) = seg.elf64_segment_body in - let paddr = big_int_of_string (Nat_big_num.to_string (seg.elf64_segment_paddr)) in - let base = big_int_of_string (Nat_big_num.to_string (seg.elf64_segment_base)) in - let offset = big_int_of_string (Nat_big_num.to_string (seg.elf64_segment_offset)) in - prerr_endline "\nLoading Segment"; - prerr_endline ("Segment offset: " ^ string_of_big_int offset); - prerr_endline ("Segment base address: " ^ string_of_big_int base); - prerr_endline ("Segment physical address: " ^ string_of_big_int paddr); - print_segment seg; - List.iteri (fun i byte -> Sail_lib.wram (add_big_int paddr (big_int_of_int i)) byte) (List.map int_of_char bs) - -let load_elf () = - match !opt_file_arguments with - | (name :: _) -> - let segments, e_entry = read name in - opt_elf_entry := e_entry; - List.iter load_segment segments - | [] -> () - -(* The sail model can access this by externing a unit -> int function - as Elf_loader.elf_entry. *) -let elf_entry () = !opt_elf_entry diff --git a/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_le.ml b/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_le.ml deleted file mode 100644 index 9b73765a..00000000 --- a/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_le.ml +++ /dev/null @@ -1,82 +0,0 @@ -(*Generated by Lem from abis/aarch64/abi_aarch64_le.lem.*) -(** [abi_aarch64_le] contains top-level definition for the AArch64 ABI (little-endian case). - *) - -open Lem_basic_classes -open Lem_bool -open Lem_list -open Lem_num -open Lem_maybe -open Lem_assert_extra -open Error -open Missing_pervasives - -open Elf_header -open Elf_types_native_uint -open Elf_file -open Elf_interpreted_segment -open Elf_interpreted_section - -open Endianness -(* open import Elf_memory_image *) -open Abi_classes -open Memory_image -open Abi_aarch64_relocation -open Abi_aarch64_le_elf_header - -(** [abi_aarch64_le_compute_program_entry_point segs entry] computes the program - * entry point using ABI-specific conventions. On AArch64 the entry point in - * the ELF header ([entry] here) is the real entry point. On other ABIs, e.g. - * PowerPC64, the entry point [entry] is a pointer into one of the segments - * constituting the process image (passed in as [segs] here for a uniform - * interface). - *) -(*val abi_aarch64_le_compute_program_entry_point : list elf64_interpreted_segments -> elf64_addr -> error natural*) -let abi_aarch64_le_compute_program_entry_point segs entry:(Nat_big_num.num)error= - (return (Ml_bindings.nat_big_num_of_uint64 entry)) - -(*val header_is_aarch64_le : elf64_header -> bool*) -let header_is_aarch64_le h:bool= - (is_valid_elf64_header h - && ((Lem.option_equal (=) (Lem_list.list_index h.elf64_ident (Nat_big_num.to_int elf_ii_data)) (Some (Uint32.of_string (Nat_big_num.to_string elf_data_2lsb)))) - && (is_valid_abi_aarch64_le_machine_architecture (Nat_big_num.of_string (Uint32.to_string h.elf64_machine)) - && is_valid_abi_aarch64_le_magic_number h.elf64_ident))) - -type aarch64_le_abi_feature = GOT | PLT (* placeholder / FIXME *) - -(*val abiFeatureCompare : aarch64_le_abi_feature -> aarch64_le_abi_feature -> Basic_classes.ordering*) -let abiFeatureCompare f1 f2:int= - ((match (f1, f2) with - (GOT, GOT) -> 0 - | (GOT, PLT) -> (-1) - | (PLT, PLT) -> 0 - | (PLT, GOT) -> 1 - )) - -(*val abiFeatureTagEq : aarch64_le_abi_feature -> aarch64_le_abi_feature -> bool*) -let abiFeatureTagEq f1 f2:bool= - ((match (f1, f2) with - (GOT, GOT) -> true - | (PLT, PLT) -> true - | (_, _) -> false - )) - -let instance_Basic_classes_Ord_Abi_aarch64_le_aarch64_le_abi_feature_dict:(aarch64_le_abi_feature)ord_class= ({ - - compare_method = abiFeatureCompare; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(abiFeatureCompare f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (abiFeatureCompare f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(abiFeatureCompare f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (abiFeatureCompare f1 f2)(Pset.from_list compare [1; 0])))}) - -let instance_Abi_classes_AbiFeatureTagEquiv_Abi_aarch64_le_aarch64_le_abi_feature_dict:(aarch64_le_abi_feature)abiFeatureTagEquiv_class= ({ - - abiFeatureTagEquiv_method = abiFeatureTagEq}) - -(*val section_is_special : forall 'abifeature. elf64_interpreted_section -> annotated_memory_image 'abifeature -> bool*) -let section_is_special0 s f:bool= - (elf_section_is_special s f || (* FIXME *) false) diff --git a/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_le_elf_header.ml b/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_le_elf_header.ml deleted file mode 100644 index 72510d38..00000000 --- a/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_le_elf_header.ml +++ /dev/null @@ -1,60 +0,0 @@ -(*Generated by Lem from abis/aarch64/abi_aarch64_le_elf_header.lem.*) -(** [abi_aarch64_le_elf_header] contains types and definitions relating to ABI - * specific ELF header functionality for the AArch64 ABI (little-endian). - *) - -open Lem_basic_classes -open Lem_bool -open Lem_list -open Lem_num -open Lem_maybe -open Missing_pervasives - -open Elf_header -open Elf_types_native_uint - -open Endianness - -(*val abi_aarch64_le_data_encoding : natural*) -let abi_aarch64_le_data_encoding:Nat_big_num.num= elf_data_2lsb - -(*val abi_aarch64_le_endianness : endianness*) -let abi_aarch64_le_endianness:endianness= Little (* Must match above *) - -(*val abi_aarch64_le_file_class : natural*) -let abi_aarch64_le_file_class:Nat_big_num.num= elf_class_64 - -(*val abi_aarch64_le_file_version : natural*) -let abi_aarch64_le_file_version:Nat_big_num.num= elf_ev_current - -(*val abi_aarch64_le_page_size_min : natural*) -let abi_aarch64_le_page_size_min:Nat_big_num.num= (Nat_big_num.of_int 4096) - -(*val abi_aarch64_le_page_size_max : natural*) -let abi_aarch64_le_page_size_max:Nat_big_num.num= (Nat_big_num.of_int 65536) - -(** [is_valid_abi_aarch64_le_machine_architecture m] checks whether the ELF header's - * machine architecture is valid according to the ABI-specific specification. - * Machine architecture must be AArch64 (pg 60) - *) -(*val is_valid_abi_aarch64_le_machine_architecture : natural -> bool*) -let is_valid_abi_aarch64_le_machine_architecture m:bool= (Nat_big_num.equal - m elf_ma_aarch64) - -(** [is_valid_abi_aarch64_le_magic_number magic] checks whether the ELF header's - * magic number is valid according to the ABI-specific specification. - * File class must be 64-bit (pg 60) - * Data encoding must be little endian (pg 60) - *) -(*val is_valid_abi_aarch64_le_magic_number : list unsigned_char -> bool*) -let is_valid_abi_aarch64_le_magic_number magic:bool= - ((match Lem_list.list_index magic (Nat_big_num.to_int elf_ii_class) with - | None -> false - | Some cls -> - (match Lem_list.list_index magic (Nat_big_num.to_int elf_ii_data) with - | None -> false - | Some data -> - ( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string cls)) abi_aarch64_le_file_class) && - ( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string data)) abi_aarch64_le_data_encoding) - ) - )) diff --git a/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_le_serialisation.ml b/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_le_serialisation.ml deleted file mode 100644 index 6a83784e..00000000 --- a/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_le_serialisation.ml +++ /dev/null @@ -1,293 +0,0 @@ -(*Generated by Lem from abis/aarch64/abi_aarch64_le_serialisation.lem.*) -(** [abi_aarch64_le_serialisation], code for producing an AARCH64 conformant - * ELF binary file from executable (machine code) data. - * Used in ongoing experiments with CakeML. - * - * XXX: experimental, and outdated. Commented out for now until attention turns - * to CakeML again. - *) - -open Lem_basic_classes -open Lem_list -open Lem_maybe -open Lem_num - -open Byte_sequence -open Missing_pervasives - -open Memory_image -open Elf_file -open Elf_header -open Elf_interpreted_segment -open Elf_program_header_table -open Elf_section_header_table -open Elf_types_native_uint - -open Abi_aarch64_le_elf_header - -(* -(** [abi_aarch64_le_elf_ident abi_version] produces the ELF identification field for - * the ELF header based on ABI-specific information and the [abi_version] - * argument passed in. - *) -val abi_aarch64_le_elf_ident : natural -> list unsigned_char -let abi_aarch64_le_elf_ident abi_version = - List.map unsigned_char_of_natural - [127; 69; 76; 70; (* 127 E L F *) - abi_aarch64_le_file_class; abi_aarch64_le_data_encoding; abi_aarch64_le_file_version; - elf_osabi_none; abi_version; 0; - 0; 0; 0; - 0; 0; 0] - -(** [abi_aarch64_le_generate_elf_header entry phoff phnum] produces an ELF header for - * 64-bit AArh64 little-endian ELF files. The function expects the [entry] address to start - * execution from, the offset of the program header table in [phoff] and the - * number of entries in the program header table in [phnum]. - *) -val abi_aarch64_le_generate_elf_header : elf64_addr -> elf64_off -> elf64_half -> elf64_header -let abi_aarch64_le_generate_elf_header entry phoff phnum = - <| elf64_ident = abi_aarch64_le_elf_ident 0; - elf64_type = elf64_half_of_natural elf_ft_exec; - elf64_machine = elf64_half_of_natural elf_ma_aarch64; - elf64_version = elf64_word_of_natural elf_ev_current; - elf64_entry = entry; - elf64_phoff = phoff; - elf64_shoff = elf64_off_of_natural 0; - elf64_flags = elf64_word_of_natural 0; - elf64_ehsize = elf64_half_of_natural 64; - elf64_phentsize = elf64_half_of_natural 56; - elf64_phnum = phnum; - elf64_shentsize = elf64_half_of_natural 0; - elf64_shnum = elf64_half_of_natural 0; - elf64_shstrndx = elf64_half_of_natural shn_undef - |> - -(** [elf64_pack_segment_flags bs] packages three boolean segment permission flags - * into a word value. - * TODO: move into elf_program_header_table? - *) -val elf64_pack_segment_flags : (bool * bool * bool) -> elf64_word -let elf64_pack_segment_flags (r, w, x) = - let xflag = 1 * natural_of_bool x in - let wflag = 2 * natural_of_bool w in - let rflag = 4 * natural_of_bool r in - elf64_word_of_natural (xflag + wflag + rflag) - -(** [elf64_header_size], size in bytes of an ELF64 header. - * TODO: move into elf_header? - *) -val elf64_header_size : natural -let elf64_header_size = 64 - -(** [elf64_program_header_table_entry_size], size in bytes of an ELF64 program - * header table entry. - * TODO: more into elf_program_header_table? - *) -val elf64_program_header_table_entry_size : natural -let elf64_program_header_table_entry_size = 56 - -val exec_entry_offset : natural -let exec_entry_offset = - elf64_header_size + (elf64_program_header_table_entry_size * 3) - -val code_heap_entry_offset : natural -> natural -let code_heap_entry_offset exec_size = - elf64_header_size + (elf64_program_header_table_entry_size * 3) + exec_size - -val data_heap_entry_offset : natural -> natural -> natural -let data_heap_entry_offset exec_size code_heap_size = - elf64_header_size + (elf64_program_header_table_entry_size * 3) + exec_size + code_heap_size - -val abi_aarch64_le_generate_program_header_table : elf64_interpreted_segment -> elf64_interpreted_segment -> elf64_interpreted_segment -> elf64_program_header_table -let abi_aarch64_le_generate_program_header_table exec code_heap data_heap = - (* exec segment and then base *) - let exec_header = - <| elf64_p_type = elf64_word_of_natural exec.elf64_segment_type; - elf64_p_flags = elf64_pack_segment_flags exec.elf64_segment_flags; - elf64_p_offset = elf64_off_of_natural exec.elf64_segment_offset; - elf64_p_vaddr = elf64_addr_of_natural exec.elf64_segment_base; - elf64_p_paddr = elf64_addr_of_natural exec.elf64_segment_paddr; - elf64_p_filesz = elf64_xword_of_natural exec.elf64_segment_size; - elf64_p_memsz = elf64_xword_of_natural exec.elf64_segment_memsz; - elf64_p_align = elf64_xword_of_natural exec.elf64_segment_align |> - in - let code_heap_header = - <| elf64_p_type = elf64_word_of_natural code_heap.elf64_segment_type; - elf64_p_flags = elf64_pack_segment_flags code_heap.elf64_segment_flags; - elf64_p_offset = elf64_off_of_natural code_heap.elf64_segment_offset; - elf64_p_vaddr = elf64_addr_of_natural code_heap.elf64_segment_base; - elf64_p_paddr = elf64_addr_of_natural code_heap.elf64_segment_paddr; - elf64_p_filesz = elf64_xword_of_natural code_heap.elf64_segment_size; - elf64_p_memsz = elf64_xword_of_natural code_heap.elf64_segment_memsz; - elf64_p_align = elf64_xword_of_natural code_heap.elf64_segment_align |> - in - let data_heap_header = - <| elf64_p_type = elf64_word_of_natural data_heap.elf64_segment_type; - elf64_p_flags = elf64_pack_segment_flags data_heap.elf64_segment_flags; - elf64_p_offset = elf64_off_of_natural data_heap.elf64_segment_offset; - elf64_p_vaddr = elf64_addr_of_natural data_heap.elf64_segment_base; - elf64_p_paddr = elf64_addr_of_natural data_heap.elf64_segment_paddr; - elf64_p_filesz = elf64_xword_of_natural data_heap.elf64_segment_size; - elf64_p_memsz = elf64_xword_of_natural data_heap.elf64_segment_memsz; - elf64_p_align = elf64_xword_of_natural data_heap.elf64_segment_align |> - in - [exec_header; code_heap_header; data_heap_header] - -val abi_aarch64_le_generate_exec_interpreted_segment : natural -> natural -> byte_sequence -> elf64_interpreted_segment -let abi_aarch64_le_generate_exec_interpreted_segment vma offset exec_code = - let segment_size = Byte_sequence.length exec_code in - <| elf64_segment_body = exec_code; - elf64_segment_size = segment_size; - elf64_segment_memsz = segment_size; - elf64_segment_base = vma; - elf64_segment_paddr = 0; - elf64_segment_align = abi_aarch64_le_page_size_max; - elf64_segment_flags = (true, false, true); - elf64_segment_type = elf_pt_load; - elf64_segment_offset = offset - |> - -val abi_aarch64_le_generate_code_heap_interpreted_segment : natural -> natural -> natural -> elf64_interpreted_segment -let abi_aarch64_le_generate_code_heap_interpreted_segment vma offset segment_size = - let seg = Byte_sequence.create segment_size Missing_pervasives.null_byte in - <| elf64_segment_body = seg; - elf64_segment_size = segment_size; - elf64_segment_memsz = segment_size; - elf64_segment_base = vma; - elf64_segment_paddr = 0; - elf64_segment_align = abi_aarch64_le_page_size_max; - elf64_segment_flags = (true, true, true); - elf64_segment_type = elf_pt_load; - elf64_segment_offset = offset - |> - -val abi_aarch64_le_entry_point_addr : natural -let abi_aarch64_le_entry_point_addr = 4194304 (* 0x400000 *) - -val abi_aarch64_le_code_heap_addr : natural -let abi_aarch64_le_code_heap_addr = 67108864 (* 16 * 4194304 *) - -val abi_aarch64_le_data_heap_addr : natural -let abi_aarch64_le_data_heap_addr = 67108864 * 16 - -val quad_le_bytes_of_natural : natural -> byte * byte * byte * byte -let quad_le_bytes_of_natural m = - let conv = elf64_addr_of_natural m in - let b0 = byte_of_natural (natural_of_elf64_addr (elf64_addr_land conv (elf64_addr_of_natural 255))) in - let b1 = byte_of_natural (natural_of_elf64_addr (elf64_addr_land (elf64_addr_rshift conv 8) (elf64_addr_of_natural 255))) in - let b2 = byte_of_natural (natural_of_elf64_addr (elf64_addr_land (elf64_addr_rshift conv 16) (elf64_addr_of_natural 255))) in - let b3 = byte_of_natural (natural_of_elf64_addr (elf64_addr_land (elf64_addr_rshift conv 24) (elf64_addr_of_natural 255))) in - (b0, b1, b2, b3) - -val abi_aarch64_le_generate_data_heap_interpreted_segment : natural -> natural -> natural -> natural -> elf64_interpreted_segment -let abi_aarch64_le_generate_data_heap_interpreted_segment vma off segment_size code_heap_size = - let (d0, d1, d2, d3) = quad_le_bytes_of_natural segment_size in - let (c0, c1, c2, c3) = quad_le_bytes_of_natural abi_aarch64_le_code_heap_addr in - let (sz0, sz1, sz2, sz3) = quad_le_bytes_of_natural code_heap_size in - let (pc0, pc1, pc2, pc3) = quad_le_bytes_of_natural 0 in - let (gc0, gc1, gc2, gc3) = quad_le_bytes_of_natural 0 in - let preamble = Byte_sequence.from_byte_lists [[ - d0; d1; d2; d3; null_byte; null_byte; null_byte; null_byte; - c0; c1; c2; c3; null_byte; null_byte; null_byte; null_byte; - sz0; sz1; sz2; sz3; null_byte; null_byte; null_byte; null_byte; - pc0; pc1; pc2; pc3; null_byte; null_byte; null_byte; null_byte; - gc0; gc1; gc2; gc3; null_byte; null_byte; null_byte; null_byte - ]] in - <| elf64_segment_body = preamble; - elf64_segment_size = Byte_sequence.length preamble; - elf64_segment_memsz = max segment_size (Byte_sequence.length preamble); - elf64_segment_base = vma; - elf64_segment_paddr = 0; - elf64_segment_align = abi_aarch64_le_page_size_max; - elf64_segment_flags = (true, true, false); - elf64_segment_type = elf_pt_load; - elf64_segment_offset = off - |> - -val init_data_heap_instrs : byte_sequence -let init_data_heap_instrs = - let (b0, b1, b2, b3) = quad_le_bytes_of_natural abi_aarch64_le_data_heap_addr in - Byte_sequence.from_byte_lists - [[ byte_of_natural 72 - ; byte_of_natural 199 - ; byte_of_natural 68 - ; byte_of_natural 36 - ; byte_of_natural 248 - ; b0 - ; b1 - ; b2 - ; b3 - ; byte_of_natural 72 - ; byte_of_natural 139 - ; byte_of_natural 68 - ; byte_of_natural 36 - ; byte_of_natural 248 - ]] - -val exit_syscall_instrs : byte_sequence -let exit_syscall_instrs = - Byte_sequence.from_byte_lists - [[ - byte_of_natural 72; - byte_of_natural 199; - byte_of_natural 192; - byte_of_natural 60; - byte_of_natural 0; - byte_of_natural 0; - byte_of_natural 0; - byte_of_natural 15; - byte_of_natural 5 - ]] - -val push_instr : natural -> byte_sequence -let push_instr addr = - let (b0, b1, b2, b3) = quad_le_bytes_of_natural addr in - Byte_sequence.from_byte_lists [[ - byte_of_natural 104; - b0; b1; b2; b3 - ]] - -val setup_return_code_instr : byte_sequence -let setup_return_code_instr = - Byte_sequence.from_byte_lists [[ - byte_of_natural 191; - byte_of_natural 0; - byte_of_natural 0; - byte_of_natural 0; - byte_of_natural 0 - ]] - -val abi_aarch64_le_generate_executable_file : byte_sequence -> natural -> natural -> elf64_file -let abi_aarch64_le_generate_executable_file exec_code code_heap_size data_heap_size = - let exec_code' = Byte_sequence.concat [ - init_data_heap_instrs; - exec_code - ] in - let pre_entry = 5 + abi_aarch64_le_entry_point_addr + Byte_sequence.length exec_code' in - let exec_code = Byte_sequence.concat [push_instr pre_entry; exec_code'; setup_return_code_instr; exit_syscall_instrs] in - let hdr = abi_aarch64_le_generate_elf_header - (elf64_addr_of_natural abi_aarch64_le_entry_point_addr) - (elf64_off_of_natural 64) (elf64_half_of_natural 3) in - let exec_off_i = 64 + 3 * 56 in - let exec_off_adj = compute_virtual_address_adjustment abi_aarch64_le_page_size_max exec_off_i abi_aarch64_le_entry_point_addr in - let exec_off = exec_off_i + exec_off_adj in - let exec = abi_aarch64_le_generate_exec_interpreted_segment - abi_aarch64_le_entry_point_addr exec_off exec_code in - let code_off_i = exec_off + exec.elf64_segment_size in - let code_off_adj = compute_virtual_address_adjustment abi_aarch64_le_page_size_max code_off_i abi_aarch64_le_code_heap_addr in - let code_off = code_off_i + code_off_adj in - let code_heap = abi_aarch64_le_generate_code_heap_interpreted_segment - abi_aarch64_le_code_heap_addr code_off code_heap_size in - let data_off_i = code_off + code_heap.elf64_segment_size in - let data_off_adj = compute_virtual_address_adjustment abi_aarch64_le_page_size_max data_off_i abi_aarch64_le_data_heap_addr in - let data_off = data_off_i + data_off_adj in - let data_heap = abi_aarch64_le_generate_data_heap_interpreted_segment - abi_aarch64_le_data_heap_addr data_off data_heap_size code_heap_size in - let pht = abi_aarch64_le_generate_program_header_table - exec code_heap data_heap in - <| elf64_file_header = hdr; elf64_file_program_header_table = pht; - elf64_file_interpreted_segments = [exec; code_heap; data_heap]; - elf64_file_interpreted_sections = []; - elf64_file_section_header_table = []; - elf64_file_bits_and_bobs = [] |> -*) diff --git a/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_program_header_table.ml b/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_program_header_table.ml deleted file mode 100644 index 53b34757..00000000 --- a/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_program_header_table.ml +++ /dev/null @@ -1,26 +0,0 @@ -(*Generated by Lem from abis/aarch64/abi_aarch64_program_header_table.lem.*) -(** [abi_aarch64_program_header_table], AARCH64 ABI specific program header - * table related flags, data, etc. - *) - -open Lem_basic_classes -open Lem_num - -(** AARCH64 specific segment types. See Section 5.1 *) - -(** Reserved for architecture compatibility information. *) -let abi_aarch64_pt_archext : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 939524096)(Nat_big_num.of_int 2)) (* 0x70000000 *) -(** Reserved for unwind information. *) -let abi_aarch64_pt_unwind : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 939524096)(Nat_big_num.of_int 2))(Nat_big_num.of_int 1)) (* 0x70000001 *) - -(** [string_of_abi_aarch64_segment_type m] produces a string representation of - * an AARCH64 ABI segment type. - *) -(*val string_of_abi_aarch64_segment_type : natural -> string*) -let string_of_abi_aarch64_segment_type m:string= - (if Nat_big_num.equal m abi_aarch64_pt_archext then - "ARCHEXT" - else if Nat_big_num.equal m abi_aarch64_pt_unwind then - "UNWIND" - else - "Invalid AARCH64 segment type") diff --git a/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_relocation.ml b/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_relocation.ml deleted file mode 100644 index 742c233c..00000000 --- a/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_relocation.ml +++ /dev/null @@ -1,944 +0,0 @@ -(*Generated by Lem from abis/aarch64/abi_aarch64_relocation.lem.*) -(** [abi_aarch64_relocation] contains types and definitions relating to ABI - * specific relocation functionality for the AArch64 ABI (little-endian case). - *) - -open Lem_basic_classes -open Lem_num -open Lem_string -open Lem_maybe -open Missing_pervasives - -open Error - -open Elf_types_native_uint -open Elf_file -open Elf_header -open Elf_relocation -open Elf_symbol_table - -open Abi_utilities -open Memory_image - -(** Relocations *) - -let r_aarch64_none : Nat_big_num.num= (Nat_big_num.of_int 0) -let r_aarch64_withdrawn : Nat_big_num.num= (Nat_big_num.of_int 256) (** Treated as R_AARCH6_NONE *) - -let r_aarch64_abs64 : Nat_big_num.num= (Nat_big_num.of_int 257) -let r_aarch64_abs32 : Nat_big_num.num= (Nat_big_num.of_int 258) -let r_aarch64_abs16 : Nat_big_num.num= (Nat_big_num.of_int 259) -let r_aarch64_prel64 : Nat_big_num.num= (Nat_big_num.of_int 260) -let r_aarch64_prel32 : Nat_big_num.num= (Nat_big_num.of_int 261) -let r_aarch64_prel16 : Nat_big_num.num= (Nat_big_num.of_int 262) - -let r_aarch64_movw_uabs_g0 : Nat_big_num.num= (Nat_big_num.of_int 263) -let r_aarch64_movw_uabs_g0_nc : Nat_big_num.num= (Nat_big_num.of_int 264) -let r_aarch64_movw_uabs_g1 : Nat_big_num.num= (Nat_big_num.of_int 265) -let r_aarch64_movw_uabs_g1_nc : Nat_big_num.num= (Nat_big_num.of_int 266) -let r_aarch64_movw_uabs_g2 : Nat_big_num.num= (Nat_big_num.of_int 267) -let r_aarch64_movw_uabs_g2_nc : Nat_big_num.num= (Nat_big_num.of_int 268) -let r_aarch64_movw_uabs_g3 : Nat_big_num.num= (Nat_big_num.of_int 269) - -let r_aarch64_movw_sabs_g0 : Nat_big_num.num= (Nat_big_num.of_int 270) -let r_aarch64_movw_sabs_g1 : Nat_big_num.num= (Nat_big_num.of_int 271) -let r_aarch64_movw_sabs_g2 : Nat_big_num.num= (Nat_big_num.of_int 272) - -let r_aarch64_ld_prel_lo19 : Nat_big_num.num= (Nat_big_num.of_int 273) -let r_aarch64_adr_prel_lo21 : Nat_big_num.num= (Nat_big_num.of_int 274) -let r_aarch64_adr_prel_pg_hi21 : Nat_big_num.num= (Nat_big_num.of_int 275) -let r_aarch64_adr_prel_pg_hi21_nc : Nat_big_num.num= (Nat_big_num.of_int 276) -let r_aarch64_add_abs_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 277) -let r_aarch64_ldst8_abs_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 278) -let r_aarch64_ldst16_abs_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 284) -let r_aarch64_ldst32_abs_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 285) -let r_aarch64_ldst64_abs_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 286) -let r_aarch64_ldst128_abs_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 299) - -let r_aarch64_tstbr14 : Nat_big_num.num= (Nat_big_num.of_int 279) -let r_aarch64_condbr19 : Nat_big_num.num= (Nat_big_num.of_int 280) -let r_aarch64_jump26 : Nat_big_num.num= (Nat_big_num.of_int 282) -let r_aarch64_call26 : Nat_big_num.num= (Nat_big_num.of_int 283) - -let r_aarch64_movw_prel_g0 : Nat_big_num.num= (Nat_big_num.of_int 287) -let r_aarch64_movw_prel_g0_nc : Nat_big_num.num= (Nat_big_num.of_int 288) -let r_aarch64_movw_prel_g1 : Nat_big_num.num= (Nat_big_num.of_int 289) -let r_aarch64_movw_prel_g1_nc : Nat_big_num.num= (Nat_big_num.of_int 290) -let r_aarch64_movw_prel_g2 : Nat_big_num.num= (Nat_big_num.of_int 291) -let r_aarch64_movw_prel_g2_nc : Nat_big_num.num= (Nat_big_num.of_int 292) -let r_aarch64_movw_prel_g3 : Nat_big_num.num= (Nat_big_num.of_int 293) - -let r_aarch64_movw_gotoff_g0 : Nat_big_num.num= (Nat_big_num.of_int 300) -let r_aarch64_movw_gotoff_g0_nc : Nat_big_num.num= (Nat_big_num.of_int 301) -let r_aarch64_movw_gotoff_g1 : Nat_big_num.num= (Nat_big_num.of_int 302) -let r_aarch64_movw_gotoff_g1_nc : Nat_big_num.num= (Nat_big_num.of_int 303) -let r_aarch64_movw_gotoff_g2 : Nat_big_num.num= (Nat_big_num.of_int 304) -let r_aarch64_movw_gotoff_g2_nc : Nat_big_num.num= (Nat_big_num.of_int 305) -let r_aarch64_movw_gotoff_g3 : Nat_big_num.num= (Nat_big_num.of_int 306) - -let r_aarch64_gotrel64 : Nat_big_num.num= (Nat_big_num.of_int 307) -let r_aarch64_gotrel32 : Nat_big_num.num= (Nat_big_num.of_int 308) - -let r_aarch64_got_ld_prel19 : Nat_big_num.num= (Nat_big_num.of_int 309) -let r_aarch64_got_ld64_gotoff_lo15 : Nat_big_num.num= (Nat_big_num.of_int 310) -let r_aarch64_adr_got_page : Nat_big_num.num= (Nat_big_num.of_int 311) -let r_aarch64_ld64_got_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 312) -let r_aarch64_ld64_gotpage_lo15 : Nat_big_num.num= (Nat_big_num.of_int 313) - -let r_aarch64_tlsgd_adr_prel21 : Nat_big_num.num= (Nat_big_num.of_int 512) -let r_aarch64_tlsgd_adr_page21 : Nat_big_num.num= (Nat_big_num.of_int 513) -let r_aarch64_tlsgd_add_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 514) -let r_aarch64_tlsgd_movw_g1 : Nat_big_num.num= (Nat_big_num.of_int 515) -let r_aarch64_tlsgd_movw_g0_nc : Nat_big_num.num= (Nat_big_num.of_int 516) - -let r_aarch64_tlsld_adr_prel21 : Nat_big_num.num= (Nat_big_num.of_int 517) -let r_aarch64_tlsld_adr_page21 : Nat_big_num.num= (Nat_big_num.of_int 518) -let r_aarch64_tlsld_add_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 519) -let r_aarch64_tlsld_movw_g1 : Nat_big_num.num= (Nat_big_num.of_int 520) -let r_aarch64_tlsld_movw_g0_nc : Nat_big_num.num= (Nat_big_num.of_int 521) -let r_aarch64_tlsld_ld_prel19 : Nat_big_num.num= (Nat_big_num.of_int 522) -let r_aarch64_tlsld_movw_dtprel_g2 : Nat_big_num.num= (Nat_big_num.of_int 523) -let r_aarch64_tlsld_movw_dtprel_g1 : Nat_big_num.num= (Nat_big_num.of_int 524) -let r_aarch64_tlsld_movw_dtprel_g1_nc : Nat_big_num.num= (Nat_big_num.of_int 525) -let r_aarch64_tlsld_movw_dtprel_g0 : Nat_big_num.num= (Nat_big_num.of_int 526) -let r_aarch64_tlsld_movw_dtprel_g0_nc : Nat_big_num.num= (Nat_big_num.of_int 527) -let r_aarch64_tlsld_add_dtprel_hi12 : Nat_big_num.num= (Nat_big_num.of_int 528) -let r_aarch64_tlsld_add_dtprel_lo12 : Nat_big_num.num= (Nat_big_num.of_int 529) -let r_aarch64_tlsld_add_dtprel_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 530) -let r_aarch64_tlsld_ldst8_dtprel_lo12 : Nat_big_num.num= (Nat_big_num.of_int 531) -let r_aarch64_tlsld_ldst8_dtprel_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 532) -let r_aarch64_tlsld_ldst16_dtprel_lo12 : Nat_big_num.num= (Nat_big_num.of_int 533) -let r_aarch64_tlsld_ldst16_dtprel_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 534) -let r_aarch64_tlsld_ldst32_dtprel_lo12 : Nat_big_num.num= (Nat_big_num.of_int 535) -let r_aarch64_tlsld_ldst32_dtprel_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 536) -let r_aarch64_tlsld_ldst64_dtprel_lo12 : Nat_big_num.num= (Nat_big_num.of_int 537) -let r_aarch64_tlsld_ldst64_dtprel_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 538) -let r_aarch64_tlsld_ldst128_dtprel_lo12 : Nat_big_num.num= (Nat_big_num.of_int 572) -let r_aarch64_tlsld_ldst128_dtprel_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 573) - -let r_aarch64_tlsie_movw_gottprel_g1 : Nat_big_num.num= (Nat_big_num.of_int 539) -let r_aarch64_tlsie_movw_gottprel_g0_nc : Nat_big_num.num= (Nat_big_num.of_int 540) -let r_aarch64_tlsie_movw_gottprel_page21 : Nat_big_num.num= (Nat_big_num.of_int 541) -let r_aarch64_tlsie_movw_gottprel_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 542) -let r_aarch64_tlsie_movw_gottprel_prel19 : Nat_big_num.num= (Nat_big_num.of_int 543) - -let r_aarch64_tlsle_movw_tprel_g2 : Nat_big_num.num= (Nat_big_num.of_int 544) -let r_aarch64_tlsle_movw_tprel_g1 : Nat_big_num.num= (Nat_big_num.of_int 545) -let r_aarch64_tlsle_movw_tprel_g1_nc : Nat_big_num.num= (Nat_big_num.of_int 546) -let r_aarch64_tlsle_movw_tprel_g0 : Nat_big_num.num= (Nat_big_num.of_int 547) -let r_aarch64_tlsle_movw_tprel_g0_nc : Nat_big_num.num= (Nat_big_num.of_int 548) -let r_aarch64_add_tprel_hi12 : Nat_big_num.num= (Nat_big_num.of_int 549) -let r_aarch64_add_tprel_lo12 : Nat_big_num.num= (Nat_big_num.of_int 550) -let r_aarch64_add_tprel_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 551) -let r_aarch64_ldst8_tprel_lo12 : Nat_big_num.num= (Nat_big_num.of_int 552) -let r_aarch64_ldst8_tprel_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 553) -let r_aarch64_ldst16_tprel_lo12 : Nat_big_num.num= (Nat_big_num.of_int 554) -let r_aarch64_ldst16_tprel_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 555) -let r_aarch64_ldst32_tprel_lo12 : Nat_big_num.num= (Nat_big_num.of_int 556) -let r_aarch64_ldst32_tprel_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 557) -let r_aarch64_ldst64_tprel_lo12 : Nat_big_num.num= (Nat_big_num.of_int 558) -let r_aarch64_ldst64_tprel_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 559) -let r_aarch64_ldst128_tprel_lo12 : Nat_big_num.num= (Nat_big_num.of_int 570) -let r_aarch64_ldst128_tprel_lo12_nc : Nat_big_num.num= (Nat_big_num.of_int 571) - -let r_aarch64_tlsdesc_ld_prel19 : Nat_big_num.num= (Nat_big_num.of_int 560) -let r_aarch64_tlsdesc_adr_prel21 : Nat_big_num.num= (Nat_big_num.of_int 561) -let r_aarch64_tlsdesc_adr_page21 : Nat_big_num.num= (Nat_big_num.of_int 562) -let r_aarch64_tlsdesc_ld64_lo12 : Nat_big_num.num= (Nat_big_num.of_int 563) -let r_aarch64_tlsdesc_add_lo12 : Nat_big_num.num= (Nat_big_num.of_int 564) -let r_aarch64_tlsdesc_off_g1 : Nat_big_num.num= (Nat_big_num.of_int 565) -let r_aarch64_tlsdesc_off_g0_nc : Nat_big_num.num= (Nat_big_num.of_int 566) -let r_aarch64_tlsdesc_ldr : Nat_big_num.num= (Nat_big_num.of_int 567) -let r_aarch64_tlsdesc_add : Nat_big_num.num= (Nat_big_num.of_int 568) -let r_aarch64_tlsdesc_call : Nat_big_num.num= (Nat_big_num.of_int 569) - -let r_aarch64_copy : Nat_big_num.num= (Nat_big_num.of_int 1024) -let r_aarch64_glob_dat : Nat_big_num.num= (Nat_big_num.of_int 1025) -let r_aarch64_jump_slot : Nat_big_num.num= (Nat_big_num.of_int 1026) -let r_aarch64_relative : Nat_big_num.num= (Nat_big_num.of_int 1027) -let r_aarch64_tls_dtprel64 : Nat_big_num.num= (Nat_big_num.of_int 1028) -let r_aarch64_tls_dtpmod64 : Nat_big_num.num= (Nat_big_num.of_int 1029) -let r_aarch64_tls_tprel64 : Nat_big_num.num= (Nat_big_num.of_int 1030) -let r_aarch64_tlsdesc : Nat_big_num.num= (Nat_big_num.of_int 1031) -let r_aarch64_irelative : Nat_big_num.num= (Nat_big_num.of_int 1032) - -(** [string_of_aarch64_relocation_type m] produces a string representation of the - * relocation type [m]. - *) -(*val string_of_aarch64_relocation_type : natural -> string*) -let string_of_aarch64_relocation_type rel_type1:string= - (if Nat_big_num.equal rel_type1 r_aarch64_none then - "R_AARCH64_NONE" - else if Nat_big_num.equal rel_type1 r_aarch64_withdrawn then - "R_AARCH64_NONE" - else if Nat_big_num.equal rel_type1 r_aarch64_abs64 then - "R_AARCH64_ABS64" - else if Nat_big_num.equal rel_type1 r_aarch64_abs32 then - "R_AARCH64_ABS32" - else if Nat_big_num.equal rel_type1 r_aarch64_abs16 then - "R_AARCH64_ABS16" - else if Nat_big_num.equal rel_type1 r_aarch64_prel64 then - "R_AARCH64_PREL64" - else if Nat_big_num.equal rel_type1 r_aarch64_prel32 then - "R_AARCH64_PREL32" - else if Nat_big_num.equal rel_type1 r_aarch64_prel16 then - "R_AARCH64_PREL16" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_uabs_g0 then - "R_AARCH64_MOVW_UABS_G0" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_uabs_g0_nc then - "R_AARCH64_MOVW_UABS_G0_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_uabs_g1 then - "R_AARCH64_MOVW_UABS_G1" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_uabs_g1_nc then - "R_AARCH64_MOVW_UABS_G1_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_uabs_g2 then - "R_AARCH64_MOVW_UABS_G2" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_uabs_g2_nc then - "R_AARCH64_MOVW_UABS_G2_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_uabs_g3 then - "R_AARCH64_MOVW_UABS_G3" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_sabs_g0 then - "R_AARCH64_MOVW_SABS_G0" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_sabs_g1 then - "R_AARCH64_MOVW_SABS_G1" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_sabs_g2 then - "R_AARCH64_MOVW_SABS_G2" - else if Nat_big_num.equal rel_type1 r_aarch64_ld_prel_lo19 then - "R_AARCH64_LD_PREL_LO19" - else if Nat_big_num.equal rel_type1 r_aarch64_adr_prel_lo21 then - "R_AARCH64_ADR_PREL_LO21" - else if Nat_big_num.equal rel_type1 r_aarch64_adr_prel_pg_hi21 then - "R_AARCH64_ADR_PREL_PG_HI21" - else if Nat_big_num.equal rel_type1 r_aarch64_adr_prel_pg_hi21_nc then - "R_AARCH64_ADR_PREL_PG_HI21_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_add_abs_lo12_nc then - "R_AARCH64_ADD_ABS_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_ldst8_abs_lo12_nc then - "R_AARCH64_LDST8_ABS_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_ldst16_abs_lo12_nc then - "R_AARCH64_LDST16_ABS_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_ldst32_abs_lo12_nc then - "R_AARCH64_LDST32_ABS_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_ldst64_abs_lo12_nc then - "R_AARCH64_LDST64_ABS_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_ldst128_abs_lo12_nc then - "R_AARCH64_LDST128_ABS_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tstbr14 then - "R_AARCH64_TSTBR14" - else if Nat_big_num.equal rel_type1 r_aarch64_condbr19 then - "R_AARCH64_CONBR19" - else if Nat_big_num.equal rel_type1 r_aarch64_jump26 then - "R_AARCH64_JUMP26" - else if Nat_big_num.equal rel_type1 r_aarch64_call26 then - "R_AARCH64_CALL26" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_prel_g0 then - "R_AARCH64_MOVW_PREL_G0" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_prel_g0_nc then - "R_AARCH64_MOVW_PREL_G0_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_prel_g1 then - "R_AARCH64_MOVW_PREL_G1" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_prel_g1_nc then - "R_AARCH64_MOVW_PREL_G1_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_prel_g2 then - "R_AARCH64_MOVW_PREL_G2" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_prel_g2_nc then - "R_AARCH64_MOVW_PREL_G2_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_prel_g3 then - "R_AARCH64_MOVW_PREL_G3" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_gotoff_g0 then - "R_AARCH64_MOVW_GOTOFF_G0" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_gotoff_g0_nc then - "R_AARCH64_MOVW_GOTOFF_G0_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_gotoff_g1 then - "R_AARCH64_MOVW_GOTOFF_G1" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_gotoff_g1_nc then - "R_AARCH64_MOVW_GOTOFF_G1_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_gotoff_g2 then - "R_AARCH64_MOVW_GOTOFF_G2" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_gotoff_g2_nc then - "R_AARCH64_MOVW_GOTOFF_G2_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_movw_gotoff_g3 then - "R_AARCH64_MOVW_GOTOFF_G3" - else if Nat_big_num.equal rel_type1 r_aarch64_gotrel64 then - "R_AARCH64_GOTREL64" - else if Nat_big_num.equal rel_type1 r_aarch64_gotrel32 then - "R_AARCH64_GOTREL32" - else if Nat_big_num.equal rel_type1 r_aarch64_got_ld_prel19 then - "R_AARCH64_GOT_LD_PREL19" - else if Nat_big_num.equal rel_type1 r_aarch64_got_ld64_gotoff_lo15 then - "R_AARCH64_GOT_LD64_GOTOFF_LO15" - else if Nat_big_num.equal rel_type1 r_aarch64_adr_got_page then - "R_AARCH64_ADR_GOT_PAGE" - else if Nat_big_num.equal rel_type1 r_aarch64_ld64_got_lo12_nc then - "R_AARCH64_LD64_GOT_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_ld64_gotpage_lo15 then - "R_AARCH64_LD64_GOTPAGE_LO15" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsgd_adr_prel21 then - "R_AARCH64_TLSGD_ADR_PREL21" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsgd_adr_page21 then - "R_AARCH64_TLSGD_ADR_PAGE21" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsgd_add_lo12_nc then - "R_AARCH64_TLSGD_ADD_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsgd_movw_g1 then - "R_AARCH64_TLSGD_MOVW_G1" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsgd_movw_g0_nc then - "R_AARCH64_TlSGD_MOVW_G0_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_adr_prel21 then - "R_AARCH64_TLSLD_ADR_PREL21" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_adr_page21 then - "R_AARCH64_TLSLD_ADR_PAGE21" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_add_lo12_nc then - "R_AARCH64_TLSLD_ADD_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_movw_g1 then - "R_AARCH64_TLSLD_MOVW_G1" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_movw_g0_nc then - "R_AARCH64_TLSLD_MOVW_G0_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ld_prel19 then - "R_AARCH64_TLSLD_LD_PREL19" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_movw_dtprel_g2 then - "R_AARCH64_TLSLD_MOVW_DTPREL_G2" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_movw_dtprel_g1 then - "R_AARCH64_TLSLD_MOVW_DTPREL_G1" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_movw_dtprel_g1_nc then - "R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_movw_dtprel_g0 then - "R_AARCH64_TLSLD_MOVW_DTPREL_G0" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_movw_dtprel_g0_nc then - "R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_add_dtprel_hi12 then - "R_AARCH64_TLSLD_ADD_DTPREL_HI12" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_add_dtprel_lo12 then - "R_AARCH64_TLSLD_ADD_DTPREL_LO12" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_add_dtprel_lo12_nc then - "R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst8_dtprel_lo12 then - "R_AARCH64_TLSLD_LDST8_DTPREL_LO12" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst8_dtprel_lo12_nc then - "R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst16_dtprel_lo12 then - "R_AARCH64_TLSLD_LDST16_DTPREL_LO12" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst16_dtprel_lo12_nc then - "R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst32_dtprel_lo12 then - "R_AARCH64_TLSLD_LDST32_DTPREL_LO12" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst32_dtprel_lo12_nc then - "R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst64_dtprel_lo12 then - "R_AARCH64_TLSLD_LDST64_DPTREL_LO12" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst64_dtprel_lo12_nc then - "R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst128_dtprel_lo12 then - "R_AARCH64_TLSLD_LDST128_DTPREL_LO12" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst128_dtprel_lo12_nc then - "R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsie_movw_gottprel_g1 then - "R_AARCH64_TLSIE_MOVW_GOTTPREL_G1" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsie_movw_gottprel_g0_nc then - "R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsie_movw_gottprel_page21 then - "R_AARCH64_TLSIE_MOVW_GOTTPREL_PAGE21" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsie_movw_gottprel_lo12_nc then - "R_AARCH64_TLSIE_MOVW_GOTTPREL_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsie_movw_gottprel_prel19 then - "R_AARCH64_TLSIE_MOVW_GOTTPREL_PREL19" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsle_movw_tprel_g2 then - "R_AARCH64_TLSLE_MOVW_TPREL_G2" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsle_movw_tprel_g1 then - "R_AARCH64_TLSLE_MOVW_TPREL_G1" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsle_movw_tprel_g1_nc then - "R_AARCH64_TLSLE_MOVW_TPREL_G1_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsle_movw_tprel_g0 then - "R_AARCH64_TLSLE_MOVW_TPREL_G0" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsle_movw_tprel_g0_nc then - "R_AARCH64_TLSLE_MOVW_TPREL_G0_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_add_tprel_hi12 then - "R_AARCH64_ADD_TPREL_HI12" - else if Nat_big_num.equal rel_type1 r_aarch64_add_tprel_lo12 then - "R_AARCH64_ADD_TPREL_LO12" - else if Nat_big_num.equal rel_type1 r_aarch64_add_tprel_lo12_nc then - "R_AARCH64_ADD_TPREL_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_ldst8_tprel_lo12 then - "R_AARCH64_LDST8_TPREL_LO12" - else if Nat_big_num.equal rel_type1 r_aarch64_ldst8_tprel_lo12_nc then - "R_AARCH64_LDST8_TPREL_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_ldst16_tprel_lo12 then - "R_AARCH64_LDST16_TPREL_LO12" - else if Nat_big_num.equal rel_type1 r_aarch64_ldst16_tprel_lo12_nc then - "R_AARCH64_LDST16_TPREL_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_ldst32_tprel_lo12 then - "R_AARCH64_LDST32_TPREL_LO12" - else if Nat_big_num.equal rel_type1 r_aarch64_ldst32_tprel_lo12_nc then - "R_AARCH64_LDST32_TPREL_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_ldst64_tprel_lo12 then - "R_AARCH64_LDST64_TPREL_LO12" - else if Nat_big_num.equal rel_type1 r_aarch64_ldst64_tprel_lo12_nc then - "R_AARCH64_LDST64_TPREL_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_ldst128_tprel_lo12 then - "R_AARCH64_LDST128_TPREL_LO12" - else if Nat_big_num.equal rel_type1 r_aarch64_ldst128_tprel_lo12_nc then - "R_AARCH64_LDST128_TPREL_LO12_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_ld_prel19 then - "R_AARCH64_TLSDESC_LS_PREL19" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_adr_prel21 then - "R_AARCH64_TLSDESC_ADR_PREL21" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_adr_page21 then - "R_AARCH64_TLSDESC_ADR_PAGE21" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_ld64_lo12 then - "R_AARCH64_TLSDESC_LD64_LO12" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_add_lo12 then - "R_AARCH64_TLSDESC_ADD_LO12" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_off_g1 then - "R_AARCH64_TLSDESC_OFF_G1" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_off_g0_nc then - "R_AARCH64_TLSDESC_OFF_G0_NC" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_ldr then - "R_AARCH64_TLSDESC_LDR" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_add then - "R_AARCH64_TLSDESC_ADD" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_call then - "R_AARCH64_TLSDESC_CALL" - else if Nat_big_num.equal rel_type1 r_aarch64_copy then - "R_AARCH64_COPY" - else if Nat_big_num.equal rel_type1 r_aarch64_glob_dat then - "R_AARCH64_GLOB_DAT" - else if Nat_big_num.equal rel_type1 r_aarch64_jump_slot then - "R_AARCH64_JUMP_SLOT" - else if Nat_big_num.equal rel_type1 r_aarch64_relative then - "R_AARCH64_RELATIVE" - else if Nat_big_num.equal rel_type1 r_aarch64_tls_dtprel64 then - "R_AARCH64_DTPREL64" - else if Nat_big_num.equal rel_type1 r_aarch64_tls_dtpmod64 then - "R_AARCH64_DTPMOD64" - else if Nat_big_num.equal rel_type1 r_aarch64_tls_tprel64 then - "R_AARCH64_TPREL64" - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc then - "R_AARCH64_TLSDESC" - else if Nat_big_num.equal rel_type1 r_aarch64_irelative then - "R_AARCH64_IRELATIVE" - else - "Invalid AARCH64 relocation type") - -(*val aarch64_le_reloc : forall 'abifeature. reloc_fn 'abifeature*) -let aarch64_le_reloc r:bool*('abifeature annotated_memory_image ->Nat_big_num.num ->symbol_reference_and_reloc_site ->Nat_big_num.num*(Nat_big_num.num ->Nat_big_num.num ->Nat_big_num.num ->Nat_big_num.num))= - (if Nat_big_num.equal r r_aarch64_none then - (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 0, (fun s -> fun a -> fun e -> e)))))) - else - (false, noop_reloc_apply)) - -(** [abi_aarch64_apply_relocation rel s_val p_val got_val ef] produces an AST - * of the relocation calculation for relocation type [rel] using [s_val], [p_val], - * and [got_val] as primitive components. - * - * TODO: unclear from ABI spec. whether overflow check on relocations is - * supposed to cause relocation to fail if not satisfied or whether there is - * wrap-around. Resolve. - *) -(*val abi_aarch64_apply_relocation : elf64_relocation_a -> integer -> integer -> - integer -> elf64_file -> - error (Map.map elf64_addr (relocation_operator_expression integer * integer_bit_width * can_fail integer))*) -let abi_aarch64_apply_relocation rel s_val p_val got_val ef:(((Uint64.uint64),((Nat_big_num.num)relocation_operator_expression*integer_bit_width*(Nat_big_num.num)can_fail))Pmap.map)error= - (if is_elf64_relocatable_file ef.elf64_file_header then - let rel_type1 = (get_elf64_relocation_a_type rel) in - let a_val = (Nat_big_num.of_int64 rel.elf64_ra_addend) in - (** No width, no calculation *) - if Nat_big_num.equal rel_type1 r_aarch64_none then - return (Pmap.empty compare) - (** No width, no calculation *) - else if Nat_big_num.equal rel_type1 r_aarch64_withdrawn then - return (Pmap.empty compare) - (** Signed 64 bit width, calculation: S + A *) - else if Nat_big_num.equal rel_type1 r_aarch64_abs64 then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - (** Signed 32 bit width, calculation: S + A *) - else if Nat_big_num.equal rel_type1 r_aarch64_abs32 then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - (** Signed 16 bith width, calculation: S + A *) - else if Nat_big_num.equal rel_type1 r_aarch64_abs16 then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - (** Signed 64 bit width, calculation: S + A - P *) - else if Nat_big_num.equal rel_type1 r_aarch64_prel64 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - (** Signed 32 bit width, calculation: S + A - P *) - else if Nat_big_num.equal rel_type1 r_aarch64_prel32 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - (** Signed 16 bit width, calculation: S + A - P *) - else if Nat_big_num.equal rel_type1 r_aarch64_prel16 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_uabs_g0 then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U16, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_uabs_g0_nc then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_uabs_g1 then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U32, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_uabs_g1_nc then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U32, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_uabs_g2 then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U48, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_uabs_g2_nc then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U48, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_uabs_g3 then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U64, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_sabs_g0 then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_sabs_g1 then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_sabs_g2 then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I48, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ld_prel_lo19 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I20, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_adr_prel_lo21 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I20, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_adr_prel_pg_hi21 then - let result = (Minus(Apply(Page, Lift ( Nat_big_num.add s_val a_val)), Apply(Page, Lift p_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_adr_prel_pg_hi21_nc then - let result = (Minus (Apply(Page, Lift ( Nat_big_num.add s_val a_val)), Apply(Page, Lift p_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_add_abs_lo12_nc then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ldst8_abs_lo12_nc then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ldst16_abs_lo12_nc then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ldst32_abs_lo12_nc then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ldst64_abs_lo12_nc then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ldst128_abs_lo12_nc then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tstbr14 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I15, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_condbr19 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I20, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_jump26 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I27, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_call26 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I27, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_prel_g0 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_prel_g0_nc then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_prel_g1 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_prel_g1_nc then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_prel_g2 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I48, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_prel_g2_nc then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I48, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_prel_g3 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_gotoff_g0 then - let result = (Minus (Apply(G, Apply(GDat, Lift ( Nat_big_num.add s_val a_val))), Lift got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_gotoff_g0_nc then - let result = (Minus (Apply(G, Apply(GDat, Lift ( Nat_big_num.add s_val a_val))), Lift got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_gotoff_g1 then - let result = (Minus (Apply(G, Apply(GDat, Lift ( Nat_big_num.add s_val a_val))), Lift got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_gotoff_g1_nc then - let result = (Minus (Apply(G, Apply(GDat, Lift ( Nat_big_num.add s_val a_val))), Lift got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_gotoff_g2 then - let result = (Minus (Apply(G, Apply(GDat, Lift ( Nat_big_num.add s_val a_val))), Lift got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I48, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_gotoff_g2_nc then - let result = (Minus (Apply(G, Apply(GDat, Lift ( Nat_big_num.add s_val a_val))), Lift got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_movw_gotoff_g3 then - let result = (Minus (Apply(G, Apply(GDat, Lift ( Nat_big_num.add s_val a_val))), Lift got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_gotrel64 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_gotrel32 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_got_ld_prel19 then - let result = (Minus (Apply(G, Apply(GDat, Lift ( Nat_big_num.add s_val a_val))), Lift p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I20, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_got_ld64_gotoff_lo15 then - let result = (Minus (Apply(G, Apply(GDat, Lift ( Nat_big_num.add s_val a_val))), Lift got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U15, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_adr_got_page then - let result = (Minus (Apply(Page, Apply(G, Apply(GDat, Lift ( Nat_big_num.add s_val a_val)))), Apply(Page, Lift p_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ld64_got_lo12_nc then - (** requires ad hoc check *) - let result = (Apply(G, Apply(GDat, Lift ( Nat_big_num.add s_val a_val)))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I20, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ld64_gotpage_lo15 then - (** requires ad hoc check *) - let result = (Minus(Apply(G, Apply(GDat, Lift ( Nat_big_num.add s_val a_val))), Apply(Page, Lift got_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U15, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsgd_adr_prel21 then - let result = (Minus(Apply(G, Apply2(GTLSIdx, Lift s_val, Lift a_val)), Lift p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I20, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsgd_adr_page21 then - let result = (Minus(Apply(Page, Apply(G, Apply2(GTLSIdx, Lift s_val, Lift a_val))), Apply(Page, Lift p_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsgd_add_lo12_nc then - let result = (Apply(G, Apply2(GTLSIdx, Lift s_val, Lift a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I12, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsgd_movw_g1 then - (** requires ad hoc check *) - let result = (Minus(Apply(G, Apply2(GTLSIdx, Lift s_val, Lift a_val)), Lift got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsgd_movw_g0_nc then - let result = (Minus(Apply(G, Apply2 (GTLSIdx, Lift s_val, Lift a_val)), Lift got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_adr_prel21 then - let result = (Minus(Apply(G, Apply(GLDM, Lift s_val)), Lift p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I20, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_adr_page21 then - let result = (Minus(Apply(G, Apply(GLDM, Lift s_val)), Apply(Page, Lift p_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_add_lo12_nc then - let result = (Apply(G, Apply(GLDM, Lift s_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_movw_g1 then - let result = (Minus(Apply(G, Apply(GLDM, Lift s_val)), Lift got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I15, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_movw_g0_nc then - let result = (Minus(Apply(G, Apply(GLDM, Lift s_val)), Lift got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I15, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ld_prel19 then - let result = (Minus(Apply(G, Apply(GLDM, Lift s_val)), Lift p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I20, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_movw_dtprel_g2 then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I15, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_movw_dtprel_g1 then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I15, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_movw_dtprel_g1_nc then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I15, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_movw_dtprel_g0 then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I15, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_movw_dtprel_g0_nc then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I15, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_add_dtprel_hi12 then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U24, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_add_dtprel_lo12 then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_add_dtprel_lo12_nc then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst8_dtprel_lo12 then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst8_dtprel_lo12_nc then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst16_dtprel_lo12 then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst16_dtprel_lo12_nc then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst32_dtprel_lo12 then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst32_dtprel_lo12_nc then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst64_dtprel_lo12 then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst64_dtprel_lo12_nc then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst128_dtprel_lo12 then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsld_ldst128_dtprel_lo12_nc then - let result = (Apply(DTPRel, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsie_movw_gottprel_g1 then - let result = (Minus(Apply(G, Apply(GTPRel, Lift ( Nat_big_num.add s_val a_val))), Lift got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I15, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsie_movw_gottprel_g0_nc then - let result = (Minus(Apply(G, Apply(GTPRel, Lift ( Nat_big_num.add s_val a_val))), Lift got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I15, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsie_movw_gottprel_page21 then - let result = (Minus(Apply(Page, Apply(G, Apply(GTPRel, Lift ( Nat_big_num.add s_val a_val)))), Apply(Page, Lift p_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsie_movw_gottprel_lo12_nc then - (** requires ad hoc check *) - let result = (Apply(G, Apply(GTPRel, Lift ( Nat_big_num.add s_val a_val)))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I8, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsie_movw_gottprel_prel19 then - let result = (Minus(Apply(G, Apply(GTPRel, Lift ( Nat_big_num.add s_val a_val))), Lift p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I20, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsle_movw_tprel_g2 then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U16, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsle_movw_tprel_g1 then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U16, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsle_movw_tprel_g1_nc then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsle_movw_tprel_g0 then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U16, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsle_movw_tprel_g0_nc then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_add_tprel_hi12 then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U24, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_add_tprel_lo12 then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_add_tprel_lo12_nc then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ldst8_tprel_lo12 then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ldst8_tprel_lo12_nc then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ldst16_tprel_lo12 then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ldst16_tprel_lo12_nc then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ldst32_tprel_lo12 then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ldst32_tprel_lo12_nc then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ldst64_tprel_lo12 then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ldst64_tprel_lo12_nc then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ldst128_tprel_lo12 then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_ldst128_tprel_lo12_nc then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, U12, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_ld_prel19 then - (** requires ad hoc test *) - let result = (Minus(Apply(G, Apply(GTLSDesc, Lift ( Nat_big_num.add s_val a_val))), Lift p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I20, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_adr_prel21 then - let result = (Minus (Apply(G, Apply(GTLSDesc, Lift ( Nat_big_num.add s_val a_val))), Lift p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I20, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_adr_page21 then - let result = (Minus(Apply(Page, Apply(G, Apply(GTLSDesc, Lift( Nat_big_num.add s_val a_val)))), Apply(Page, Lift p_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_ld64_lo12 then - (** requires ad hoc test *) - let result = (Apply(G, Apply(GTLSDesc, Lift ( Nat_big_num.add s_val a_val)))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I20, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_add_lo12 then - let result = (Apply(G, Apply(GTLSDesc, Lift ( Nat_big_num.add s_val a_val)))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_off_g1 then - let result = (Minus(Apply(G, Apply(GTLSDesc, Lift ( Nat_big_num.add s_val a_val))), Lift got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_off_g0_nc then - let result = (Minus(Apply(G, Apply(GTLSDesc, Lift ( Nat_big_num.add s_val a_val))), Lift got_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_ldr then - return (Pmap.empty compare) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_add then - return (Pmap.empty compare) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc_call then - return (Pmap.empty compare) - else if Nat_big_num.equal rel_type1 r_aarch64_copy then - fail "AARCH64_COPY" - else if Nat_big_num.equal rel_type1 r_aarch64_glob_dat then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_jump_slot then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_relative then - let result = (Plus(Apply(Delta, Lift s_val), Lift a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tls_dtprel64 then - let result = (Apply(DTPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tls_dtpmod64 then - let result = (Apply(LDM, Lift s_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tls_tprel64 then - let result = (Apply(TPRel, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_tlsdesc then - let result = (Apply(TLSDesc, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_aarch64_irelative then - let result = (Apply(Indirect, Plus (Apply(Delta, Lift s_val), Lift a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - else - fail "Invalid AARCH64 relocation type" - else - fail "abi_aarch64_apply_relocation: not a relocatable file") diff --git a/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_section_header_table.ml b/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_section_header_table.ml deleted file mode 100644 index 5716a83f..00000000 --- a/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_section_header_table.ml +++ /dev/null @@ -1,25 +0,0 @@ -(*Generated by Lem from abis/aarch64/abi_aarch64_section_header_table.lem.*) -(** [abi_aarch64_section_header_table], AARCH64 ABI specific definitions related - * to the section header table. - *) - -open Lem_basic_classes -open Lem_num - -(** AARCH64 specific section types *) - -(** Contains build attributes. What these are is not specified, and compilers - * are free to insert their own proprietary information in this section. See - * Section 4.3. - *) -let sht_aarch64_attributes : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 939524097)(Nat_big_num.of_int 2))(Nat_big_num.of_int 1)) (* 0x70000003 *) - -(** [string_of_aarch64_section_type m] produces a string based representation of - * AARCH64 section type [m]. - *) -(*val string_of_aarch64_section_type : natural -> string*) -let string_of_aarch64_section_type m:string= - (if Nat_big_num.equal m sht_aarch64_attributes then - ".ARM.attributes" - else - "Unrecognised section type") diff --git a/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_symbol_table.ml b/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_symbol_table.ml deleted file mode 100644 index 35428632..00000000 --- a/lib/ocaml_rts/linksem/abis/aarch64/abi_aarch64_symbol_table.ml +++ /dev/null @@ -1,23 +0,0 @@ -(*Generated by Lem from abis/aarch64/abi_aarch64_symbol_table.lem.*) -(** [abi_aarch64_symbol_table], symbol table specific defintions for the AARCH64 - * ABI. - *) - -open Lem_basic_classes -open Lem_bool - -open Elf_header -open Elf_symbol_table -open Elf_section_header_table -open Elf_types_native_uint - -(** Two types of weak symbol are defined in the AARCH64 ABI. See Section 4.5. - *) -(*val is_aarch64_weak_reference : elf64_symbol_table_entry -> bool*) -let is_aarch64_weak_reference ent:bool= (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string ent.elf64_st_shndx)) shn_undef && Nat_big_num.equal -(get_elf64_symbol_binding ent) stb_weak) - -(*val is_aarch64_weak_definition : elf64_symbol_table_entry -> bool*) -let is_aarch64_weak_definition ent:bool= (not (Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string ent.elf64_st_shndx)) shn_undef) && Nat_big_num.equal -(get_elf64_symbol_binding ent) stb_weak) diff --git a/lib/ocaml_rts/linksem/abis/abi_classes.ml b/lib/ocaml_rts/linksem/abis/abi_classes.ml deleted file mode 100644 index 7b8b8876..00000000 --- a/lib/ocaml_rts/linksem/abis/abi_classes.ml +++ /dev/null @@ -1,4 +0,0 @@ -(*Generated by Lem from abis/abi_classes.lem.*) -type 'a abiFeatureTagEquiv_class={ - abiFeatureTagEquiv_method : 'a -> 'a -> bool -} diff --git a/lib/ocaml_rts/linksem/abis/abi_utilities.ml b/lib/ocaml_rts/linksem/abis/abi_utilities.ml deleted file mode 100644 index 02dd9fab..00000000 --- a/lib/ocaml_rts/linksem/abis/abi_utilities.ml +++ /dev/null @@ -1,213 +0,0 @@ -(*Generated by Lem from abis/abi_utilities.lem.*) -(** [abi_utilities], generic utilities shared between all ABIs. - *) - -open Lem_map -open Lem_maybe -open Lem_num -open Lem_basic_classes -open Lem_maybe -open Lem_string -open Error -open Lem_assert_extra - -open Abi_classes -open Missing_pervasives -open Elf_types_native_uint -open Elf_symbol_table -open Elf_relocation -open Memory_image -open Memory_image_orderings - - -open Error - -(** [integer_bit_width] records various bit widths for integral types, as used - * in relocation calculations. The names are taken directly from the processor - * supplements to keep the calculations as close as possible - * to the specification of relocations. - *) -type integer_bit_width - = I8 (** Signed 8 bit *) - | I12 - | U12 (** Unsigned 12 bit *) - | Low14 - | U15 (** Unsigned 15 bit *) - | I15 - | I16 (** Signed 16 bit *) - | Half16ds - | I20 (** Signed 20 bit *) - | Low24 - | I27 - | Word30 - | I32 (** Signed 32 bit *) - | I48 (** Signed 48 bit *) - | I64 (** Signed 64 bit *) - | I64X2 (** Signed 128 bit *) - | U16 (** Unsigned 16 bit *) - | U24 (** Unsigned 24 bit *) - | U32 (** Unsigned 32 bit *) - | U48 (** Unsigned 48 bit *) - | U64 (** Unsigned 64 bit *) - -(** [natural_of_integer_bit_width i] computes the bit width of integer bit width - * [i]. - *) -(*val natural_of_integer_bit_width : integer_bit_width -> natural*) -let natural_of_integer_bit_width i:Nat_big_num.num= - ((match i with - | I8 ->Nat_big_num.of_int 8 - | I12 ->Nat_big_num.of_int 12 - | U12 ->Nat_big_num.of_int 12 - | Low14 ->Nat_big_num.of_int 14 - | I15 ->Nat_big_num.of_int 15 - | U15 ->Nat_big_num.of_int 15 - | I16 ->Nat_big_num.of_int 16 - | Half16ds ->Nat_big_num.of_int 16 - | U16 ->Nat_big_num.of_int 16 - | I20 ->Nat_big_num.of_int 20 - | Low24 ->Nat_big_num.of_int 24 - | U24 ->Nat_big_num.of_int 24 - | I27 ->Nat_big_num.of_int 27 - | Word30 ->Nat_big_num.of_int 30 - | I32 ->Nat_big_num.of_int 32 - | U32 ->Nat_big_num.of_int 32 - | I48 ->Nat_big_num.of_int 48 - | U48 ->Nat_big_num.of_int 48 - | I64 ->Nat_big_num.of_int 64 - | U64 ->Nat_big_num.of_int 64 - | I64X2 ->Nat_big_num.of_int 128 - )) - -(** [relocation_operator] records the operators used to calculate relocations by - * the various ABIs. Each ABI will only use a subset of these, and they should - * be interpreted on a per-ABI basis. As more ABIs are added, more operators - * will be needed, and therefore more constructors in this type will need to - * be added. These are unary operators, operating on a single integral type. - *) -type relocation_operator - = TPRel - | LTOff - | DTPMod - | DTPRel - | Page - | GDat - | G - | GLDM - | GTPRel - | GTLSDesc - | Delta - | LDM - | TLSDesc - | Indirect - | Lo - | Hi - | Ha - | Higher - | HigherA - | Highest - | HighestA - -(** [relocation_operator2] is a binary relocation operator, as detailed above. - *) -type relocation_operator2 = - | GTLSIdx - -(** Generalising and abstracting over relocation calculations and their return - * types - *) - -type( 'k, 'v) val_map = ('k, 'v) - Pmap.map - -(*val lookupM : forall 'k 'v. MapKeyType 'k => 'k -> val_map 'k 'v -> error 'v*) -let lookupM dict_Map_MapKeyType_k key val_map1:'v error= - ((match Pmap.lookup key val_map1 with - | None -> fail "lookupM: key not found in val_map" - | Some j -> return j - )) - -(** Some relocations may fail, for example: - * Page 58, Power ABI: relocation types whose Field column is marked with an - * asterisk are subject to failure is the value computed does not fit in the - * allocated bits. [can_fail] type passes this information back to the caller - * of the relocation application function. - *) -type 'a can_fail - = CanFail (** [CanFail] signals a potential failing relocation calculation when width constraints are invalidated *) - | CanFailOnTest of ('a -> bool) (** [CanFailOnTest p] signals a potentially failing relocation calculation when predicate [p] on the result of the calculation returns [false] *) - | CannotFail (** [CannotFail] states the relocation calculation cannot fail and bit-width constraints should be ignored *) - -(** [relocation_operator_expression] is an AST of expressions describing a relocation - * calculation. An AST is used as it allows us to unify the treatment of relocation - * calculation: rather than passing in dozens of functions to the calculation function - * that perform the actual relocation, we can simply return a description (in the form - * of the AST below) of the calculation to be carried out and have it interpreted - * separately from the function that produces it. The type parameter 'a is the - * type of base integral type. This AST suffices for the relocation calculations we - * currently have implemented, but adding more ABIs may require that this type is - * expanded. - *) -type 'a relocation_operator_expression - = Lift of 'a (** Lift a base type into an AST *) - | Apply of (relocation_operator * 'a relocation_operator_expression) (** Apply a unary operator to an expression *) - | Apply2 of (relocation_operator2 * 'a relocation_operator_expression * 'a relocation_operator_expression) (** Apply a binary operator to two expressions *) - | Plus of ( 'a relocation_operator_expression * 'a relocation_operator_expression) (** Add two expressions. *) - | Minus of ( 'a relocation_operator_expression * 'a relocation_operator_expression) (** Subtract two expressions. *) - | RShift of ( 'a relocation_operator_expression * Nat_big_num.num) (** Right shift the result of an expression [m] places. *) - -type( 'addr, 'res) relocation_frame = - | Copy - | NoCopy of ( ('addr, ( 'res relocation_operator_expression * integer_bit_width * 'res can_fail))Pmap.map) - -(*val size_of_def : symbol_reference_and_reloc_site -> natural*) -let size_of_def rr:Nat_big_num.num= - (let rf = (rr.ref) in - let sm = (rf.ref_syment) in - Ml_bindings.nat_big_num_of_uint64 sm.elf64_st_size) - -(*val size_of_copy_reloc : forall 'abifeature. annotated_memory_image 'abifeature -> symbol_reference_and_reloc_site -> natural*) -let size_of_copy_reloc img2 rr:Nat_big_num.num= -( - (* it's the minimum of the two definition symbol sizes. FIXME: for now, just use the rr *)size_of_def rr) - -(*val reloc_site_address : forall 'abifeature. Ord 'abifeature, AbiFeatureTagEquiv 'abifeature => - annotated_memory_image 'abifeature -> symbol_reference_and_reloc_site -> natural*) -let reloc_site_address dict_Basic_classes_Ord_abifeature dict_Abi_classes_AbiFeatureTagEquiv_abifeature img2 rr:Nat_big_num.num= -( - (* find the element range that's tagged with this reloc site *)let found_kvs = (Multimap.lookupBy0 - (instance_Basic_classes_Ord_Memory_image_range_tag_dict - dict_Basic_classes_Ord_abifeature) (instance_Basic_classes_Ord_Maybe_maybe_dict - (instance_Basic_classes_Ord_tup2_dict - Lem_string_extra.instance_Basic_classes_Ord_string_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_Num_natural_dict - instance_Basic_classes_Ord_Num_natural_dict))) instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) (=) (SymbolRef(rr)) img2.by_tag) - in - (match found_kvs with - [] -> failwith "impossible: reloc site not marked in memory image" - | [(_, maybe_range)] -> (match maybe_range with - None -> failwith "impossible: reloc site has no element range" - | Some (el_name, el_range) -> - let element_addr = ((match Pmap.lookup el_name img2.elements with - None -> failwith "impossible: non-existent element" - | Some el -> (match el.startpos with - None -> failwith "error: resolving relocation site address before address has been assigned" - | Some addr -> addr - ) - )) - in - let site_offset = (* match rr.maybe_reloc with - Just reloc -> natural_of_elf64_addr reloc.ref_relent.elf64_ra_offset - | Nothing -> failwith "symbol reference with range but no reloc site" - end*) (let (start, _) = el_range in start) - in Nat_big_num.add - element_addr site_offset - ) - | _ -> failwith "error: more than one address with identical relocation record" - )) diff --git a/lib/ocaml_rts/linksem/abis/abis.ml b/lib/ocaml_rts/linksem/abis/abis.ml deleted file mode 100644 index 0cbd92d8..00000000 --- a/lib/ocaml_rts/linksem/abis/abis.ml +++ /dev/null @@ -1,1420 +0,0 @@ -(*Generated by Lem from abis/abis.lem.*) -(** The [abis] module is the top-level module for all ABI related code, including - * some generic functionality that works across all ABIs, and a primitive attempt - * at abstracting over ABIs for purposes of linking. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_num -open Lem_maybe -open Lem_list -open Lem_set -(*import Map*) -open Lem_string -open Show -open Lem_assert_extra -open Error -open Missing_pervasives - -open Elf_file -open Elf_header -open Elf_interpreted_section -open Elf_relocation -open Elf_symbol_table -open Elf_program_header_table -open Elf_section_header_table -open Memory_image - -open Abi_amd64 -open Abi_amd64_relocation - -open Abi_aarch64_le -open Abi_aarch64_relocation - -open Abi_power64 -open Abi_power64_relocation - -open Gnu_ext_abi - -open Abi_classes -open Abi_utilities -open Elf_types_native_uint - -open Memory_image_orderings - -(** Relocation operators and their validity on a given platform *) - -(*val is_valid_abi_aarch64_relocation_operator : relocation_operator -> bool*) -let is_valid_abi_aarch64_relocation_operator op:bool= - ((match op with - | Page -> true - | G -> true - | GDat -> true - | GLDM -> true - | DTPRel -> true - | GTPRel -> true - | TPRel -> true - | GTLSDesc -> true - | Delta -> true - | LDM -> true - | TLSDesc -> true - | Indirect -> true - | _ -> false - )) - -(*val is_valid_abi_aarch64_relocation_operator2 : relocation_operator2 -> bool*) -let is_valid_abi_aarch64_relocation_operator2 op:bool= - ((match op with - | GTLSIdx -> true - )) - -(*val is_valid_abi_amd64_relocation_operator : relocation_operator -> bool*) -let is_valid_abi_amd64_relocation_operator op:bool= - ((match op with - | Indirect -> true - | _ -> false (* XXX: not sure about this? *) - )) - -(*val is_valid_abi_amd64_relocation_operator2 : relocation_operator2 -> bool*) -let is_valid_abi_amd64_relocation_operator2 op:bool= - ((match op with - | _ -> false - )) - -(*val is_valid_abi_power64_relocation_operator : relocation_operator -> bool*) -let is_valid_abi_power64_relocation_operator op:bool= false (* TODO *) - -(*val is_valid_abi_power64_relocation_operator2 : relocation_operator2 -> bool*) -let is_valid_abi_power64_relocation_operator2 op:bool= - ((match op with - | _ -> false - )) - -(** Misc. ABI related stuff *) - -type any_abi_feature = Amd64AbiFeature of any_abi_feature amd64_abi_feature - | Aarch64LeAbiFeature of aarch64_le_abi_feature - -(*val anyAbiFeatureCompare : any_abi_feature -> any_abi_feature -> Basic_classes.ordering*) -let anyAbiFeatureCompare f1 f2:int= - ((match (f1, f2) with - (Amd64AbiFeature(af1), Amd64AbiFeature(af2)) -> Abi_amd64.abiFeatureCompare0 af1 af2 - |(Amd64AbiFeature(_), _) -> (-1) - |(Aarch64LeAbiFeature(af1), Amd64AbiFeature(af2)) -> 1 - |(Aarch64LeAbiFeature(af1), Aarch64LeAbiFeature(af2)) -> abiFeatureCompare af1 af2 - )) - -(*val anyAbiFeatureTagEquiv : any_abi_feature -> any_abi_feature -> bool*) -let anyAbiFeatureTagEquiv f1 f2:bool= - ((match (f1, f2) with - (Amd64AbiFeature(af1), Amd64AbiFeature(af2)) -> Abi_amd64.abiFeatureTagEq0 af1 af2 - |(Amd64AbiFeature(_), _) -> false - |(Aarch64LeAbiFeature(af1), Amd64AbiFeature(af2)) -> false - |(Aarch64LeAbiFeature(af1), Aarch64LeAbiFeature(af2)) -> abiFeatureTagEq af1 af2 - )) - -let instance_Basic_classes_Ord_Abis_any_abi_feature_dict:(any_abi_feature)ord_class= ({ - - compare_method = anyAbiFeatureCompare; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(anyAbiFeatureCompare f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (anyAbiFeatureCompare f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(anyAbiFeatureCompare f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (anyAbiFeatureCompare f1 f2)(Pset.from_list compare [1; 0])))}) - -let instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict:(any_abi_feature)abiFeatureTagEquiv_class= ({ - - abiFeatureTagEquiv_method = anyAbiFeatureTagEquiv}) - -let make_elf64_header data osabi abiv ma t entry shoff phoff phnum shnum shstrndx:elf64_header= - ({ elf64_ident = ([elf_mn_mag0; elf_mn_mag1; elf_mn_mag2; elf_mn_mag3; - Uint32.of_string (Nat_big_num.to_string elf_class_64); - Uint32.of_string (Nat_big_num.to_string data); - Uint32.of_string (Nat_big_num.to_string elf_ev_current); - Uint32.of_string (Nat_big_num.to_string osabi); - Uint32.of_string (Nat_big_num.to_string abiv); - Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0)); - Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0)); - Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0)); - Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0)); - Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0)); - Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0)); - Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))]) - ; elf64_type = (Uint32.of_string (Nat_big_num.to_string t)) - ; elf64_machine = (Uint32.of_string (Nat_big_num.to_string ma)) - ; elf64_version = (Uint32.of_string (Nat_big_num.to_string elf_ev_current)) - ; elf64_entry = (Uint64.of_string (Nat_big_num.to_string entry)) - ; elf64_phoff = (Uint64.of_string (Nat_big_num.to_string phoff)) - ; elf64_shoff = (Uint64.of_string (Nat_big_num.to_string shoff)) - ; elf64_flags = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_ehsize = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 64))) - ; elf64_phentsize= (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 56))) - ; elf64_phnum = (Uint32.of_string (Nat_big_num.to_string phnum)) - ; elf64_shentsize= (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 64))) - ; elf64_shnum = (Uint32.of_string (Nat_big_num.to_string shnum)) - ; elf64_shstrndx = (Uint32.of_string (Nat_big_num.to_string shstrndx)) - }) - -(*val phdr_flags_from_section_flags : natural -> string -> natural*) -let phdr_flags_from_section_flags section_flags sec_name:Nat_big_num.num= - (let flags = (Nat_big_num.bitwise_or elf_pf_r (Nat_big_num.bitwise_or - (if flag_is_set shf_write section_flags then elf_pf_w else Nat_big_num.of_int 0) - (if flag_is_set shf_execinstr section_flags then elf_pf_x else Nat_big_num.of_int 0))) - in - (*let _ = errln ("Phdr flags of section " ^ sec_name ^ "(ELF section flags 0x " ^ - (hex_string_of_natural section_flags) ^ ") are 0x" ^ (hex_string_of_natural flags)) - in*) - flags) - -(*val phdr_is_writable : natural -> bool*) -let phdr_is_writable flags:bool= (Nat_big_num.equal - (Nat_big_num.bitwise_and flags elf_pf_w) elf_pf_w) - -type can_combine_flags_fn = Nat_big_num.num Pset.set -> Nat_big_num.num option - -(* FIXME: lift this to a personality function of the GNU linker? - * Not sure really... need to try some other linkers. *) -(*val load_can_combine_flags : can_combine_flags_fn*) -let load_can_combine_flags flagsets:(Nat_big_num.num)option= -( - (* The GNU linker happily adds a .rodata section to a RX segment, - * but not to a RW segment. So the only clear rule is: if any is writable, - * all must be writable. *)let flagslist = (Pset.elements flagsets) - in - let union_flags = (List.fold_left Nat_big_num.bitwise_or(Nat_big_num.of_int 0) flagslist) - in - if List.exists phdr_is_writable flagslist - then - if List.for_all phdr_is_writable flagslist then Some union_flags - else None - else - Some union_flags) - -(*val tls_can_combine_flags : can_combine_flags_fn*) -let tls_can_combine_flags flagsets:(Nat_big_num.num)option= (Some (List.fold_left Nat_big_num.bitwise_or(Nat_big_num.of_int 0) (Pset.elements flagsets))) - -let maybe_extend_phdr phdr isec1 can_combine_flags:(elf64_program_header_table_entry)option= - (let new_p_type = (Nat_big_num.of_string (Uint32.to_string phdr.elf64_p_type)) - in - let this_section_phdr_flags = (phdr_flags_from_section_flags isec1.elf64_section_flags isec1.elf64_section_name_as_string) - in - let maybe_extended_flags = (can_combine_flags(Pset.from_list Nat_big_num.compare [ this_section_phdr_flags; Nat_big_num.of_string (Uint32.to_string phdr.elf64_p_flags) ])) - in - if (Lem.option_equal Nat_big_num.equal maybe_extended_flags None) then (*let _ = errln "flag mismatch" in*) None - else let new_p_flags = ((match maybe_extended_flags with Some flags -> flags | _ -> failwith "impossible" )) - in - (* The new filesz is the file end offset of this section, - * minus the existing file start offset of the phdr. - * Check that the new section begins after the old offset+filesz. *) - if Nat_big_num.less isec1.elf64_section_offset (Nat_big_num.add (Nat_big_num.of_string (Uint64.to_string phdr.elf64_p_offset)) (Ml_bindings.nat_big_num_of_uint64 phdr.elf64_p_filesz)) - then (*let _ = errln "offset went backwards" in*) None - else - let new_p_filesz = (Nat_big_num.add (Ml_bindings.nat_big_num_of_uint64 phdr.elf64_p_filesz) (if Nat_big_num.equal isec1.elf64_section_type sht_progbits then isec1.elf64_section_size else Nat_big_num.of_int 0)) - in - (* The new memsz is the virtual address end address of this section, - * minus the existing start vaddr of the phdr. - * Check that the new section begins after the old vaddr+memsz. *) - if Nat_big_num.less isec1.elf64_section_addr (Nat_big_num.add (Ml_bindings.nat_big_num_of_uint64 phdr.elf64_p_vaddr) (Ml_bindings.nat_big_num_of_uint64 phdr.elf64_p_memsz)) - then (*let _ = errln "vaddr went backwards" in*) None - else - let new_p_memsz = (Nat_big_num.add (Ml_bindings.nat_big_num_of_uint64 phdr.elf64_p_memsz) isec1.elf64_section_size) - in - let (one_if_zero : Nat_big_num.num -> Nat_big_num.num) = (fun n -> if Nat_big_num.equal n(Nat_big_num.of_int 0) then Nat_big_num.of_int 1 else n) - in - let new_p_align = (lcm (one_if_zero (Ml_bindings.nat_big_num_of_uint64 phdr.elf64_p_align)) (one_if_zero isec1.elf64_section_align)) - in - Some - { elf64_p_type = (Uint32.of_string (Nat_big_num.to_string new_p_type)) - ; elf64_p_flags = (Uint32.of_string (Nat_big_num.to_string new_p_flags)) - ; elf64_p_offset = (phdr.elf64_p_offset) - ; elf64_p_vaddr = (phdr.elf64_p_vaddr) - ; elf64_p_paddr = (phdr.elf64_p_paddr) - ; elf64_p_filesz = (Uint64.of_string (Nat_big_num.to_string new_p_filesz)) - ; elf64_p_memsz = (Uint64.of_string (Nat_big_num.to_string new_p_memsz)) - ; elf64_p_align = (Uint64.of_string (Nat_big_num.to_string new_p_align)) - }) - -let make_new_phdr isec1 t maxpagesize1 commonpagesize1:elf64_program_header_table_entry= - (let rounded_down_offset = (fun isec1 -> round_down_to commonpagesize1 isec1.elf64_section_offset) - in - let offset_round_down_amount = (fun isec1 -> Nat_big_num.sub_nat isec1.elf64_section_offset (rounded_down_offset isec1)) - in - let rounded_down_vaddr = (fun isec1 -> round_down_to commonpagesize1 isec1.elf64_section_addr) - in - let vaddr_round_down_amount = (fun isec1 -> Nat_big_num.sub_nat isec1.elf64_section_addr (rounded_down_vaddr isec1)) - in - { elf64_p_type = (Uint32.of_string (Nat_big_num.to_string t)) (** Type of the segment *) - ; elf64_p_flags = (Uint32.of_string (Nat_big_num.to_string (phdr_flags_from_section_flags isec1.elf64_section_flags isec1.elf64_section_name_as_string))) (** Segment flags *) - ; elf64_p_offset = (Uint64.of_string (Nat_big_num.to_string (rounded_down_offset isec1))) (** Offset from beginning of file for segment *) - ; elf64_p_vaddr = (Uint64.of_string (Nat_big_num.to_string (rounded_down_vaddr isec1))) (** Virtual address for segment in memory *) - ; elf64_p_paddr = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) (** Physical address for segment *) - ; elf64_p_filesz = (Uint64.of_string (Nat_big_num.to_string (if Nat_big_num.equal isec1.elf64_section_type sht_nobits then Nat_big_num.of_int 0 else Nat_big_num.add isec1.elf64_section_size (offset_round_down_amount isec1)))) (** Size of segment in file, in bytes *) - ; elf64_p_memsz = (Uint64.of_string (Nat_big_num.to_string ( Nat_big_num.add isec1.elf64_section_size (vaddr_round_down_amount isec1)))) (** Size of segment in memory image, in bytes *) - ; elf64_p_align = (Uint64.of_string (Nat_big_num.to_string (* isec.elf64_section_align *)maxpagesize1)) (** Segment alignment memory for memory and file *) - }) - -(*val make_load_phdrs : forall 'abifeature. natural -> natural -> annotated_memory_image 'abifeature -> list elf64_interpreted_section -> list elf64_program_header_table_entry*) -let make_load_phdrs maxpagesize1 commonpagesize1 img2 section_pairs_bare_sorted_by_address:(elf64_program_header_table_entry)list= -( - (* accumulate sections into the phdr *)let rev_list = (List.fold_left (fun accum_phdr_list -> (fun isec1 -> ( - (* Do we have a current phdr? *) - (match accum_phdr_list with - [] -> (* no, so make one *) - (*let _ = errln ("Starting the first LOAD phdr for section " ^ isec.elf64_section_name_as_string) - in*) - [make_new_phdr isec1 elf_pt_load maxpagesize1 commonpagesize1] - | current_phdr :: more -> - (* can we extend it with the current section? *) - (match maybe_extend_phdr current_phdr isec1 load_can_combine_flags with - None -> - (*let _ = errln ("Starting new LOAD phdr for section " ^ isec.elf64_section_name_as_string) - in*) - (make_new_phdr isec1 elf_pt_load maxpagesize1 commonpagesize1) :: (current_phdr :: more) - | Some phdr -> phdr :: more - ) - ) - ))) [] (List.filter (fun isec1 -> flag_is_set shf_alloc isec1.elf64_section_flags - && not (flag_is_set shf_tls isec1.elf64_section_flags)) section_pairs_bare_sorted_by_address)) - in - (*let _ = errln "Successfully made phdrs" - in*) - List.rev rev_list) - -(*val tls_extend: forall 'abifeature. abi 'abifeature -> abi 'abifeature*) -let tls_extend a:'abifeature abi= - ({ is_valid_elf_header = (a.is_valid_elf_header) - ; make_elf_header = (a.make_elf_header) - ; reloc = (a.reloc) - ; section_is_special = (a.section_is_special) - ; section_is_large = (a.section_is_large) - ; maxpagesize = (a.maxpagesize) - ; minpagesize = (a.minpagesize) - ; commonpagesize = (a.commonpagesize) - ; symbol_is_generated_by_linker = (a.symbol_is_generated_by_linker) - ; make_phdrs = (fun maxpagesize1 -> fun commonpagesize1 -> fun file_type -> fun img2 -> fun section_pairs_bare_sorted_by_address -> ( - let rev_list = (List.fold_left (fun accum_phdr_list -> (fun isec1 -> ( - (match accum_phdr_list with - [] -> - (*let _ = errln "Making a new TLS program header" in*) - [make_new_phdr isec1 elf_pt_tls maxpagesize1 commonpagesize1] - | current_phdr :: more -> - (match maybe_extend_phdr current_phdr isec1 tls_can_combine_flags with - None -> - (make_new_phdr isec1 elf_pt_tls maxpagesize1 commonpagesize1) :: (current_phdr :: more) - | Some phdr -> phdr :: more - ) - ) - ))) [] (List.filter (fun isec1 -> flag_is_set shf_alloc isec1.elf64_section_flags - && flag_is_set shf_tls isec1.elf64_section_flags) section_pairs_bare_sorted_by_address)) - in - List.rev_append (List.rev (a.make_phdrs maxpagesize1 commonpagesize1 file_type img2 section_pairs_bare_sorted_by_address)) (List.rev rev_list) - )) - ; max_phnum = (Nat_big_num.add(Nat_big_num.of_int 1) a.max_phnum) - ; guess_entry_point = (a.guess_entry_point) - ; pad_data = (a.pad_data) - ; pad_code = (a.pad_code) - ; generate_support = (a.generate_support) - ; concretise_support = (a.concretise_support) - ; get_reloc_symaddr = (a.get_reloc_symaddr) - }) - -(* We use these snappily-named functions in relocation calculations. *) - -(*val make_default_phdrs : forall 'abifeature. natural -> natural -> natural (* file type *) -> annotated_memory_image 'abifeature -> list elf64_interpreted_section -> list elf64_program_header_table_entry*) -let make_default_phdrs maxpagesize1 commonpagesize1 t img2 section_pairs_bare_sorted_by_address:(elf64_program_header_table_entry)list= -( - (* FIXME: do the shared object and dyn. exec. stuff too *)make_load_phdrs maxpagesize1 commonpagesize1 img2 section_pairs_bare_sorted_by_address) - -(*val find_start_symbol_address : forall 'abifeature. Ord 'abifeature, AbiFeatureTagEquiv 'abifeature => annotated_memory_image 'abifeature -> maybe natural*) -let find_start_symbol_address dict_Basic_classes_Ord_abifeature dict_Abi_classes_AbiFeatureTagEquiv_abifeature img2:(Nat_big_num.num)option= -( - (* Do we have a symbol called "_start"? *)let all_defs = (Memory_image_orderings.defined_symbols_and_ranges - dict_Basic_classes_Ord_abifeature dict_Abi_classes_AbiFeatureTagEquiv_abifeature img2) - in - let get_entry_point = (fun (maybe_range, symbol_def) -> - if symbol_def.def_symname = "_start" - then Some (maybe_range, symbol_def) - else None - ) - in - let all_entry_points = (Lem_list.mapMaybe get_entry_point all_defs) - in - (match all_entry_points with - [(maybe_range, symbol_def)] -> - (match maybe_range with - Some (el_name, (el_off, len)) -> - (match Pmap.lookup el_name img2.elements with - None -> failwith ("_start symbol defined in nonexistent element `" ^ (el_name ^ "'")) - | Some el_rec -> - (match el_rec.startpos with - None -> (*let _ = Missing_pervasives.errln "warning: saw `_start' in element with no assigned address" in *)None - | Some x -> (* success! *) Some ( Nat_big_num.add x el_off) - ) - ) - | _ -> (*let _ = Missing_pervasives.errln "warning: `_start' symbol with no range" in*) None - ) - | [] -> (* no _start symbol *) None - | _ -> (*let _ = Missing_pervasives.errln ("warning: saw multiple `_start' symbols: " ^ - (let (ranges, defs) = unzip all_entry_points in show ranges)) in *)None - )) - -(*val pad_zeroes : natural -> list byte*) -let pad_zeroes n:(char)list= (replicate0 n (Char.chr (Nat_big_num.to_int (Nat_big_num.of_int 0)))) - -(*val pad_0x90 : natural -> list byte*) -let pad_0x90 n:(char)list= (replicate0 n (Char.chr (Nat_big_num.to_int ( Nat_big_num.mul(Nat_big_num.of_int 9)(Nat_big_num.of_int 16))))) - -(* null_abi captures ABI details common to all ELF-based, System V-based systems. - * HACK: for now, specialise to 64-bit ABIs. *) -(*val null_abi : abi any_abi_feature*) -let null_abi:(any_abi_feature)abi= ({ - is_valid_elf_header = is_valid_elf64_header - ; make_elf_header = (make_elf64_header elf_data_2lsb elf_osabi_none(Nat_big_num.of_int 0) elf_ma_none) - ; reloc = noop_reloc - ; section_is_special = elf_section_is_special - ; section_is_large = (fun s -> (fun f -> false)) - ; maxpagesize = (Nat_big_num.mul (Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 256))(Nat_big_num.of_int 4096)) (* 2MB; bit of a guess, based on gdb and prelink code *) - ; minpagesize =(Nat_big_num.of_int 1024) (* bit of a guess again *) - ; commonpagesize =(Nat_big_num.of_int 4096) - ; symbol_is_generated_by_linker = (fun symname -> symname = "_GLOBAL_OFFSET_TABLE_") - ; make_phdrs = make_default_phdrs - ; max_phnum =(Nat_big_num.of_int 2) - ; guess_entry_point = - (find_start_symbol_address - instance_Basic_classes_Ord_Abis_any_abi_feature_dict - instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict) - ; pad_data = pad_zeroes - ; pad_code = pad_zeroes - ; generate_support = ( (* fun _ -> *)fun _ -> get_empty_memory_image ()) - ; concretise_support = (fun img2 -> img2) - ; get_reloc_symaddr = - (default_get_reloc_symaddr - instance_Basic_classes_Ord_Abis_any_abi_feature_dict - instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict) - }) - -(*val got_entry_ordering : (string * maybe symbol_definition) -> (string * maybe symbol_definition) -> Basic_classes.ordering*) -let got_entry_ordering (s1, md1) (s2, md2):int= (compare s1 s2) (* FIXME *) - -let is_ifunc_def:(symbol_definition)option ->bool= (fun maybe_def -> -(match maybe_def with - None -> false - | Some d -> Nat_big_num.equal (get_elf64_symbol_type d.def_syment) stt_gnu_ifunc -)) - -let amd64_reloc_needs_got_slot:'a ->reloc_site ->(symbol_definition)option ->bool= (fun symref -> fun rr -> fun maybe_def -> - if ( Pset.mem(get_elf64_relocation_a_type rr.ref_relent)(Pset.from_list Nat_big_num.compare [ - r_x86_64_got32; r_x86_64_gotpcrel; r_x86_64_gottpoff; r_x86_64_gotoff64; r_x86_64_gotpc32 (* ; r_x86_64_gotpc32_tlsdesc *) - ])) then - true - else if is_ifunc_def maybe_def - then - (* This reference is bound to a STT_GNU_IFUNC definition. - * What now needs to happen is as follows. - * - we ensure that a GOT entry is generated for this symbol (we do this here); - * - we ensure that a PLT entry (specifically .iplt) is generated for the symbol (Below); - * - on making the GOT, we also generate a .rela.plt relocation record covering the GOT slot; - * - when applying the relocation, of whatever kind, the address of the PLT slot - * is the address input to the calculation - * - the code marked by the STT_GNU_IFUNC symbol definition is not the function - * to call; it's the function that calculates the address of the function to call! - * this becomes the addend of the R_X86_64_IRELATIVE Elf64_Rela marking the GOT slot - * - note that for static linking, the GOT is usually pre-filled (cf. dynamically when it is filled by JUMP_SLOT relocs). - * ... but our GOT entries *must* have corresponding R_X86_64_IRELATIVEs generated - *) - true - else false) - - -let amd64_reloc_needs_plt_slot (symref : symbol_reference_and_reloc_site) rr maybe_def ref_is_statically_linked:bool= - (if ( Pset.mem(get_elf64_relocation_a_type rr.ref_relent)(Pset.from_list Nat_big_num.compare [ - r_x86_64_plt32 (* NOTE: when generating shared libs, it starts to matter - * where the definition is -- anything that is locally interposable - * or undefined will need a slot. See amd64_get_reloc_symaddr. *) - ])) then - not (ref_is_statically_linked rr) - else if is_ifunc_def maybe_def - then - true - else - (* not a PLT ref *) - false) - -let amd64_find_got_label_and_element img2:((string*(symbol_definition)option)list*element)option= - ((match Pmap.lookup ".got" img2.elements with - None -> (* got no GOT? okay... *) None - | Some got_el -> - (* Find the GOT tag. *) - let tags_and_ranges = (Multimap.lookupBy0 - (instance_Basic_classes_Ord_Memory_image_range_tag_dict - instance_Basic_classes_Ord_Abis_any_abi_feature_dict) (instance_Basic_classes_Ord_Maybe_maybe_dict - (instance_Basic_classes_Ord_tup2_dict - Lem_string_extra.instance_Basic_classes_Ord_string_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_Num_natural_dict - instance_Basic_classes_Ord_Num_natural_dict))) instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) (Memory_image_orderings.tagEquiv - instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict) (AbiFeature(Amd64AbiFeature(Abi_amd64.GOT0([])))) img2.by_tag) - in - (match tags_and_ranges with - [] -> failwith "error: GOT element but no ABI feature GOT tag" - | [(AbiFeature(Amd64AbiFeature(Abi_amd64.GOT0(l))), _)] -> Some (l, got_el) - | _ -> failwith ("multiple GOT elements/tags") - ) - )) - -let amd64_find_plt_label_and_element img2:((string*(symbol_definition)option*(any_abi_feature)plt_entry_content_fn)list*element)option= - ((match Pmap.lookup ".plt" img2.elements with - None -> (* got no PLT? okay... *) None - | Some plt_el -> - (* Find the PLT tag. *) - let tags_and_ranges = (Multimap.lookupBy0 - (instance_Basic_classes_Ord_Memory_image_range_tag_dict - instance_Basic_classes_Ord_Abis_any_abi_feature_dict) (instance_Basic_classes_Ord_Maybe_maybe_dict - (instance_Basic_classes_Ord_tup2_dict - Lem_string_extra.instance_Basic_classes_Ord_string_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_Num_natural_dict - instance_Basic_classes_Ord_Num_natural_dict))) instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) (Memory_image_orderings.tagEquiv - instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict) (AbiFeature(Amd64AbiFeature(Abi_amd64.PLT0([])))) img2.by_tag) - in - (match tags_and_ranges with - [] -> failwith "error: PLT element but no ABI feature PLT tag" - | [(AbiFeature(Amd64AbiFeature(Abi_amd64.PLT0(l))), _)] -> Some (l, plt_el) - | _ -> failwith ("multiple PLT elements/tags") - ) - )) - -let got_slot_index_for_symname dict_Basic_classes_Eq_a symname got_label:(int)option= - (Lem_list.find_index (fun (s, _) -> - dict_Basic_classes_Eq_a.isEqual_method s symname) got_label) - -(*val amd64_get_reloc_symaddr : symbol_definition -> annotated_memory_image any_abi_feature -> maybe reloc_site -> natural*) -let amd64_get_reloc_symaddr the_input_def output_img maybe_reloc1:Nat_big_num.num= -( - (* The default implementation simply looks up a "matching" symbol in the output image - * and calculates its address. - * - * That's normally fine, even for via-GOT references since their calculations don't - * use the symaddr. For via-PLT references, we need to use the PLT slot address. - * HMM. Isn't this duplicating the role of functions like amd64_plt_slot_addr? - - * Recall that we created this get_reloc_symaddr mechanism to deal with IFUNC symbols. - * With an IFUNC symbol, we reference it simply using a PC32 relocation, but the address - * that gets filled in isn't the IFUNC address; it's the corresponding PLT slot. - * HMM: does this happen for other PC32 references? If so, we'll need this mechanism - * there. And it certainly does, because relocatable object code never uses PLT32 - * relocs. - * - * I had previously tried to handle this issue in mark_fate_of_relocs, using the - * 1-argument ApplyReloc(_) and MakePIC to encode the "replacement". But at that stage, - * which is ABI-independent and happens before address assignment?, we can't know enough. - *) - (* match bound_def_in_input with - Nothing -> 0 - | Just the_input_def -> *)if is_ifunc_def (Some(the_input_def)) - then - (* We need to return the address of the "matching" PLT slot. - * PLT label entries are (symname, maybe_def, content_fn). *) - (match amd64_find_plt_label_and_element output_img with - None -> failwith "error: ifunc but no PLT" - | Some (l, plt_el) -> - (match Lem_list.find_index (fun (symname, _, _) -> symname = the_input_def.def_symname) l with - (* FIXME: using symnames seems wrong *) - Some idx1 -> - (match plt_el.startpos with - Some addr -> Nat_big_num.add addr (Nat_big_num.mul (Nat_big_num.of_int idx1)(Nat_big_num.of_int 16)) (* size of a PLT entry *) - | None -> failwith "error: PLT has no address assigned" - ) - | None ->Nat_big_num.of_int 0 - ) - ) - else default_get_reloc_symaddr - instance_Basic_classes_Ord_Abis_any_abi_feature_dict instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict the_input_def output_img maybe_reloc1) - (* end *) - -(* *) -(*val amd64_generate_support : (* list (list reloc_site_resolution) -> *) list (string * annotated_memory_image any_abi_feature) -> annotated_memory_image any_abi_feature*) -let amd64_generate_support (* reloc_resolution_lists *) input_fnames_and_imgs:(any_abi_feature)annotated_memory_image= -( - (* We generate a basic GOT. At the moment we can only describe the GOT - * contents abstractly, not as its binary content, because addresses - * have not yet been fixed. - * - * To do this, we create a set of Abi_amd64.GOTEntry records, one for - * each distinct symbol that is referenced by one or more GOT-based relocations. - * To enumerate these, we look at all the symbol refs in the image. - *)let ref_is_statically_linked = (fun _ -> true) - in - let (fnames, input_imgs) = (List.split input_fnames_and_imgs) - in - let tags_and_ranges_by_image = (Lem_list.mapi (fun i -> fun (fname1, img2) -> - (i, fname1, Multimap.lookupBy0 - (instance_Basic_classes_Ord_Memory_image_range_tag_dict - instance_Basic_classes_Ord_Abis_any_abi_feature_dict) (instance_Basic_classes_Ord_Maybe_maybe_dict - (instance_Basic_classes_Ord_tup2_dict - Lem_string_extra.instance_Basic_classes_Ord_string_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_Num_natural_dict - instance_Basic_classes_Ord_Num_natural_dict))) instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) (Memory_image_orderings.tagEquiv - instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict) (SymbolRef(null_symbol_reference_and_reloc_site)) img2.by_tag) - ) input_fnames_and_imgs) - in - let refs_via_got = (list_concat_map (fun (i, fname1, tags_and_ranges) -> Lem_list.mapMaybe (fun (tag, maybe_range) -> (match tag with - SymbolRef(symref) -> - (* Is this ref a relocation we're going to apply, and does it reference the GOT? *) - (match (symref.maybe_reloc, symref.maybe_def_bound_to) with - (None, _) -> None - | (Some rr, Some(ApplyReloc, maybe_def)) -> - if amd64_reloc_needs_got_slot symref rr maybe_def then - (*let _ = errln ("Saw a via-GOT symbol reference: to `" ^ symref.ref.ref_symname ^ "' coming from linkable " ^ (show i) ^ " (" ^ - fname ^ "), logically from section " ^ (show rr.ref_src_scn)) in *) - Some (symref.ref.ref_symname, maybe_def) - else None - | (Some rr, Some(makePIC0, maybe_def)) -> failwith "FIXME: PIC support please" - ) - | _ -> failwith "impossible: reloc site tag is not a SymbolRef" - )) tags_and_ranges) tags_and_ranges_by_image) - in - let (symnames, maybe_defs) = (List.split refs_via_got) - in - (*let _ = errln ("GOT includes defs with names: " ^ (show (Set_extra.toList (Set.fromList symnames)))) - in*) - let got_pairs_set = (Pset.from_list (pairCompare compare (maybeCompare compare)) refs_via_got) - in - let got_defs_set = (Pset.from_list (maybeCompare compare) maybe_defs) - in - (* This is where we fix the order of the GOT entries. *) - let got_pairs_list = (Pset.elements got_pairs_set) - in - let got_idx_and_maybe_def_by_symname_map = (Lem_map.fromList - (Lem_map.instance_Map_MapKeyType_var_dict - instance_Basic_classes_SetType_var_dict) (mapi (fun slot_idx -> fun (symname, maybe_def) -> (symname, (slot_idx, maybe_def))) got_pairs_list)) - in - let got_ifunc_set = (let x2 =(Pset.from_list (maybeCompare compare) - []) in Pset.fold - (fun maybe_d x2 -> - if is_ifunc_def maybe_d then Pset.add maybe_d x2 else x2) got_defs_set - x2) - in - (* Quirk: what if we have the same def appearing under two different symnames? - * This shouldn't happen, at present. - * What if we have the same symname related to two different defs? This also - * shouldn't happen, because only global symbols go in the GOT, so we don't have - * to worry about local symbols with the same name as another symbol. But still, it - * could plausibly happen in some situations with weird symbol visibilities or binding. *) - (* if Set.size pairs_set <> Set.size defs_set then - failwith "something quirky going on with GOT symbol defs and their names" - else *) -(* let name_def_pairs = List.foldl (fun acc -> fun (idx, symname, (maybe_range, rr)) -> - Set.insert ( - - symname, (match rr.maybe_def_bound_to with - Map.lookup symname acc with - Nothing -> [item] - | Just l -> item :: l - end) acc) {} refs_via_got - in *) - let got_nentries = (Nat_big_num.of_int (Pset.cardinal got_pairs_set)) - in - let got_entrysize =(Nat_big_num.of_int 8) - in - (* We also need a PLT... sort of. We need a way to resolve via-PLT relocs. - * But we might do so without actually creating a (non-zero-length) PLT. - * Again, this is to accommodate the sorts of optimisations the GNU linker does. - * - * Note that every PLT entry has a corresponding GOT entry. Here we are simply - * enumerating the via-PLT relocs that imply a PLT entry. We look their GOT - * slots up later, by symbol name. *) - let refs_via_plt = (list_concat_map (fun (i, fname1, tags_and_ranges) -> Lem_list.mapMaybe (fun (tag, maybe_range) -> (match tag with - SymbolRef(symref) -> - (* Is this ref a relocation we're going to apply, and does it reference the GOT? *) - (match (symref.maybe_reloc, symref.maybe_def_bound_to) with - (None, _) -> None - | (Some rr, Some(ApplyReloc, maybe_def)) -> - if amd64_reloc_needs_plt_slot symref rr maybe_def ref_is_statically_linked - then - (*let _ = if is_ifunc_def maybe_def then - (* we ensure that a PLT entry (specifically .iplt) is generated for the symbol *) - errln ("Saw a reference to IFUNC symbol `" ^ symref.ref.ref_symname ^ "'; ref is coming from linkable " ^ (show i) ^ " (" ^ - fname ^ "), relent idx " ^ (show rr.ref_rel_idx) ^ " logically from section " ^ (show rr.ref_src_scn) ) - else - errln ("Saw a via-PLT symbol reference: to `" ^ symref.ref.ref_symname ^ "' coming from linkable " ^ (show i) ^ " (" ^ - fname ^ "), relent idx " ^ (show rr.ref_rel_idx) ^ " logically from section " ^ (show rr.ref_src_scn) ^ - match maybe_def with Just _ -> ", with definition" | Nothing -> ", not bound to anything" end - ) - in*) - Some(symref.ref.ref_symname, maybe_def) - else None - | (Some rr, Some(makePIC0, maybe_def)) -> failwith "FIXME: PIC support please" - ) - | _ -> failwith "impossible: reloc site tag is not a SymbolRef" - )) tags_and_ranges) tags_and_ranges_by_image) - in - (*let _ = errln ("Saw " ^ (show (length refs_via_plt)) ^ " relocations of a via-PLT type") - in*) - (* account for the optimisations we did on GOT slots *) - let refs_via_plt_having_got_slot = (Lem_list.mapMaybe (fun (symname, _) -> - (match Pmap.lookup symname got_idx_and_maybe_def_by_symname_map with - Some(idx1, maybe_d) -> Some (symname, idx1, maybe_d) - | None -> None - ) - ) refs_via_plt) - in - (*let _ = errln ("Saw " ^ (show (length refs_via_plt_having_got_slot)) ^ " relocations of a via-PLT type where we instantiated a GOT slot for the symbol") - in*) - let (plt_symnames, plt_got_idxs, plt_ref_bound_to_maybe_defs) = (unzip3 refs_via_plt_having_got_slot) - in - let plt_symnames_excluding_header = (Pset.elements ((Pset.from_list compare plt_symnames))) - in - (*let _ = errln ("PLT symnames: " ^ (show plt_symnames_excluding_header)) - in*) - let n_iplt_entries = (Pset.cardinal got_ifunc_set) - (* The content of the IPLT entries depends on the address assignment of GOT slots - * and the IFUNCs that they reference. We need to reserve space for them here, though. *) - in - (*let _ = errln ("We think there should be " ^ (show n_iplt_entries) ^ " PLT entries due to references to IFUNC symbols") - in*) - (* let got_entries_referencing_functions = (List.filter (fun (symname, maybe_def) -> - match def with - Just d -> d.def_syment - | Nothing -> false - end) refs_via_got) - in *) - let plt_needs_header_entry = ((List.length plt_symnames_excluding_header) > n_iplt_entries) - in - (*let _ = errln ("PLT needs header entry? " ^ (show plt_needs_header_entry)) - in*) - let total_n_plt_entries = (Nat_big_num.add (if plt_needs_header_entry then Nat_big_num.of_int 1 else Nat_big_num.of_int 0) (Missing_pervasives.length plt_symnames_excluding_header)) - in - (*let _ = errln ("PLT total entry count: " ^ (show total_n_plt_entries)) - in*) - let new_by_range =(Pset.from_list (pairCompare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))) compare) [ - (Some(".plt", (Nat_big_num.of_int 0, Nat_big_num.mul(Nat_big_num.of_int 16) total_n_plt_entries)), AbiFeature(Amd64AbiFeature(Abi_amd64.PLT0( - (* header content fn *) - (* the header entry is required only for dynamic linking, which is not supported yet *) - (* (if plt_needs_header_entry then - ("", Nothing, (((fun (got_base_addr : natural) -> fun (plt_base_addr : natural) -> - (0, [byte_of_natural 0; byte_of_natural 0; byte_of_natural 0; byte_of_natural 0; - byte_of_natural 0; byte_of_natural 0; byte_of_natural 0; byte_of_natural 0; - byte_of_natural 0; byte_of_natural 0; byte_of_natural 0; byte_of_natural 0; - byte_of_natural 0; byte_of_natural 0; byte_of_natural 0; byte_of_natural 0]))) : plt_entry_content_fn any_abi_feature)) - else ("", Nothing, (((fun (got_base_addr : natural) -> fun (plt_base_addr : natural) -> (0, []))) : plt_entry_content_fn any_abi_feature)) - ) - ++ *) ( - mapi (fun plt_entry_idx_not_counting_header -> (fun symname -> - (* We want to label the PLT entry with a function that - * - accepts the PLT base address, the GOT base address and the GOT slot number; - * - closure-captures whatever else it needs (whether we're inserting a PLT header); - * - yields the *full contents of the PLT entry* before relocation. - * - recall that PLT entries might be "header" (the special one at the start), - * "normal" (to be relocated with R_X86_64_JUMP_SLOT) - * or "irelative" (to be relocated with R_X86_64_IRELATIVE). - * Q. Why are R_X86_64_JUMP_SLOT necessary? - * The PLT entries are doing relative addressing, and - * the offset to the GOT entry is known at link time, - * so the linker should be able to fill them in. In - * fact, it does. HMM. Understand this better. *) - (* What is the GOT slot number? *) - let (got_slot_idx, maybe_def) = ((match Pmap.lookup symname got_idx_and_maybe_def_by_symname_map with - Some(idx1, maybe_d) -> (Nat_big_num.of_int idx1, maybe_d) - | None -> failwith ("GOT does not contain symbol `" ^ (symname ^ "' required by PLT entry")) - )) - in - (symname, maybe_def, ((fun (got_base_addr : Nat_big_num.num) -> fun (plt_base_addr : Nat_big_num.num) -> - (* Okay, now we can generate the entry. NOTE that we're lexically still in generate_support, - * but we'll be called from concretise_support. The code that generates the header - * entry is actually in concretise_support. - * - * If the entry is a normal entry, it looks like - * - 0x0000000000400410 <+0>: ff 25 02 0c 20 00 jmpq *0x200c02(%rip) # 0x601018 <puts@got.plt> - 0x0000000000400416 <+6>: 68 00 00 00 00 pushq $0x0 - 0x000000000040041b <+11>: e9 e0 ff ff ff jmpq 0x400400 - * - * If the entry is an irelative entry, it looks like - * - 400350: ff 25 02 fd 2b 00 jmpq *0x2bfd02(%rip) # 6c0058 <_GLOBAL_OFFSET_TABLE_+0x58> - 400356: 68 00 00 00 00 pushq $0x0 - 40035b: e9 00 00 00 00 jmpq 400360 <check_one_fd.part.0> - - * ... i.e. basically the same but the pushq and jmpq have literal-zero args (they're not used). - *) - let this_plt_slot_base_addr = (Nat_big_num.add plt_base_addr (Nat_big_num.mul(Nat_big_num.of_int 16) ( - Nat_big_num.add(Nat_big_num.of_int plt_entry_idx_not_counting_header) (if plt_needs_header_entry then Nat_big_num.of_int 1 else Nat_big_num.of_int 0)))) - in - (*let _ = Missing_pervasives.errln ("PLT slot base address for symname `" ^ symname ^ "': 0x" ^ - (hex_string_of_natural this_plt_slot_base_addr)) - in*) - let got_slot_addr = (Nat_big_num.add got_base_addr (Nat_big_num.mul(Nat_big_num.of_int 8) got_slot_idx)) - in - (*let _ = Missing_pervasives.errln ("GOT slot address for symname `" ^ symname ^ "' (idx " ^ (show got_slot_idx) ^ "): 0x" ^ - (hex_string_of_natural got_slot_addr)) - in*) - let maybe_header_entry_address = (if plt_needs_header_entry then Some(plt_base_addr) else None) - in - let offset_to_got_slot = (Nat_big_num.sub ( got_slot_addr) (( Nat_big_num.add this_plt_slot_base_addr(Nat_big_num.of_int 6)))) - in - (*let _ = Missing_pervasives.errln ("PLT's PC-relative index to GOT slot for symname `" ^ symname ^ "' (GOT idx " ^ (show got_slot_idx) ^ ") is (decimal)" ^ - (show offset_to_got_slot)) - in*) - let content_bytes = - (List.rev_append (List.rev (List.rev_append (List.rev (List.rev_append (List.rev (List.rev_append (List.rev (List.rev_append (List.rev [Char.chr (Nat_big_num.to_int (Nat_big_num.of_int 255)); Char.chr (Nat_big_num.to_int (Nat_big_num.of_int 37))]) (* offset to the GOT entry, from the *next* instruction start, signed 32-bit LE *)(to_le_signed_bytes(Nat_big_num.of_int 4) offset_to_got_slot))) [Char.chr (Nat_big_num.to_int (Nat_big_num.of_int 104))])) (* plt slot number not including header, 32-bit LE *)(to_le_unsigned_bytes(Nat_big_num.of_int 4) ((Nat_big_num.of_int plt_entry_idx_not_counting_header))))) [Char.chr (Nat_big_num.to_int (Nat_big_num.of_int 233))])) (to_le_signed_bytes(Nat_big_num.of_int 4) ( - if is_ifunc_def maybe_def - then Nat_big_num.of_int 0 - else (match maybe_header_entry_address with - None -> failwith "normal PLT entry but no PLT header!" - | Some header_entry_address -> Nat_big_num.sub ( header_entry_address) (( Nat_big_num.add this_plt_slot_base_addr(Nat_big_num.of_int 16))) - ) - ))) - in - (*let _ = errln ("Created a PLT entry consisting of " ^ (show (length content_bytes)) ^ " bytes.") - in*) - (this_plt_slot_base_addr, content_bytes) - (* - match maybe_def with - Nothing -> 0 - | Just sd -> - match Memory_image_orderings.find_defs_matching sd img with - [] -> failwith ("no matching definitions for PLT entry named " ^ symname) - | [(Just(def_el_name, (def_start, def_len)), d)] -> - match element_and_offset_to_address (def_el_name, def_start) img with - Nothing -> failwith ("PLT: no address for definition offset in element " ^ def_el_name) - | Just x -> - let _ = errln ("PLT slot for symbol `" ^ symname ^ - "' calculated at (non-PLT) address 0x" ^ (hex_string_of_natural x) ^ - " (offset 0x" ^ (hex_string_of_natural def_start) ^ " in element " ^ def_el_name ^ ")") - in - x - end - | _ -> failwith ("multiple matching definitions for PLT entry named " ^ symname) - end - end - *) - - ) : any_abi_feature plt_entry_content_fn)) - )) - plt_symnames) - ))) - ) - ; (Some(".plt", (Nat_big_num.of_int 0, Nat_big_num.mul(Nat_big_num.of_int 16) total_n_plt_entries)), FileFeature(ElfSection(Nat_big_num.of_int 1, - { elf64_section_name =(Nat_big_num.of_int 0) (* ignored *) - ; elf64_section_type = sht_progbits - ; elf64_section_flags = shf_alloc - ; elf64_section_addr =(Nat_big_num.of_int 0) (* ignored -- covered by element *) - ; elf64_section_offset =(Nat_big_num.of_int 0) (* ignored -- will be replaced when file offsets are assigned *) - ; elf64_section_size = (Nat_big_num.mul(Nat_big_num.of_int 16) total_n_plt_entries) (* ignored? NO, we use it in linker_script to avoid plumbing through the element record *) - ; elf64_section_link =(Nat_big_num.of_int 0) - ; elf64_section_info =(Nat_big_num.of_int 0) - ; elf64_section_align =(Nat_big_num.of_int 16) - ; elf64_section_entsize =(Nat_big_num.of_int 16) - ; elf64_section_body = Byte_sequence.empty (* ignored *) - ; elf64_section_name_as_string = ".plt" - } - ))) - (* For each GOT entry that corresponds to a thread-local symbol, we also need to - * generate a relocation record. HMM. These new relocation records are ones we don't - * yet have decisions for. That might be a problem. - * - * In fact, this approach is not appropriate for static linking. Just put the offsets - * in there when we concretise the GOT. Something like this will be good for - * dynamic linking, though. At the moment, creating a SymbolRef at this stage - * is problematic because it's not in the bindings list. When we generate shared - * objects, we'll have to revisit that code. *) - (* (Just(".got", (i * got_entrysize, 8)), SymbolRef( <| - ref = <| ref_symname = symname - ; ref_syment = sd.def_syment - ; ref_sym_scn = 0 - ; ref_sym_idx = 0 - |> - ; maybe_def_bound_to = Just(ApplyReloc, Just sd) - ; maybe_reloc = Just( - <| - ref_relent = - <| elf64_ra_offset = elf64_addr_of_natural 0 - ; elf64_ra_info = elf64_xword_of_natural r_x86_64_tpoff64 - ; elf64_ra_addend = elf64_sxword_of_integer 0 - |> - ; ref_rel_scn = 0 - ; ref_rel_idx = 0 - ; ref_src_scn = 0 - |> - ) - |>)) - | forall ((i, symname, sd) IN (Set.fromList (mapMaybei (fun i -> fun (symname, maybe_def) -> - match maybe_def with Nothing -> Nothing | Just sd -> Just(i, symname, sd) end) refs_via_got))) - | get_elf64_symbol_type sd.def_syment = stt_tls - *) - ; (Some(".got", (Nat_big_num.of_int 0, Nat_big_num.mul got_nentries got_entrysize)), AbiFeature(Amd64AbiFeature(Abi_amd64.GOT0(got_pairs_list)))) - ; (Some(".got", (Nat_big_num.of_int 0, Nat_big_num.mul got_nentries got_entrysize)), FileFeature(ElfSection(Nat_big_num.of_int 2, - { elf64_section_name =(Nat_big_num.of_int 0) (* ignored *) - ; elf64_section_type = sht_progbits - ; elf64_section_flags = (Nat_big_num.bitwise_or shf_write shf_alloc) - ; elf64_section_addr =(Nat_big_num.of_int 0) (* ignored -- covered by element *) - ; elf64_section_offset =(Nat_big_num.of_int 0) (* ignored -- will be replaced when file offsets are assigned *) - ; elf64_section_size = (Nat_big_num.mul got_nentries got_entrysize) (* ignored? NO, we use it in linker_script to avoid plumbing through the element record *) - ; elf64_section_link =(Nat_big_num.of_int 0) - ; elf64_section_info =(Nat_big_num.of_int 0) - ; elf64_section_align =(Nat_big_num.of_int 8) - ; elf64_section_entsize = got_entrysize - ; elf64_section_body = Byte_sequence.empty (* ignored *) - ; elf64_section_name_as_string = ".got" - } - ))) - ; (* FIXME: I've a feeling _GLOBAL_OFFSET_TABLE_ generally doesn't mark the *start* of the GOT; - * it's some distance in. What about .got.plt? *) - (Some(".got", (Nat_big_num.of_int 0, Nat_big_num.mul got_nentries got_entrysize)), SymbolDef({ - def_symname = "_GLOBAL_OFFSET_TABLE_" - ; def_syment = ({ elf64_st_name = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) (* ignored *) - ; elf64_st_info = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) (* FIXME *) - ; elf64_st_other = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) (* FIXME *) - ; elf64_st_shndx = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 1))) - ; elf64_st_value = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) (* ignored *) - ; elf64_st_size = (Uint64.of_string (Nat_big_num.to_string ( Nat_big_num.mul got_nentries got_entrysize))) (* FIXME: start later, smaller size? zero size? *) - }) - ; def_sym_scn =(Nat_big_num.of_int 1) - ; def_sym_idx =(Nat_big_num.of_int 1) - ; def_linkable_idx =(Nat_big_num.of_int 0) - })) - ; (Some(".rela.iplt", (Nat_big_num.of_int 0, (* size of an Elf64_Rela *) Nat_big_num.mul(Nat_big_num.of_int 24) (Nat_big_num.of_int n_iplt_entries))), FileFeature(ElfSection(Nat_big_num.of_int 3, - { elf64_section_name =(Nat_big_num.of_int 0) (* ignored *) - ; elf64_section_type = sht_rela - ; elf64_section_flags = (Nat_big_num.bitwise_or shf_alloc shf_info_link) - ; elf64_section_addr =(Nat_big_num.of_int 0) (* ignored -- covered by element *) - ; elf64_section_offset =(Nat_big_num.of_int 0) (* ignored -- will be replaced when file offsets are assigned *) - ; elf64_section_size = ( (* size of an Elf64_Rela *)Nat_big_num.mul(Nat_big_num.of_int 24) (Nat_big_num.of_int n_iplt_entries)) (* ignored? NO, we use it in linker_script to avoid plumbing through the element record *) - ; elf64_section_link =(Nat_big_num.of_int 0) - ; elf64_section_info =(Nat_big_num.of_int (* FIXME: want this to be the PLT section shndx *)0) - ; elf64_section_align =(Nat_big_num.of_int 8) - ; elf64_section_entsize =(Nat_big_num.of_int 24) - ; elf64_section_body = Byte_sequence.empty (* ignored *) - ; elf64_section_name_as_string = ".rela.iplt" - } - ))) - ]) - in - { elements = (Pmap.add ".got" { - startpos = None - ; length1 = (Some ( Nat_big_num.mul got_nentries got_entrysize)) - ; contents = ([]) - } (Pmap.add ".plt" { - startpos = None - ; length1 = (let len = (Nat_big_num.mul(Nat_big_num.of_int 16) total_n_plt_entries) in - (*let _ = errln ("PLT length in element: " ^ (show len) ^ " bytes") - in *) Some ( Nat_big_num.mul(Nat_big_num.of_int 16) total_n_plt_entries)) - ; contents = ([]) - } (Pmap.add ".rela.iplt" { - startpos = None - ; length1 = (Some ( (* size of an Elf64_Rela *) Nat_big_num.mul(Nat_big_num.of_int 24) (Nat_big_num.of_int n_iplt_entries))) - ; contents = ([]) - } (Pmap.empty compare) - ))) - ; by_tag = (by_tag_from_by_range - (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) instance_Basic_classes_SetType_var_dict new_by_range) - ; by_range = new_by_range - }) - -(*val amd64_concretise_support : annotated_memory_image any_abi_feature -> annotated_memory_image any_abi_feature*) -let amd64_concretise_support orig_img:(any_abi_feature)annotated_memory_image= -( - (*let _ = errln "Concretising amd64 ABI support structures" - in*) - (* Fill in the GOT contents. *)(match amd64_find_got_label_and_element orig_img with - None -> orig_img (* no GOT, but that's okay *) - | Some (got_l, got_el) -> - let got_base_addr = ((match got_el.startpos with - Some a -> a - | None -> failwith "GOT has no address assigned" - )) - in - let got_entry_bytes_for = (fun img2 -> fun symname -> fun maybe_def -> fun plt_l -> fun maybe_plt_el -> (match maybe_def with - None -> replicate0(Nat_big_num.of_int 8) (Char.chr (Nat_big_num.to_int (Nat_big_num.of_int 0))) - | Some sd -> - (* What should the GOT slot be initialized to point to? - * If there's a PLT entry, we should point to that + 6, - * i.e. the second instruction. - * - * If there's not, then it might be a thread-local. *) - (match Lem_list.find_index (fun (plt_symname, _, _) -> symname = plt_symname) plt_l with - Some plt_slot_idx -> - (match maybe_plt_el with - None -> failwith "GOT slot with PLT entry but no PLT element" - | Some plt_el -> - (match plt_el.startpos with - Some addr -> natural_to_le_byte_list_padded_to(Nat_big_num.of_int 8) ( Nat_big_num.add (Nat_big_num.add addr ( Nat_big_num.mul(Nat_big_num.of_int plt_slot_idx)(Nat_big_num.of_int 16)))(Nat_big_num.of_int 6)) - | None -> failwith ("no PLT!") - ) - ) - | None -> - (* Just look for a definition. *) - (match Memory_image_orderings.find_defs_matching - instance_Basic_classes_Ord_Abis_any_abi_feature_dict instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict sd img2 with - [] -> failwith ("no matching definitions for GOT entry named " ^ symname) - | [(Some(def_el_name, (def_start, def_len)), d)] -> - (match element_and_offset_to_address (def_el_name, def_start) img2 with - None -> failwith ("no address for definition offset in element " ^ def_el_name) - | Some x -> - (* If sd is a TLS symbol, we want its offset from the *end* of the - * TLS segment. *) - (* FIXME: factor out this logic so that it lives in the TLS ABI spec. *) - if Nat_big_num.equal (get_elf64_symbol_type sd.def_syment) stt_tls then - (* FIXME: the right way to do this is to mark the segments in the image - * *first*. They can't have ranges, because they span many elements, - * but they can have vaddr ranges as arguments. *) - let offs = (i2n_signed( 64) (Nat_big_num.sub(Nat_big_num.of_int 0)(Nat_big_num.of_int 8))) - in - (*let _ = errln ("GOT slot for TLS symbol `" ^ symname ^ - "' created containing offset 0x" ^ (hex_string_of_natural offs)) - in*) - natural_to_le_byte_list offs - else (*let _ = errln ("GOT slot for symbol `" ^ symname ^ - "' created pointing to address 0x" ^ (hex_string_of_natural x) ^ - " (offset 0x" ^ (hex_string_of_natural def_start) ^ " in element " ^ def_el_name ^ ")") - in*) - natural_to_le_byte_list_padded_to(Nat_big_num.of_int 8) x - ) - | _ -> failwith ("multiple matching definitions for GOT entry named " ^ symname) - ) - ) - )) - in - let concretise_got = (fun img2 -> fun plt_l -> fun maybe_plt_el -> - let l = got_l - (* Just(got_el_name, (got_start_off, got_len)))] -> *) - in - (*let _ = errln ("Concretising a GOT of " ^ (show (length l)) ^ " entries.") - in*) - let got_entry_contents = (Lem_list.map (fun (symname, maybe_def) -> - Lem_list.map (fun b -> Some b) (got_entry_bytes_for img2 symname maybe_def plt_l maybe_plt_el)) l) - in - (* We replace the GOT element's contents with the concrete addresses - * of the symbols it should contain. We leave the metadata label in there, - * for the relocation logic to find. If we change the order of entries, - * change it there too. *) - let got_content = (List.concat got_entry_contents) - in - let new_got_el = - ({ contents = got_content - ; startpos = (got_el.startpos) - ; length1 = (got_el.length1) - }) - in - let new_got_tag = (AbiFeature(Amd64AbiFeature(Abi_amd64.GOT0(l)))) - in - let got_range = (Some(".got", (Nat_big_num.of_int 0, Nat_big_num.mul(Nat_big_num.of_int 8) (length l)))) - in - let new_by_tag = - (Pset.(union)( Pset.diff(img2.by_tag : (( any_abi_feature range_tag) * ( element_range option)) Pset.set)(Pset.from_list (pairCompare compare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare)))) [(AbiFeature(Amd64AbiFeature(Abi_amd64.GOT0(l))), got_range)]))(Pset.from_list (pairCompare compare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare)))) [(new_got_tag, got_range)])) - in - let new_elements_map = (Pmap.add ".got" new_got_el ( - Pmap.remove ".got" img2.elements - )) - in - { elements = new_elements_map - ; by_tag = new_by_tag - ; by_range = (by_range_from_by_tag - instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) new_by_tag) - }) - in - (match amd64_find_plt_label_and_element orig_img with - None -> concretise_got orig_img [] None (* no PLT, but possibly a GOT *) - | Some (plt_l, plt_el) -> - let plt_base_addr = ((match plt_el.startpos with - Some a -> a - | None -> failwith "PLT has no address assigned" - )) - in - let concretise_plt = (fun img2 -> - let l = plt_l - in - (* We replace the PLT element's contents with the concrete entries - * for each of the symbols in the table. We leave the metadata label in there, - * for the relocation logic to find. If we change the order of entries, - * change it there too. *) - let all_content = (List.concat (Lem_list.map (fun (_, _, plt_content_fn) -> - let (_, content) = (plt_content_fn got_base_addr plt_base_addr) in - content - ) l)) - in - (*let _ = errln ("Got " ^ (show (length all_content)) ^ " bytes of PLT content") - in - let _ = errln ("Generated PLT reserved " ^ (show (match plt_el.length with - Just n -> n - | Nothing -> failwith "PLT has no length" - end)) ^ " bytes of PLT content") - in*) - let new_plt_el = - ({ contents = (Lem_list.map (fun b -> Some b) all_content) - ; startpos = (plt_el.startpos) - ; length1 = (Some(length all_content)) - }) - in - let new_elements_map = (Pmap.add ".plt" new_plt_el ( - Pmap.remove ".plt" img2.elements - )) - in - { elements = new_elements_map - ; by_tag = (img2.by_tag) - ; by_range = (img2.by_range) - }) - in - let concretise_rela_plt = (fun img2 -> - let maybe_rela_plt_el = (Pmap.lookup ".rela.plt" img2.elements) - in - let maybe_new_rela_plt_el = ((match maybe_rela_plt_el with - None -> (* got no .rela.plt? okay... *) - (*let _ = errln "No .rela.plt found" - in*) - None - | Some rela_plt_el -> - let got_entry_iplt_widget_for = (fun symname -> fun maybe_def -> (match maybe_def with - None -> None - | Some sd -> - if not (Nat_big_num.equal (get_elf64_symbol_type sd.def_syment) stt_gnu_ifunc) then None - else Some(fun index_in_got -> - (* This is a 24-byte Elf64_Rela. *) - let (r_offset : Nat_big_num.num) (* GOT *slot* address! *) = - ((match got_el.startpos with - None -> failwith "internal error: GOT has no assigned address" - | Some addr -> Nat_big_num.add addr ( Nat_big_num.mul(Nat_big_num.of_int 8) index_in_got) - )) - in - let (r_info : Nat_big_num.num) = r_x86_64_irelative in - ( List.rev_append (List.rev (List.rev_append (List.rev (natural_to_le_byte_list_padded_to(Nat_big_num.of_int 8) r_offset)) (natural_to_le_byte_list_padded_to(Nat_big_num.of_int 8) r_info))) - (* r_addend -- address of the ifunc definition. - * NOTE that this is NOT the same as the GOT entry bytes. - * It's the actual address of the ifunc, whereas - * the GOT entry is initialized to point back into the PLT entry. *)(match Memory_image_orderings.find_defs_matching - instance_Basic_classes_Ord_Abis_any_abi_feature_dict instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict sd img2 with - [] -> failwith ("impossible: IPLT entry widget found matching ifunc definition for " ^ symname) - | [(Some(def_el_name, (def_start, def_len)), d)] -> - (match element_and_offset_to_address (def_el_name, def_start) img2 with - None -> failwith ("no address for ifunc definition offset in element " ^ def_el_name) - | Some x -> - (* If sd is a TLS symbol, we want its offset from the *end* of the - * TLS segment. *) - (* FIXME: factor out this logic so that it lives in the TLS ABI spec. *) - if not (Nat_big_num.equal (get_elf64_symbol_type sd.def_syment) stt_gnu_ifunc) - then failwith "impossible: found ifunc definition that is not an ifunc" - else - natural_to_le_byte_list_padded_to(Nat_big_num.of_int 8) x - ) - | _ -> failwith "impossible: more than one ifunc definition" - ) - )) - (* end Just sd *) - )) - in - let rela_iplt_widgets = (Lem_list.map (fun (symname, maybe_def) -> got_entry_iplt_widget_for symname maybe_def) got_l) - in - let new_content_bytelists = - (mapi (fun i -> fun rela_widget -> - (match rela_widget with - Some f -> f (Nat_big_num.of_int i) - | None -> [] - ) - ) rela_iplt_widgets) - in - let new_contents = (Lem_list.map (fun b -> Some b) (List.concat new_content_bytelists)) - in - (*let _ = errln ("Concretised .rela.plt; first 24 bytes: " ^ (show (take 24 new_contents))) - in*) - Some( - { contents = new_contents - ; startpos = (rela_plt_el.startpos) - ; length1 = (rela_plt_el.length1) - } - ) - )) - in - let new_elements_map = ((match maybe_new_rela_plt_el with - Some new_rela_plt_el -> Pmap.add ".rela.plt" new_rela_plt_el ( - Pmap.remove ".rela.plt" img2.elements - ) - | None -> img2.elements - )) - in - { elements = new_elements_map - ; by_tag = (img2.by_tag) - ; by_range = (img2.by_range) - }) - in - concretise_rela_plt (concretise_plt (concretise_got orig_img plt_l (Some plt_el))) -) )) - -(*val amd64_got_slot_idx : annotated_memory_image any_abi_feature -> symbol_reference_and_reloc_site -> natural*) -let amd64_got_slot_idx img2 rr:Nat_big_num.num= -( - (*let _ = errln ("Looking up GOT slot for symbol " ^ rr.ref.ref_symname) in*)(match Pmap.lookup ".got" img2.elements with - None -> (* got no GOT? okay... *) failwith "got no GOT" - | Some got_el -> - (* Find the GOT tag. *) - let tags_and_ranges = (Multimap.lookupBy0 - (instance_Basic_classes_Ord_Memory_image_range_tag_dict - instance_Basic_classes_Ord_Abis_any_abi_feature_dict) (instance_Basic_classes_Ord_Maybe_maybe_dict - (instance_Basic_classes_Ord_tup2_dict - Lem_string_extra.instance_Basic_classes_Ord_string_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_Num_natural_dict - instance_Basic_classes_Ord_Num_natural_dict))) instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) (Memory_image_orderings.tagEquiv - instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict) (AbiFeature(Amd64AbiFeature(Abi_amd64.GOT0([])))) img2.by_tag) - in - (match tags_and_ranges with - [] -> failwith "error: GOT element but no ABI feature GOT tag" - | [(AbiFeature(Amd64AbiFeature(Abi_amd64.GOT0(l))), Some(got_el_name, (got_start_off, got_len)))] -> - (* Find the slot corresponding to rr, if we have one. *) - let got_addr = ((match got_el.startpos with Some addr -> addr | None -> failwith "GOT has no addr at reloc time" )) - in - (match rr.maybe_def_bound_to with - Some (_, Some(d)) -> - (match Lem_list.find_index (fun (symname, maybe_def) -> (Lem.option_equal (=) (Some(d)) maybe_def)) l with - Some idx1 -> Nat_big_num.of_int idx1 - | None -> failwith ("no GOT slot for reloc against `" ^ (rr.ref.ref_symname ^ "'")) - ) - | Some(_, None) -> (* HACK: look for the weak symname. Really want more (ref-based) labelling. *) - (match Lem_list.find_index (fun (symname, _) -> symname = rr.ref.ref_symname) l with - Some idx1 -> Nat_big_num.of_int idx1 - | None -> failwith ("no GOT slot for reloc against undefined symbol `" ^ (rr.ref.ref_symname ^ "'")) - ) - | _ -> failwith "GOT: unbound def" - ) - | _ -> failwith "got bad GOT" - ) - )) - -(*val amd64_got_slot_addr : annotated_memory_image any_abi_feature -> symbol_reference_and_reloc_site -> natural*) -let amd64_got_slot_addr img2 rr:Nat_big_num.num= - ((match Pmap.lookup ".got" img2.elements with - None -> (* got no GOT? okay... *) failwith "got no GOT" - | Some got_el -> - (* Find the GOT tag. *) - let tags_and_ranges = (Multimap.lookupBy0 - (instance_Basic_classes_Ord_Memory_image_range_tag_dict - instance_Basic_classes_Ord_Abis_any_abi_feature_dict) (instance_Basic_classes_Ord_Maybe_maybe_dict - (instance_Basic_classes_Ord_tup2_dict - Lem_string_extra.instance_Basic_classes_Ord_string_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_Num_natural_dict - instance_Basic_classes_Ord_Num_natural_dict))) instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) (Memory_image_orderings.tagEquiv - instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict) (AbiFeature(Amd64AbiFeature(Abi_amd64.GOT0([])))) img2.by_tag) - in - (match tags_and_ranges with - [] -> failwith "error: GOT element but no ABI feature GOT tag" - | [(AbiFeature(Amd64AbiFeature(Abi_amd64.GOT0(l))), Some(got_el_name, (got_start_off, got_len)))] -> - (* Find the slot corresponding to rr, if we have one. *) - let got_addr = ((match got_el.startpos with Some addr -> addr | None -> failwith "GOT has no addr at reloc time" )) - in Nat_big_num.add (Nat_big_num.mul(Nat_big_num.of_int 8) (amd64_got_slot_idx img2 rr)) got_addr - | _ -> failwith "got bad GOT" - ) - )) - -(*val amd64_plt_slot_addr : annotated_memory_image any_abi_feature -> symbol_reference_and_reloc_site -> natural -> natural*) -let amd64_plt_slot_addr img2 rr raw_addr:Nat_big_num.num= - ((match Pmap.lookup ".plt" img2.elements with - None -> - (* got no PLT? okay... under static linking this can happen. - We use the actual symbol address of the *) - (*let _ = errln "Warning: no PLT, so attempting to use actual symbol address as PLT slot address" - in*) - (* if raw_addr = 0 then failwith "bailing rather than resolving PLT slot to null address (perhaps conservatively)" else *) - raw_addr - | Some plt_el -> - (* Find the PLT tag. *) - let tags_and_ranges = (Multimap.lookupBy0 - (instance_Basic_classes_Ord_Memory_image_range_tag_dict - instance_Basic_classes_Ord_Abis_any_abi_feature_dict) (instance_Basic_classes_Ord_Maybe_maybe_dict - (instance_Basic_classes_Ord_tup2_dict - Lem_string_extra.instance_Basic_classes_Ord_string_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_Num_natural_dict - instance_Basic_classes_Ord_Num_natural_dict))) instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) (Memory_image_orderings.tagEquiv - instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict) (AbiFeature(Amd64AbiFeature(Abi_amd64.PLT0([])))) img2.by_tag) - in - (match tags_and_ranges with - [] -> failwith "error: PLT element but no ABI feature PLT tag" - | [(AbiFeature(Amd64AbiFeature(Abi_amd64.PLT0(l))), Some(plt_el_name, (plt_start_off, plt_len)))] -> - let plt_addr = ((match plt_el.startpos with Some addr -> addr | None -> failwith "PLT has no addr at reloc time" )) - in - (* Find the slot corresponding to rr, if we have one. *) - (match rr.maybe_def_bound_to with - Some (_, Some(d)) -> - (match Lem_list.mapMaybe (fun (symname, maybe_def, fn) -> if (Lem.option_equal (=) (Some(d)) maybe_def) then Some fn else None) l with - [fn] -> - let got_addr = - ((match Pmap.lookup ".got" img2.elements with - None -> (* got no GOT? okay... *) failwith "got no GOT (applying PLT calculation)" - | Some got_el -> (match got_el.startpos with - Some addr -> addr - | None -> failwith "concrete GOT has no addr" - ) - )) - in - let (addr, content) = (fn got_addr plt_addr) - in - (*let _ = errln ("Calculated PLT slot for `" ^ d.def_symname ^ "', from PLT addr " ^ (hex_string_of_natural plt_addr) - ^ " and GOT addr " ^ (hex_string_of_natural got_addr) ^ ", as " ^ (hex_string_of_natural addr)) - in*) - addr - | [] -> (* failwith ("internal error: no PLT entry for reloc against `" ^ rr.ref.ref_symname ^ "'") *) - (* If we got no PLT slot, we assume it's because the PLT entry was optimised out. - * So we just return the address of the symbol itself. *) - (*let _ = errln ("No PLT entry for reloc against `" ^ rr.ref.ref_symname ^ - "', which we assume was optimised to avoid the GOT") - in*) - (match Memory_image_orderings.find_defs_matching - instance_Basic_classes_Ord_Abis_any_abi_feature_dict instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict d img2 with - [] ->Nat_big_num.of_int 0 (* HMM -- should be an error? *) - | [(Some(el_name, (start_off, len)), matching_d)] -> - (match element_and_offset_to_address (el_name, start_off) img2 with - Some a -> a - | None -> failwith ("internal error: could not get address for PLT-short-circuited symbol `" ^ (rr.ref.ref_symname ^ "'")) - ) - | _ -> failwith ("output image has multiple and/or no-location definitions to which via-PLT ref to `" ^ (rr.ref.ref_symname ^ "' could resolve")) - ) - | _ -> failwith ("internal error: multiple PLT entries for reloc against `" ^ (rr.ref.ref_symname ^ "'")) - ) - | Some(_, None) ->Nat_big_num.of_int (* weak, so 0 *)0 - | _ -> failwith "PLT: unbound def" - ) - | _ -> failwith "got bad PLT" - ) - )) - -(** [amd64_reloc r] yields a function that applies relocations of type [r]. *) -(*val amd64_reloc : reloc_fn any_abi_feature*) -let amd64_reloc r:bool*((any_abi_feature)annotated_memory_image ->Nat_big_num.num ->symbol_reference_and_reloc_site ->Nat_big_num.num*(Nat_big_num.num ->Nat_big_num.num ->Nat_big_num.num ->Nat_big_num.num))= - ((match (string_of_amd64_relocation_type r) with - | "R_X86_64_NONE" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 0, (fun s -> fun a -> fun e -> e)))))) - | "R_X86_64_64" -> (true, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 8, (fun s -> fun a -> fun e -> i2n ( Nat_big_num.add(n2i s) a))))))) - | "R_X86_64_PC32" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 4, (fun s -> fun a -> fun e -> i2n_signed( 32) ( Nat_big_num.sub( Nat_big_num.add(n2i s) a) (n2i site_addr)))))))) - | "R_X86_64_GOT32" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 4, (fun s -> fun a -> fun e -> i2n_signed( 32) ( Nat_big_num.add(n2i (amd64_got_slot_idx img2 rr)) a))))))) - | "R_X86_64_PLT32" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 4, (fun s -> fun a -> fun e -> i2n_signed( 32) ( Nat_big_num.sub (Nat_big_num.add(n2i (amd64_plt_slot_addr img2 rr s)) a) (n2i site_addr))) )))) ) - | "R_X86_64_COPY" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (size_of_copy_reloc img2 rr, (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_GLOB_DAT" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (size_of_def rr, (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_JUMP_SLOT" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 4 (* CHECK *), (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_RELATIVE" -> (true, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 8, (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_GOTPCREL" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 4, (fun s -> fun a -> fun e -> i2n_signed( 32) ( Nat_big_num.sub (Nat_big_num.add(n2i (amd64_got_slot_addr img2 rr)) a) (n2i site_addr))) )))) ) - | "R_X86_64_32" -> (true, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 4, (fun s -> fun a -> fun e -> i2n ( Nat_big_num.add(n2i s) a))))))) - | "R_X86_64_32S" -> (true, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 4, (fun s -> fun a -> fun e -> i2n_signed( 32) ( Nat_big_num.add(n2i s) a))))))) - | "R_X86_64_16" -> (true, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 2, (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_PC16" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 2, (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_8" -> (true, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 1, (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_PC8" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 1, (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_DTPMOD64" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 8 (* CHECK *), (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_DTPOFF64" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 8 (* CHECK *), (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_TPOFF64" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 8 (* CHECK *), (fun s -> fun a -> fun e -> i2n_signed( 64) (Nat_big_num.sub(Nat_big_num.of_int 0)(Nat_big_num.of_int 8))) (* FIXME *)))))) - | "R_X86_64_TLSGD" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 8 (* CHECK *), (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_TLSLD" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 8 (* CHECK *), (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_DTPOFF32" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 4 (* CHECK *), (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_GOTTPOFF" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 4, (fun s -> fun a -> fun e -> i2n_signed( 32) ( Nat_big_num.sub (Nat_big_num.add(n2i (amd64_got_slot_addr img2 rr)) a) (n2i site_addr)))))))) - | "R_X86_64_TPOFF32" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 4 (* CHECK *), (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_PC64" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 8, (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_GOTOFF64" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 8, (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_GOTPC32" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 4, (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_SIZE32" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 4, (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_SIZE64" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 8, (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_GOTPC32_TLSDESC" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 4 (* CHECK *), (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_TLSDESC_CALL" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 4 (* CHECK *), (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_TLSDESC" -> (false, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 8 (* CHECK *), (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | "R_X86_64_IRELATIVE" -> (true, (fun img2 -> (fun site_addr -> (fun rr -> (Nat_big_num.of_int 8 (* CHECK *), (fun s -> fun a -> fun e -> e) (* FIXME *)))))) - | _ -> failwith "unrecognised relocation" -)) - -(*val sysv_amd64_std_abi : abi any_abi_feature*) -let sysv_amd64_std_abi:(any_abi_feature)abi= - ({ is_valid_elf_header = header_is_amd64 - ; make_elf_header = (make_elf64_header elf_data_2lsb elf_osabi_none(Nat_big_num.of_int 0) elf_ma_x86_64) - ; reloc = amd64_reloc - ; section_is_special = section_is_special0 - ; section_is_large = (fun s -> (fun f -> flag_is_set shf_x86_64_large s.elf64_section_flags)) - ; maxpagesize =(Nat_big_num.of_int 65536) - ; minpagesize =(Nat_big_num.of_int 4096) - ; commonpagesize =(Nat_big_num.of_int 4096) - (* XXX: DPM, changed from explicit reference to null_abi field due to problems in HOL4. *) - ; symbol_is_generated_by_linker = (fun symname -> symname = "_GLOBAL_OFFSET_TABLE_") - ; make_phdrs = make_default_phdrs - ; max_phnum =(Nat_big_num.of_int 2) (* incremented by extensions *) - ; guess_entry_point = - (find_start_symbol_address - instance_Basic_classes_Ord_Abis_any_abi_feature_dict - instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict) - ; pad_data = pad_zeroes - ; pad_code = pad_0x90 - ; generate_support = amd64_generate_support - ; concretise_support = amd64_concretise_support - ; get_reloc_symaddr = amd64_get_reloc_symaddr - }) - -(*val sysv_aarch64_le_std_abi : abi any_abi_feature*) -let sysv_aarch64_le_std_abi:(any_abi_feature)abi= - ({ is_valid_elf_header = header_is_aarch64_le - ; make_elf_header = (make_elf64_header elf_data_2lsb elf_osabi_none(Nat_big_num.of_int 0) elf_ma_aarch64) - ; reloc = aarch64_le_reloc - ; section_is_special = section_is_special0 - ; section_is_large = (fun _ -> (fun _ -> false)) - ; maxpagesize = (Nat_big_num.mul (Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 256))(Nat_big_num.of_int 4096)) (* 2MB; bit of a guess, based on gdb and prelink code *) - ; minpagesize =(Nat_big_num.of_int 1024) (* bit of a guess again *) - ; commonpagesize =(Nat_big_num.of_int 4096) - ; symbol_is_generated_by_linker = (fun symname -> symname = "_GLOBAL_OFFSET_TABLE_") - ; make_phdrs = make_default_phdrs - ; max_phnum =(Nat_big_num.of_int 2) (* incremented by extensions *) - ; guess_entry_point = - (find_start_symbol_address - instance_Basic_classes_Ord_Abis_any_abi_feature_dict - instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict) - ; pad_data = pad_zeroes - ; pad_code = pad_zeroes - ; generate_support = ( (* fun _ -> *)fun _ -> get_empty_memory_image ()) - ; concretise_support = (fun img2 -> img2) - ; get_reloc_symaddr = - (default_get_reloc_symaddr - instance_Basic_classes_Ord_Abis_any_abi_feature_dict - instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict) - }) - -(*val all_abis : list (abi any_abi_feature)*) -let all_abis:((any_abi_feature)abi)list= ([sysv_amd64_std_abi; sysv_aarch64_le_std_abi; null_abi]) - diff --git a/lib/ocaml_rts/linksem/abis/amd64/abi_amd64.ml b/lib/ocaml_rts/linksem/abis/amd64/abi_amd64.ml deleted file mode 100644 index 1f7ee662..00000000 --- a/lib/ocaml_rts/linksem/abis/amd64/abi_amd64.ml +++ /dev/null @@ -1,98 +0,0 @@ -(*Generated by Lem from abis/amd64/abi_amd64.lem.*) -(** [abi_amd64] contains top-level definition for the AMD64 ABI. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_list -open Lem_num -open Lem_maybe -open Error -open Lem_map -open Lem_assert_extra - -open Missing_pervasives -open Elf_header -open Elf_types_native_uint -open Elf_file -open Elf_interpreted_segment -open Elf_interpreted_section - -open Endianness -open Memory_image -(* open import Elf_memory_image *) - -open Abi_classes -open Abi_amd64_relocation -open Abi_amd64_elf_header - -(** [abi_amd64_compute_program_entry_point segs entry] computes the program - * entry point using ABI-specific conventions. On AMD64 the entry point in - * the ELF header ([entry] here) is the real entry point. On other ABIs, e.g. - * PowerPC64, the entry point [entry] is a pointer into one of the segments - * constituting the process image (passed in as [segs] here for a uniform - * interface). - *) -(*val abi_amd64_compute_program_entry_point : list elf64_interpreted_segments -> elf64_addr -> error natural*) -let abi_amd64_compute_program_entry_point segs entry:(Nat_big_num.num)error= - (return (Ml_bindings.nat_big_num_of_uint64 entry)) - -(*val header_is_amd64 : elf64_header -> bool*) -let header_is_amd64 h:bool= - (is_valid_elf64_header h - && ((Lem.option_equal (=) (Lem_list.list_index h.elf64_ident (Nat_big_num.to_int elf_ii_data)) (Some (Uint32.of_string (Nat_big_num.to_string elf_data_2lsb)))) - && (is_valid_abi_amd64_machine_architecture (Nat_big_num.of_string (Uint32.to_string h.elf64_machine)) - && is_valid_abi_amd64_magic_number h.elf64_ident))) - -let shf_x86_64_large : Nat_big_num.num= ( Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 1048576)) (* 0x10000000 a.k.a. 2^28 *) - -(* We model the PLT as a list of symbol name, maybe def, and a function - * - from the PLT slot offset and the whole with-addresses image (overkill) - * - to... what? currently it's the address of the named symbol *) -type 'abifeature plt_entry_content_fn = Nat_big_num.num -> Nat_big_num.num -> (Nat_big_num.num * char list) - (* PLT base addr, GOT base addr (the rest is closure-captured) -> slot_addr, slot contents *) - -type 'abifeature amd64_abi_feature = - GOT0 of ( (string * ( symbol_definition option))list) - | PLT0 of ( (string * ( symbol_definition option) * 'abifeature plt_entry_content_fn)list) - -(*val abiFeatureCompare : forall 'abifeature. amd64_abi_feature 'abifeature -> amd64_abi_feature 'abifeature -> Basic_classes.ordering*) -let abiFeatureCompare0 f1 f2:int= - ((match (f1, f2) with - (GOT0(_), GOT0(_)) -> 0 - | (GOT0(_), PLT0(_)) -> (-1) - | (PLT0(_), PLT0(_)) -> 0 - | (PLT0(_), GOT0(_)) -> 1 - )) - -(*val abiFeatureTagEq : forall 'abifeature. amd64_abi_feature 'abifeature -> amd64_abi_feature 'abifeature -> bool*) -let abiFeatureTagEq0 f1 f2:bool= - ((match (f1, f2) with - (GOT0(_), GOT0(_)) -> true - | (PLT0(_), PLT0(_)) -> true - | (_, _) -> false - )) - -let instance_Abi_classes_AbiFeatureTagEquiv_Abi_amd64_amd64_abi_feature_dict:('abifeature amd64_abi_feature)abiFeatureTagEquiv_class= ({ - - abiFeatureTagEquiv_method = abiFeatureTagEq0}) - -let instance_Basic_classes_Ord_Abi_amd64_amd64_abi_feature_dict:('abifeature amd64_abi_feature)ord_class= ({ - - compare_method = abiFeatureCompare0; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(abiFeatureCompare0 f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (abiFeatureCompare0 f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(abiFeatureCompare0 f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (abiFeatureCompare0 f1 f2)(Pset.from_list compare [1; 0])))}) - -(*val section_is_special : forall 'abifeature. elf64_interpreted_section -> annotated_memory_image 'abifeature -> bool*) -let section_is_special1 s img2:bool= - (elf_section_is_special s img2 || - (match s.elf64_section_name_as_string with - ".eh_frame" -> true (* HACK needed because SHT_X86_64_UNWIND is often not used *) - | _ -> false - )) diff --git a/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_elf_header.ml b/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_elf_header.ml deleted file mode 100644 index 61f36af3..00000000 --- a/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_elf_header.ml +++ /dev/null @@ -1,60 +0,0 @@ -(*Generated by Lem from abis/amd64/abi_amd64_elf_header.lem.*) -(** [abi_amd64_elf_header] contains types and definitions relating to ABI - * specific ELF header functionality for the AMD64 ABI. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_list -open Lem_num -open Lem_maybe -open Missing_pervasives - -open Elf_header -open Elf_types_native_uint - -open Endianness - -(*val abi_amd64_data_encoding : natural*) -let abi_amd64_data_encoding:Nat_big_num.num= elf_data_2lsb - -(*val abi_amd64_endianness : endianness*) -let abi_amd64_endianness:endianness= Little (* Must match above *) - -(*val abi_amd64_file_class : natural*) -let abi_amd64_file_class:Nat_big_num.num= elf_class_64 - -(*val abi_amd64_file_version : natural*) -let abi_amd64_file_version:Nat_big_num.num= elf_ev_current - -(*val abi_amd64_page_size_min : natural*) -let abi_amd64_page_size_min:Nat_big_num.num= (Nat_big_num.of_int 4096) - -(*val abi_amd64_page_size_max : natural*) -let abi_amd64_page_size_max:Nat_big_num.num= (Nat_big_num.of_int 65536) - -(** [is_valid_abi_amd64_machine_architecture m] checks whether the ELF header's - * machine architecture is valid according to the ABI-specific specification. - * Machine architecture must be x86-64 (pg 60) - *) -(*val is_valid_abi_amd64_machine_architecture : natural -> bool*) -let is_valid_abi_amd64_machine_architecture m:bool= (Nat_big_num.equal - m elf_ma_x86_64) - -(** [is_valid_abi_amd64_magic_number magic] checks whether the ELF header's - * magic number is valid according to the ABI-specific specification. - * File class must be 64-bit (pg 60) - * Data encoding must be little endian (pg 60) - *) -(*val is_valid_abi_amd64_magic_number : list unsigned_char -> bool*) -let is_valid_abi_amd64_magic_number magic:bool= - ((match Lem_list.list_index magic (Nat_big_num.to_int elf_ii_class) with - | None -> false - | Some cls -> - (match Lem_list.list_index magic (Nat_big_num.to_int elf_ii_data) with - | None -> false - | Some data -> - ( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string cls)) abi_amd64_file_class) && - ( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string data)) abi_amd64_data_encoding) - ) - )) diff --git a/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_program_header_table.ml b/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_program_header_table.ml deleted file mode 100644 index aa13d087..00000000 --- a/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_program_header_table.ml +++ /dev/null @@ -1,38 +0,0 @@ -(*Generated by Lem from abis/amd64/abi_amd64_program_header_table.lem.*) -(** [abi_amd64_program_header_table], program header table specific definitions - * for the AMD64 ABI. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_num -open Lem_string - -(** New segment types. *) - -(** The segment contains the stack unwind tables *) -let abi_amd64_pt_gnu_eh_frame : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 842691240)) (* 0x6474e550 *) -let abi_amd64_pt_sunw_eh_frame : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 842691240)) (* 0x6474e550 *) -let abi_amd64_pt_sunw_unwind : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 842691240)) (* 0x6474e550 *) - -(** [string_of_abi_amd64_elf_segment_type m] produces a string based representation - * of AMD64 segment type [m]. - *) -(*val string_of_abi_amd64_elf_segment_type : natural -> string*) -let string_of_abi_amd64_elf_segment_type m:string= - (if Nat_big_num.equal m abi_amd64_pt_gnu_eh_frame then - "GNU_EH_FRAME" - else if Nat_big_num.equal m abi_amd64_pt_sunw_eh_frame then - "SUNW_EH_FRAME" - else if Nat_big_num.equal m abi_amd64_pt_sunw_unwind then - "SUNW_UNWIND" - else - "Invalid AMD64 segment type") - -(** [abi_amd64_is_valid_program_interpreter s] checks whether the program interpreter - * string is valid for AMD64 ABI. - * See Section 5.2.1 - *) -(*val abi_amd64_is_valid_program_interpreter : string -> bool*) -let abi_amd64_is_valid_program_interpreter s:bool= - ((s = "/lib/ld64.so.1") || (s = "/lib64/ld-linux-x86-64.so.2")) diff --git a/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_relocation.ml b/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_relocation.ml deleted file mode 100644 index 39355f61..00000000 --- a/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_relocation.ml +++ /dev/null @@ -1,355 +0,0 @@ -(*Generated by Lem from abis/amd64/abi_amd64_relocation.lem.*) -(** [abi_amd64_relocation] contains types and definitions relating to ABI - * specific relocation functionality for the AMD64 ABI. - *) - -open Lem_basic_classes -open Lem_map -open Lem_maybe -open Lem_num -open Lem_string - -open Error -open Missing_pervasives -open Lem_assert_extra - -open Elf_types_native_uint -open Elf_file -open Elf_header -open Elf_relocation -open Elf_symbol_table -open Memory_image - -open Abi_classes -open Abi_utilities - -(** x86-64 relocation types. *) - -let r_x86_64_none : Nat_big_num.num= (Nat_big_num.of_int 0) -let r_x86_64_64 : Nat_big_num.num= (Nat_big_num.of_int 1) -let r_x86_64_pc32 : Nat_big_num.num= (Nat_big_num.of_int 2) -let r_x86_64_got32 : Nat_big_num.num= (Nat_big_num.of_int 3) -let r_x86_64_plt32 : Nat_big_num.num= (Nat_big_num.of_int 4) -let r_x86_64_copy : Nat_big_num.num= (Nat_big_num.of_int 5) -let r_x86_64_glob_dat : Nat_big_num.num= (Nat_big_num.of_int 6) -let r_x86_64_jump_slot : Nat_big_num.num= (Nat_big_num.of_int 7) -let r_x86_64_relative : Nat_big_num.num= (Nat_big_num.of_int 8) -let r_x86_64_gotpcrel : Nat_big_num.num= (Nat_big_num.of_int 9) -let r_x86_64_32 : Nat_big_num.num= (Nat_big_num.of_int 10) -let r_x86_64_32s : Nat_big_num.num= (Nat_big_num.of_int 11) -let r_x86_64_16 : Nat_big_num.num= (Nat_big_num.of_int 12) -let r_x86_64_pc16 : Nat_big_num.num= (Nat_big_num.of_int 13) -let r_x86_64_8 : Nat_big_num.num= (Nat_big_num.of_int 14) -let r_x86_64_pc8 : Nat_big_num.num= (Nat_big_num.of_int 15) -let r_x86_64_dtpmod64 : Nat_big_num.num= (Nat_big_num.of_int 16) -let r_x86_64_dtpoff64 : Nat_big_num.num= (Nat_big_num.of_int 17) -let r_x86_64_tpoff64 : Nat_big_num.num= (Nat_big_num.of_int 18) -let r_x86_64_tlsgd : Nat_big_num.num= (Nat_big_num.of_int 19) -let r_x86_64_tlsld : Nat_big_num.num= (Nat_big_num.of_int 20) -let r_x86_64_dtpoff32 : Nat_big_num.num= (Nat_big_num.of_int 21) -let r_x86_64_gottpoff : Nat_big_num.num= (Nat_big_num.of_int 22) -let r_x86_64_tpoff32 : Nat_big_num.num= (Nat_big_num.of_int 23) -let r_x86_64_pc64 : Nat_big_num.num= (Nat_big_num.of_int 24) -let r_x86_64_gotoff64 : Nat_big_num.num= (Nat_big_num.of_int 25) -let r_x86_64_gotpc32 : Nat_big_num.num= (Nat_big_num.of_int 26) -let r_x86_64_size32 : Nat_big_num.num= (Nat_big_num.of_int 32) -let r_x86_64_size64 : Nat_big_num.num= (Nat_big_num.of_int 33) -let r_x86_64_gotpc32_tlsdesc : Nat_big_num.num= (Nat_big_num.of_int 34) -let r_x86_64_tlsdesc_call : Nat_big_num.num= (Nat_big_num.of_int 35) -let r_x86_64_tlsdesc : Nat_big_num.num= (Nat_big_num.of_int 36) -let r_x86_64_irelative : Nat_big_num.num= (Nat_big_num.of_int 37) - -(** [string_of_x86_64_relocation_type m] produces a string representation of the - * relocation type [m]. - *) -(*val string_of_amd64_relocation_type : natural -> string*) -let string_of_amd64_relocation_type rel_type1:string= - (if Nat_big_num.equal rel_type1 r_x86_64_none then - "R_X86_64_NONE" - else if Nat_big_num.equal rel_type1 r_x86_64_64 then - "R_X86_64_64" - else if Nat_big_num.equal rel_type1 r_x86_64_pc32 then - "R_X86_64_PC32" - else if Nat_big_num.equal rel_type1 r_x86_64_got32 then - "R_X86_64_GOT32" - else if Nat_big_num.equal rel_type1 r_x86_64_plt32 then - "R_X86_64_PLT32" - else if Nat_big_num.equal rel_type1 r_x86_64_copy then - "R_X86_64_COPY" - else if Nat_big_num.equal rel_type1 r_x86_64_glob_dat then - "R_X86_64_GLOB_DAT" - else if Nat_big_num.equal rel_type1 r_x86_64_jump_slot then - "R_X86_64_JUMP_SLOT" - else if Nat_big_num.equal rel_type1 r_x86_64_relative then - "R_X86_64_RELATIVE" - else if Nat_big_num.equal rel_type1 r_x86_64_gotpcrel then - "R_X86_64_GOTPCREL" - else if Nat_big_num.equal rel_type1 r_x86_64_32 then - "R_X86_64_32" - else if Nat_big_num.equal rel_type1 r_x86_64_32s then - "R_X86_64_32S" - else if Nat_big_num.equal rel_type1 r_x86_64_16 then - "R_X86_64_16" - else if Nat_big_num.equal rel_type1 r_x86_64_pc16 then - "R_X86_64_PC16" - else if Nat_big_num.equal rel_type1 r_x86_64_8 then - "R_X86_64_8" - else if Nat_big_num.equal rel_type1 r_x86_64_pc8 then - "R_X86_64_PC8" - else if Nat_big_num.equal rel_type1 r_x86_64_dtpmod64 then - "R_X86_64_DTPMOD64" - else if Nat_big_num.equal rel_type1 r_x86_64_dtpoff64 then - "R_X86_64_DTPOFF64" - else if Nat_big_num.equal rel_type1 r_x86_64_tpoff64 then - "R_X86_64_TPOFF64" - else if Nat_big_num.equal rel_type1 r_x86_64_tlsgd then - "R_X86_64_TLSGD" - else if Nat_big_num.equal rel_type1 r_x86_64_tlsld then - "R_X86_64_TLSLD" - else if Nat_big_num.equal rel_type1 r_x86_64_dtpoff32 then - "R_X86_64_DTPOFF32" - else if Nat_big_num.equal rel_type1 r_x86_64_gottpoff then - "R_X86_64_GOTTPOFF" - else if Nat_big_num.equal rel_type1 r_x86_64_tpoff32 then - "R_X86_64_TPOFF32" - else if Nat_big_num.equal rel_type1 r_x86_64_pc64 then - "R_X86_64_PC64" - else if Nat_big_num.equal rel_type1 r_x86_64_gotoff64 then - "R_X86_64_GOTOFF64" - else if Nat_big_num.equal rel_type1 r_x86_64_gotpc32 then - "R_X86_64_GOTPC32" - else if Nat_big_num.equal rel_type1 r_x86_64_size32 then - "R_X86_64_SIZE32" - else if Nat_big_num.equal rel_type1 r_x86_64_size64 then - "R_X86_64_SIZE64" - else if Nat_big_num.equal rel_type1 r_x86_64_gotpc32_tlsdesc then - "R_X86_64_GOTPC32_TLSDESC" - else if Nat_big_num.equal rel_type1 r_x86_64_tlsdesc_call then - "R_X86_64_TLSDESC_CALL" - else if Nat_big_num.equal rel_type1 r_x86_64_tlsdesc then - "R_X86_64_TLSDESC" - else if Nat_big_num.equal rel_type1 r_x86_64_irelative then - "R_X86_64_IRELATIVE" - else - "Invalid X86_64 relocation") - -(* How do we find the GOT? *) -(* We really want to find the GOT without knowing how it's labelled, because - * in this file 'abifeature is abstract. This is a real problem. So for now, - * we use the HACK of looking for a section called ".got". - * Even then, we can't understand the content of the GOT without reading the tag. - * - * So we can - * - * - accept an argument of type abi 'abifeature and call a function on it to get the GOT - (but then type abi becomes a recursive record type); - * - extend the AbiFeatureTagEquiv class into a generic class capturing ABIs; - then we risk breaking various things in Isabelle because Lem's type classes don't work there; - * - move the amd64_reloc function to abis.lem and define it only for any_abi_feature. - *) - -(** [abi_amd64_apply_relocation rel val_map ef] - * calculates the effect of a relocation of type [rel] using relevant addresses, - * offsets and fields represented by [b_val], [g_val], [got_val], [l_val], [p_val], - * [s_val] and [z_val], stored in [val_map] with "B", "G", and so on as string - * keys, which are: - * - * - B : Base address at which a shared-object has been loaded into memory - * during execution. - * - G : Represents the offset into the GOT at which the relocation's entry - * will reside during execution. - * - GOT: Address of the GOT. - * - L : Represents the address or offset of the PLT entry for a symbol. - * - P : Represents the address or offset of the storage unit being - * relocated. - * - S : Represents the value of the symbol whose index resides in the - * relocation entry. - * - Z : Represents the size of the symbol whose index resides in the - * relocation entry. - * - * More details of the above can be found in the AMD64 ABI document's chapter - * on relocations. - * - * The [abi_amd64_apply_relocation] function returns a relocation frame, either - * indicating that the relocation is a copy relocation, or that some calculation - * must be carried out at a certain location. See the comment above the - * [relocation_frame] type in [Abi_utilities.lem] for more details. - *) -(*val abi_amd64_apply_relocation : elf64_relocation_a -> val_map string integer -> elf64_file - -> error (relocation_frame elf64_addr integer)*) -let abi_amd64_apply_relocation rel val_map1 ef:(((Uint64.uint64),(Nat_big_num.num))relocation_frame)error= - (if is_elf64_relocatable_file ef.elf64_file_header then - let rel_type1 = (get_elf64_relocation_a_type rel) in - let a_val = (Nat_big_num.of_int64 rel.elf64_ra_addend) in - (** No width, No calculation *) - if Nat_big_num.equal rel_type1 r_x86_64_none then - return (NoCopy ((Pmap.empty compare))) - (** Width: 64 Calculation: S + A *) - else if Nat_big_num.equal rel_type1 r_x86_64_64 then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "S" val_map1 >>= (fun s_val -> - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)))) - (** Width: 32 Calculation: S + A - P *) - else if Nat_big_num.equal rel_type1 r_x86_64_pc32 then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "S" val_map1 >>= (fun s_val -> - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "P" val_map1 >>= (fun p_val -> - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare))))) - (** Width: 32 Calculation: G + A *) - else if Nat_big_num.equal rel_type1 r_x86_64_got32 then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "G" val_map1 >>= (fun g_val -> - let result = (Lift ( Nat_big_num.add g_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)))) - (** Width: 32 Calculation: L + A - P *) - else if Nat_big_num.equal rel_type1 r_x86_64_plt32 then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "L" val_map1 >>= (fun l_val -> - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "P" val_map1 >>= (fun p_val -> - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add l_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare))))) - (** No width, No calculation *) - else if Nat_big_num.equal rel_type1 r_x86_64_copy then - return Copy - (** Width: 64 Calculation: S *) - else if Nat_big_num.equal rel_type1 r_x86_64_glob_dat then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "S" val_map1 >>= (fun s_val -> - let result = (Lift s_val) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)))) - (** Width: 64 Calculation: S *) - else if Nat_big_num.equal rel_type1 r_x86_64_jump_slot then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "S" val_map1 >>= (fun s_val -> - let result = (Lift s_val) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)))) - (** Width: 64 Calculation: B + A *) - else if Nat_big_num.equal rel_type1 r_x86_64_relative then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "B" val_map1 >>= (fun b_val -> - let result = (Lift ( Nat_big_num.add b_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)))) - (** Width: 32 Calculation: G + GOT + A - P *) - else if Nat_big_num.equal rel_type1 r_x86_64_gotpcrel then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "G" val_map1 >>= (fun g_val -> - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "GOT" val_map1 >>= (fun got_val -> - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "P" val_map1 >>= (fun p_val -> - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add (Nat_big_num.add g_val got_val) a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)))))) - (** Width: 32 Calculation: S + A *) - else if Nat_big_num.equal rel_type1 r_x86_64_32 then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "S" val_map1 >>= (fun s_val -> - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)))) - (** Width: 32 Calculation: S + A *) - else if Nat_big_num.equal rel_type1 r_x86_64_32s then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "S" val_map1 >>= (fun s_val -> - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)))) - (** Width: 16 Calculation: S + A *) - else if Nat_big_num.equal rel_type1 r_x86_64_16 then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "S" val_map1 >>= (fun s_val -> - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)))) - (** Width: 16 Calculation: S + A - P *) - else if Nat_big_num.equal rel_type1 r_x86_64_pc16 then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "S" val_map1 >>= (fun s_val -> - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "P" val_map1 >>= (fun p_val -> - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare))))) - (** Width: 8 Calculation: S + A *) - else if Nat_big_num.equal rel_type1 r_x86_64_8 then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "S" val_map1 >>= (fun s_val -> - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I8, CanFail) (Pmap.empty compare)))) - (** Width 8: Calculation: S + A - P *) - else if Nat_big_num.equal rel_type1 r_x86_64_pc8 then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "S" val_map1 >>= (fun s_val -> - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "P" val_map1 >>= (fun p_val -> - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I8, CanFail) (Pmap.empty compare))))) - (** Width: 64 *) - else if Nat_big_num.equal rel_type1 r_x86_64_dtpmod64 then - failwith "abi_amd64_apply_relocation: r_x86_64_dtpmod64 not implemented" - (** Width: 64 *) - else if Nat_big_num.equal rel_type1 r_x86_64_dtpoff64 then - failwith "abi_amd64_apply_relocation: r_x86_64_dtpoff64 not implemented" - (** Width: 64 *) - else if Nat_big_num.equal rel_type1 r_x86_64_tpoff64 then - failwith "abi_amd64_apply_relocation: r_x86_64_tpoff64 not implemented" - (** Width: 32 *) - else if Nat_big_num.equal rel_type1 r_x86_64_tlsgd then - failwith "abi_amd64_apply_relocation: r_x86_64_tlsgd not implemented" - (** Width: 32 *) - else if Nat_big_num.equal rel_type1 r_x86_64_tlsld then - failwith "abi_amd64_apply_relocation: r_x86_64_tlsld not implemented" - (** Width: 32 *) - else if Nat_big_num.equal rel_type1 r_x86_64_dtpoff32 then - failwith "abi_amd64_apply_relocation: r_x86_64_dtpoff32 not implemented" - (** Width: 32 *) - else if Nat_big_num.equal rel_type1 r_x86_64_gottpoff then - failwith "abi_amd64_apply_relocation: r_x86_64_gottpoff not implemented" - (** Width: 32 *) - else if Nat_big_num.equal rel_type1 r_x86_64_tpoff32 then - failwith "abi_amd64_apply_relocation: r_x86_64_tpoff32 not implemented" - (** Width: 64 Calculation: S + A - P *) - else if Nat_big_num.equal rel_type1 r_x86_64_pc64 then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "S" val_map1 >>= (fun s_val -> - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "P" val_map1 >>= (fun p_val -> - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare))))) - (** Width: 64 Calculation: S + A - GOT *) - else if Nat_big_num.equal rel_type1 r_x86_64_gotoff64 then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "S" val_map1 >>= (fun s_val -> - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "GOT" val_map1 >>= (fun got_val -> - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) got_val)) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare))))) - (** Width: 32 Calculation: GOT + A - P *) - else if Nat_big_num.equal rel_type1 r_x86_64_gotpc32 then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "GOT" val_map1 >>= (fun got_val -> - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "P" val_map1 >>= (fun p_val -> - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add got_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare))))) - (** Width: 32 Calculation: Z + A *) - else if Nat_big_num.equal rel_type1 r_x86_64_size32 then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "Z" val_map1 >>= (fun z_val -> - let result = (Lift ( Nat_big_num.add z_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)))) - (** Width: 64 Calculation: Z + A *) - else if Nat_big_num.equal rel_type1 r_x86_64_size64 then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "Z" val_map1 >>= (fun z_val -> - let result = (Lift ( Nat_big_num.add z_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)))) - (** Width: 32 *) - else if Nat_big_num.equal rel_type1 r_x86_64_gotpc32_tlsdesc then - failwith "abi_amd64_apply_relocation: r_x86_64_gotpc32_tlsdesc not implemented" - (** No width *) - else if Nat_big_num.equal rel_type1 r_x86_64_tlsdesc_call then - failwith "abi_amd64_apply_relocation: r_x86_64_tlsdesc_call not implemented" - (** Width: 64X2 *) - else if Nat_big_num.equal rel_type1 r_x86_64_tlsdesc then - failwith "abi_amd64_apply_relocation: r_x86_64_tlsdesc not implemented" - (** Calculation: indirect(B + A) *) - else if Nat_big_num.equal rel_type1 r_x86_64_irelative then - lookupM (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "B" val_map1 >>= (fun b_val -> - let result = (Apply(Indirect, Lift( Nat_big_num.add b_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (NoCopy (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)))) - else - failwith "abi_amd64_apply_relocation: invalid relocation type" - else - failwith "abi_amd64_apply_relocation: not a relocatable file") diff --git a/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_section_header_table.ml b/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_section_header_table.ml deleted file mode 100644 index f4520a67..00000000 --- a/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_section_header_table.ml +++ /dev/null @@ -1,51 +0,0 @@ -(*Generated by Lem from abis/amd64/abi_amd64_section_header_table.lem.*) -(** [abi_amd64_section_header_table] module contains section header table - * specific definitions for the AMD64 ABI. - *) - -open Lem_basic_classes -open Lem_map -open Lem_num - -open Elf_section_header_table - -(** AMD64 specific flags. See Section 4.2.1. *) - -let shf_abi_amd64_large : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 67108864)(Nat_big_num.of_int 4)) (* 0x10000000 *) - -(** AMD64 specific section types. See Section 4.2.2 *) - -let sht_abi_amd64_unwind : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 939524096)(Nat_big_num.of_int 2))(Nat_big_num.of_int 1)) (* 0x70000001 *) - -(** [string_of_abi_amd64_section_type m] produces a string based representation - * of AMD64 section type [m]. - *) -(*val string_of_abi_amd64_section_type : natural -> string*) -let string_of_abi_amd64_section_type m:string= - (if Nat_big_num.equal m sht_abi_amd64_unwind then - "X86_64_UNWIND" - else - "Invalid AMD64 section type") - -(** Special sections *) - -(*val abi_amd64_special_sections : Map.map string (natural * natural)*) -let abi_amg64_special_sections:((string),(Nat_big_num.num*Nat_big_num.num))Pmap.map= - (Lem_map.fromList (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) [ - (".got", (sht_progbits, Nat_big_num.add shf_alloc shf_write)) - ; (".plt", (sht_progbits, Nat_big_num.add shf_alloc shf_execinstr)) - ; (".eh_frame", (sht_abi_amd64_unwind, shf_alloc)) - ]) - -(*val abi_amd64_special_sections_large_code_model : Map.map string (natural * natural)*) -let abi_amd64_special_sections_large_code_model:((string),(Nat_big_num.num*Nat_big_num.num))Pmap.map= - (Lem_map.fromList (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) [ - (".lbss", (sht_nobits, Nat_big_num.add (Nat_big_num.add shf_alloc shf_write) shf_abi_amd64_large)) - ; (".ldata", (sht_progbits, Nat_big_num.add (Nat_big_num.add shf_alloc shf_write) shf_abi_amd64_large)) - ; (".ldata1", (sht_progbits, Nat_big_num.add (Nat_big_num.add shf_alloc shf_write) shf_abi_amd64_large)) - ; (".lgot", (sht_progbits, Nat_big_num.add (Nat_big_num.add shf_alloc shf_write) shf_abi_amd64_large)) - ; (".lplt", (sht_progbits, Nat_big_num.add (Nat_big_num.add shf_alloc shf_execinstr) shf_abi_amd64_large)) - ; (".lrodata", (sht_progbits, Nat_big_num.add shf_alloc shf_abi_amd64_large)) - ; (".lrodata1", (sht_progbits, Nat_big_num.add shf_alloc shf_abi_amd64_large)) - ; (".ltext", (sht_progbits, Nat_big_num.add (Nat_big_num.add shf_alloc shf_execinstr) shf_abi_amd64_large)) - ]) diff --git a/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_serialisation.ml b/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_serialisation.ml deleted file mode 100644 index 6656e896..00000000 --- a/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_serialisation.ml +++ /dev/null @@ -1,282 +0,0 @@ -(*Generated by Lem from abis/amd64/abi_amd64_serialisation.lem.*) -(** [abi_amd64_serialisation] contains code for producing an AMD64 conformant - * ELF file from executable (machine) code. - * Used in ongoing experiments with CakeML. - * - * XXX: experimental, and outdated. Commented out for now until attention turns - * to CakeML again. - *) - -open Lem_basic_classes -open Lem_list -open Lem_maybe -open Lem_num - -open Byte_sequence -open Missing_pervasives - -open Memory_image -open Elf_file -open Elf_header -open Elf_interpreted_segment -open Elf_program_header_table -open Elf_section_header_table -open Elf_types_native_uint - -open Abi_amd64_elf_header - -(* -(** [abi_amd64_elf_ident abi_version] produces the ELF identification field for - * the ELF header based on ABI-specific information and the [abi_version] - * argument passed in. - *) -val abi_amd64_elf_ident : natural -> list unsigned_char -let abi_amd64_elf_ident abi_version = - List.map unsigned_char_of_natural - [127; 69; 76; 70; (* 127 E L F *) - abi_amd64_file_class; abi_amd64_data_encoding; abi_amd64_file_version; - elf_osabi_none; abi_version; 0; - 0; 0; 0; - 0; 0; 0] - -(** [abi_amd64_generate_elf_header entry phoff phnum] produces an ELF header for - * 64-bit PPC ELF files. The function expects the [entry] address to start - * execution from, the offset of the program header table in [phoff] and the - * number of entries in the program header table in [phnum]. - *) -val abi_amd64_generate_elf_header : elf64_addr -> elf64_off -> elf64_half -> elf64_header -let abi_amd64_generate_elf_header entry phoff phnum = - <| elf64_ident = abi_amd64_elf_ident 0; - elf64_type = elf64_half_of_natural elf_ft_exec; - elf64_machine = elf64_half_of_natural elf_ma_x86_64; - elf64_version = elf64_word_of_natural elf_ev_current; - elf64_entry = entry; - elf64_phoff = phoff; - elf64_shoff = elf64_off_of_natural 0; - elf64_flags = elf64_word_of_natural 0; - elf64_ehsize = elf64_half_of_natural 64; - elf64_phentsize = elf64_half_of_natural 56; - elf64_phnum = phnum; - elf64_shentsize = elf64_half_of_natural 0; - elf64_shnum = elf64_half_of_natural 0; - elf64_shstrndx = elf64_half_of_natural shn_undef - |> - -val elf64_pack_segment_flags : (bool * bool * bool) -> elf64_word -let elf64_pack_segment_flags (r, w, x) = - let xflag = 1 * natural_of_bool x in - let wflag = 2 * natural_of_bool w in - let rflag = 4 * natural_of_bool r in - elf64_word_of_natural (xflag + wflag + rflag) - -val elf64_header_size : natural -let elf64_header_size = 64 - -val elf64_program_header_table_entry_size : natural -let elf64_program_header_table_entry_size = 56 - -val exec_entry_offset : natural -let exec_entry_offset = - elf64_header_size + (elf64_program_header_table_entry_size * 3) - -val code_heap_entry_offset : natural -> natural -let code_heap_entry_offset exec_size = - elf64_header_size + (elf64_program_header_table_entry_size * 3) + exec_size - -val data_heap_entry_offset : natural -> natural -> natural -let data_heap_entry_offset exec_size code_heap_size = - elf64_header_size + (elf64_program_header_table_entry_size * 3) + exec_size + code_heap_size - -val abi_amd64_generate_program_header_table : elf64_interpreted_segment -> elf64_interpreted_segment -> elf64_interpreted_segment -> elf64_program_header_table -let abi_amd64_generate_program_header_table exec code_heap data_heap = - (* exec segment and then base *) - let exec_header = - <| elf64_p_type = elf64_word_of_natural exec.elf64_segment_type; - elf64_p_flags = elf64_pack_segment_flags exec.elf64_segment_flags; - elf64_p_offset = elf64_off_of_natural exec.elf64_segment_offset; - elf64_p_vaddr = elf64_addr_of_natural exec.elf64_segment_base; - elf64_p_paddr = elf64_addr_of_natural exec.elf64_segment_paddr; - elf64_p_filesz = elf64_xword_of_natural exec.elf64_segment_size; - elf64_p_memsz = elf64_xword_of_natural exec.elf64_segment_memsz; - elf64_p_align = elf64_xword_of_natural exec.elf64_segment_align |> - in - let code_heap_header = - <| elf64_p_type = elf64_word_of_natural code_heap.elf64_segment_type; - elf64_p_flags = elf64_pack_segment_flags code_heap.elf64_segment_flags; - elf64_p_offset = elf64_off_of_natural code_heap.elf64_segment_offset; - elf64_p_vaddr = elf64_addr_of_natural code_heap.elf64_segment_base; - elf64_p_paddr = elf64_addr_of_natural code_heap.elf64_segment_paddr; - elf64_p_filesz = elf64_xword_of_natural code_heap.elf64_segment_size; - elf64_p_memsz = elf64_xword_of_natural code_heap.elf64_segment_memsz; - elf64_p_align = elf64_xword_of_natural code_heap.elf64_segment_align |> - in - let data_heap_header = - <| elf64_p_type = elf64_word_of_natural data_heap.elf64_segment_type; - elf64_p_flags = elf64_pack_segment_flags data_heap.elf64_segment_flags; - elf64_p_offset = elf64_off_of_natural data_heap.elf64_segment_offset; - elf64_p_vaddr = elf64_addr_of_natural data_heap.elf64_segment_base; - elf64_p_paddr = elf64_addr_of_natural data_heap.elf64_segment_paddr; - elf64_p_filesz = elf64_xword_of_natural data_heap.elf64_segment_size; - elf64_p_memsz = elf64_xword_of_natural data_heap.elf64_segment_memsz; - elf64_p_align = elf64_xword_of_natural data_heap.elf64_segment_align |> - in - [exec_header; code_heap_header; data_heap_header] - -val abi_amd64_generate_exec_interpreted_segment : natural -> natural -> byte_sequence -> elf64_interpreted_segment -let abi_amd64_generate_exec_interpreted_segment vma offset exec_code = - let segment_size = Byte_sequence.length exec_code in - <| elf64_segment_body = exec_code; - elf64_segment_size = segment_size; - elf64_segment_memsz = segment_size; - elf64_segment_base = vma; - elf64_segment_paddr = 0; - elf64_segment_align = abi_amd64_page_size_max; - elf64_segment_flags = (true, false, true); - elf64_segment_type = elf_pt_load; - elf64_segment_offset = offset - |> - -val abi_amd64_generate_code_heap_interpreted_segment : natural -> natural -> natural -> elf64_interpreted_segment -let abi_amd64_generate_code_heap_interpreted_segment vma offset segment_size = - let seg = Byte_sequence.create segment_size Missing_pervasives.null_byte in - <| elf64_segment_body = seg; - elf64_segment_size = segment_size; - elf64_segment_memsz = segment_size; - elf64_segment_base = vma; - elf64_segment_paddr = 0; - elf64_segment_align = abi_amd64_page_size_max; - elf64_segment_flags = (true, true, true); - elf64_segment_type = elf_pt_load; - elf64_segment_offset = offset - |> - -val abi_amd64_entry_point_addr : natural -let abi_amd64_entry_point_addr = 4194304 (* 0x400000 *) - -val abi_amd64_code_heap_addr : natural -let abi_amd64_code_heap_addr = 67108864 (* 16 * 4194304 *) - -val abi_amd64_data_heap_addr : natural -let abi_amd64_data_heap_addr = 67108864 * 16 - -val quad_le_bytes_of_natural : natural -> byte * byte * byte * byte -let quad_le_bytes_of_natural m = - let conv = elf64_addr_of_natural m in - let b0 = byte_of_natural (natural_of_elf64_addr (elf64_addr_land conv (elf64_addr_of_natural 255))) in - let b1 = byte_of_natural (natural_of_elf64_addr (elf64_addr_land (elf64_addr_rshift conv 8) (elf64_addr_of_natural 255))) in - let b2 = byte_of_natural (natural_of_elf64_addr (elf64_addr_land (elf64_addr_rshift conv 16) (elf64_addr_of_natural 255))) in - let b3 = byte_of_natural (natural_of_elf64_addr (elf64_addr_land (elf64_addr_rshift conv 24) (elf64_addr_of_natural 255))) in - (b0, b1, b2, b3) - -val abi_amd64_generate_data_heap_interpreted_segment : natural -> natural -> natural -> natural -> elf64_interpreted_segment -let abi_amd64_generate_data_heap_interpreted_segment vma off segment_size code_heap_size = - let (d0, d1, d2, d3) = quad_le_bytes_of_natural segment_size in - let (c0, c1, c2, c3) = quad_le_bytes_of_natural abi_amd64_code_heap_addr in - let (sz0, sz1, sz2, sz3) = quad_le_bytes_of_natural code_heap_size in - let (pc0, pc1, pc2, pc3) = quad_le_bytes_of_natural 0 in - let (gc0, gc1, gc2, gc3) = quad_le_bytes_of_natural 0 in - let preamble = Byte_sequence.from_byte_lists [[ - d0; d1; d2; d3; null_byte; null_byte; null_byte; null_byte; - c0; c1; c2; c3; null_byte; null_byte; null_byte; null_byte; - sz0; sz1; sz2; sz3; null_byte; null_byte; null_byte; null_byte; - pc0; pc1; pc2; pc3; null_byte; null_byte; null_byte; null_byte; - gc0; gc1; gc2; gc3; null_byte; null_byte; null_byte; null_byte - ]] in - <| elf64_segment_body = preamble; - elf64_segment_size = Byte_sequence.length preamble; - elf64_segment_memsz = max segment_size (Byte_sequence.length preamble); - elf64_segment_base = vma; - elf64_segment_paddr = 0; - elf64_segment_align = abi_amd64_page_size_max; - elf64_segment_flags = (true, true, false); - elf64_segment_type = elf_pt_load; - elf64_segment_offset = off - |> - -val init_data_heap_instrs : byte_sequence -let init_data_heap_instrs = - let (b0, b1, b2, b3) = quad_le_bytes_of_natural abi_amd64_data_heap_addr in - Byte_sequence.from_byte_lists - [[ byte_of_natural 72 - ; byte_of_natural 199 - ; byte_of_natural 68 - ; byte_of_natural 36 - ; byte_of_natural 248 - ; b0 - ; b1 - ; b2 - ; b3 - ; byte_of_natural 72 - ; byte_of_natural 139 - ; byte_of_natural 68 - ; byte_of_natural 36 - ; byte_of_natural 248 - ]] - -val exit_syscall_instrs : byte_sequence -let exit_syscall_instrs = - Byte_sequence.from_byte_lists - [[ - byte_of_natural 72; - byte_of_natural 199; - byte_of_natural 192; - byte_of_natural 60; - byte_of_natural 0; - byte_of_natural 0; - byte_of_natural 0; - byte_of_natural 15; - byte_of_natural 5 - ]] - -val push_instr : natural -> byte_sequence -let push_instr addr = - let (b0, b1, b2, b3) = quad_le_bytes_of_natural addr in - Byte_sequence.from_byte_lists [[ - byte_of_natural 104; - b0; b1; b2; b3 - ]] - -val setup_return_code_instr : byte_sequence -let setup_return_code_instr = - Byte_sequence.from_byte_lists [[ - byte_of_natural 191; - byte_of_natural 0; - byte_of_natural 0; - byte_of_natural 0; - byte_of_natural 0 - ]] - -val abi_amd64_generate_executable_file : byte_sequence -> natural -> natural -> elf64_file -let abi_amd64_generate_executable_file exec_code code_heap_size data_heap_size = - let exec_code' = Byte_sequence.concat [ - init_data_heap_instrs; - exec_code - ] in - let pre_entry = 5 + abi_amd64_entry_point_addr + Byte_sequence.length exec_code' in - let exec_code = Byte_sequence.concat [push_instr pre_entry; exec_code'; setup_return_code_instr; exit_syscall_instrs] in - let hdr = abi_amd64_generate_elf_header - (elf64_addr_of_natural abi_amd64_entry_point_addr) - (elf64_off_of_natural 64) (elf64_half_of_natural 3) in - let exec_off_i = 64 + 3 * 56 in - let exec_off_adj = compute_virtual_address_adjustment abi_amd64_page_size_max exec_off_i abi_amd64_entry_point_addr in - let exec_off = exec_off_i + exec_off_adj in - let exec = abi_amd64_generate_exec_interpreted_segment - abi_amd64_entry_point_addr exec_off exec_code in - let code_off_i = exec_off + exec.elf64_segment_size in - let code_off_adj = compute_virtual_address_adjustment abi_amd64_page_size_max code_off_i abi_amd64_code_heap_addr in - let code_off = code_off_i + code_off_adj in - let code_heap = abi_amd64_generate_code_heap_interpreted_segment - abi_amd64_code_heap_addr code_off code_heap_size in - let data_off_i = code_off + code_heap.elf64_segment_size in - let data_off_adj = compute_virtual_address_adjustment abi_amd64_page_size_max data_off_i abi_amd64_data_heap_addr in - let data_off = data_off_i + data_off_adj in - let data_heap = abi_amd64_generate_data_heap_interpreted_segment - abi_amd64_data_heap_addr data_off data_heap_size code_heap_size in - let pht = abi_amd64_generate_program_header_table - exec code_heap data_heap in - <| elf64_file_header = hdr; elf64_file_program_header_table = pht; - elf64_file_interpreted_segments = [exec; code_heap; data_heap]; - elf64_file_interpreted_sections = []; - elf64_file_section_header_table = []; - elf64_file_bits_and_bobs = [] |> -*) diff --git a/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_symbol_table.ml b/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_symbol_table.ml deleted file mode 100644 index 47b05e4c..00000000 --- a/lib/ocaml_rts/linksem/abis/amd64/abi_amd64_symbol_table.ml +++ /dev/null @@ -1,22 +0,0 @@ -(*Generated by Lem from abis/amd64/abi_amd64_symbol_table.lem.*) -(** [abi_amd64_symbol_table], AMD64 ABI specific definitions for the ELF symbol - * table. - *) - -open Lem_basic_classes -open Lem_num -open Gnu_ext_abi - -(** AMD64 specific symbol types. See doc/ifunc.txt and Section 4.3 of the - * ABI. - *) - -(** [string_of_abi_amd64_symbol_type m] produces a string based representation - * of AMD64 symbol type [m]. - *) -(*val string_of_abi_amd64_symbol_type : natural -> string*) -let string_of_abi_amd64_symbol_type m:string= - (if Nat_big_num.equal m stt_gnu_ifunc then - "GNU_IFUNC" - else - "Invalid AMD64 symbol type") diff --git a/lib/ocaml_rts/linksem/abis/mips64/abi_mips64.ml b/lib/ocaml_rts/linksem/abis/mips64/abi_mips64.ml deleted file mode 100644 index 9e86b537..00000000 --- a/lib/ocaml_rts/linksem/abis/mips64/abi_mips64.ml +++ /dev/null @@ -1,88 +0,0 @@ -(*Generated by Lem from abis/mips64/abi_mips64.lem.*) -(** [abi_mips64] contains top-level definition for the MIPS64 ABI. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_list -open Lem_num -open Lem_maybe -open Error -open Lem_map -open Lem_assert_extra - -open Missing_pervasives -open Elf_header -open Elf_types_native_uint -open Elf_file -open Elf_interpreted_segment -open Elf_interpreted_section - -open Endianness -open Memory_image -(* open import Elf_memory_image *) - -open Abi_classes -(*open import Abi_mips64_relocation*) -open Abi_mips64_elf_header - -(** [abi_mips64_compute_program_entry_point segs entry] computes the program - * entry point using ABI-specific conventions. On MIPS64 the entry point in - * the ELF header ([entry] here) is the real entry point. On other ABIs, e.g. - * PowerPC64, the entry point [entry] is a pointer into one of the segments - * constituting the process image (passed in as [segs] here for a uniform - * interface). - *) -(*val abi_mips64_compute_program_entry_point : list elf64_interpreted_segments -> elf64_addr -> error natural*) -let abi_mips64_compute_program_entry_point segs entry:(Nat_big_num.num)error= - (return (Ml_bindings.nat_big_num_of_uint64 entry)) - -(*val header_is_mips64 : elf64_header -> bool*) -let header_is_mips64 h:bool= - (is_valid_elf64_header h - && ((Lem.option_equal (=) (Lem_list.list_index h.elf64_ident (Nat_big_num.to_int elf_ii_data)) (Some (Uint32.of_string (Nat_big_num.to_string elf_data_2msb)))) - && (is_valid_abi_mips64_machine_architecture (Nat_big_num.of_string (Uint32.to_string h.elf64_machine)) - && is_valid_abi_mips64_magic_number h.elf64_ident))) - -type 'abifeature plt_entry_address_fn = Nat_big_num.num (* offset in PLT? *) -> 'abifeature annotated_memory_image (* img *) -> Nat_big_num.num (* addr *) - -type 'abifeature mips64_abi_feature = - GOT1 of ( (string * ( symbol_definition option))list) - | PLT1 of ( (string * ( symbol_definition option) * 'abifeature plt_entry_address_fn)list) - -(*val abiFeatureCompare : forall 'abifeature. mips64_abi_feature 'abifeature -> mips64_abi_feature 'abifeature -> Basic_classes.ordering*) -let abiFeatureCompare1 f1 f2:int= - ((match (f1, f2) with - (GOT1(_), GOT1(_)) -> 0 - | (GOT1(_), PLT1(_)) -> (-1) - | (PLT1(_), PLT1(_)) -> 0 - | (PLT1(_), GOT1(_)) -> 1 - )) - -(*val abiFeatureTagEq : forall 'abifeature. mips64_abi_feature 'abifeature -> mips64_abi_feature 'abifeature -> bool*) -let abiFeatureTagEq1 f1 f2:bool= - ((match (f1, f2) with - (GOT1(_), GOT1(_)) -> true - | (PLT1(_), PLT1(_)) -> true - | (_, _) -> false - )) - -let instance_Abi_classes_AbiFeatureTagEquiv_Abi_mips64_mips64_abi_feature_dict:('abifeature mips64_abi_feature)abiFeatureTagEquiv_class= ({ - - abiFeatureTagEquiv_method = abiFeatureTagEq1}) - -let instance_Basic_classes_Ord_Abi_mips64_mips64_abi_feature_dict:('abifeature mips64_abi_feature)ord_class= ({ - - compare_method = abiFeatureCompare1; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(abiFeatureCompare1 f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (abiFeatureCompare1 f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(abiFeatureCompare1 f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (abiFeatureCompare1 f1 f2)(Pset.from_list compare [1; 0])))}) - -(*val section_is_special : forall 'abifeature. elf64_interpreted_section -> annotated_memory_image 'abifeature -> bool*) -let section_is_special2 s img2:bool= - (elf_section_is_special s img2) diff --git a/lib/ocaml_rts/linksem/abis/mips64/abi_mips64_elf_header.ml b/lib/ocaml_rts/linksem/abis/mips64/abi_mips64_elf_header.ml deleted file mode 100644 index 90193916..00000000 --- a/lib/ocaml_rts/linksem/abis/mips64/abi_mips64_elf_header.ml +++ /dev/null @@ -1,59 +0,0 @@ -(*Generated by Lem from abis/mips64/abi_mips64_elf_header.lem.*) -(** [abi_mips64_elf_header] contains types and definitions relating to ABI - * specific ELF header functionality for the MIPS64 ABI. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_list -open Lem_num -open Lem_maybe -open Missing_pervasives - -open Elf_header -open Elf_types_native_uint - -open Endianness - -(*val abi_mips64_data_encoding : natural*) -let abi_mips64_data_encoding:Nat_big_num.num= elf_data_2msb - -(*val abi_mips64_endianness : endianness*) -let abi_mips64_endianness:endianness= Big (* Must match above *) - -(*val abi_mips64_file_class : natural*) -let abi_mips64_file_class:Nat_big_num.num= elf_class_64 - -(*val abi_mips64_file_version : natural*) -let abi_mips64_file_version:Nat_big_num.num= elf_ev_current - -(*val abi_mips64_page_size_min : natural*) -let abi_mips64_page_size_min:Nat_big_num.num= (Nat_big_num.of_int 4096) - -(*val abi_mips64_page_size_max : natural*) -let abi_mips64_page_size_max:Nat_big_num.num= (Nat_big_num.of_int 65536) - -(** [is_valid_abi_mips64_machine_architecture m] checks whether the ELF header's - * machine architecture is valid according to the ABI-specific specification. - *) -(*val is_valid_abi_mips64_machine_architecture : natural -> bool*) -let is_valid_abi_mips64_machine_architecture m:bool= (Nat_big_num.equal - m elf_ma_mips) - -(** [is_valid_abi_mips64_magic_number magic] checks whether the ELF header's - * magic number is valid according to the ABI-specific specification. - * File class must be 64-bit (pg 60) - * Data encoding must be little endian (pg 60) - *) -(*val is_valid_abi_mips64_magic_number : list unsigned_char -> bool*) -let is_valid_abi_mips64_magic_number magic:bool= - ((match Lem_list.list_index magic (Nat_big_num.to_int elf_ii_class) with - | None -> false - | Some cls -> - (match Lem_list.list_index magic (Nat_big_num.to_int elf_ii_data) with - | None -> false - | Some data -> - ( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string cls)) abi_mips64_file_class) && - ( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string data)) abi_mips64_data_encoding) - ) - )) diff --git a/lib/ocaml_rts/linksem/abis/mips64/abi_mips64_program_header_table.ml b/lib/ocaml_rts/linksem/abis/mips64/abi_mips64_program_header_table.ml deleted file mode 100644 index d1a4a1fa..00000000 --- a/lib/ocaml_rts/linksem/abis/mips64/abi_mips64_program_header_table.ml +++ /dev/null @@ -1,38 +0,0 @@ -(*Generated by Lem from abis/mips64/abi_mips64_program_header_table.lem.*) -(** [abi_mips64_program_header_table], program header table specific definitions - * for the MIPS64 ABI. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_num -open Lem_string - -(** New segment types. *) - -(** The segment contains the stack unwind tables *) -let abi_mips64_pt_gnu_eh_frame : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 842691240)) (* 0x6474e550 *) -let abi_mips64_pt_sunw_eh_frame : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 842691240)) (* 0x6474e550 *) -let abi_mips64_pt_sunw_unwind : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 842691240)) (* 0x6474e550 *) - -(** [string_of_abi_mips64_elf_segment_type m] produces a string based representation - * of MIPS64 segment type [m]. - *) -(*val string_of_abi_mips64_elf_segment_type : natural -> string*) -let string_of_abi_mips64_elf_segment_type m:string= - (if Nat_big_num.equal m abi_mips64_pt_gnu_eh_frame then - "GNU_EH_FRAME" - else if Nat_big_num.equal m abi_mips64_pt_sunw_eh_frame then - "SUNW_EH_FRAME" - else if Nat_big_num.equal m abi_mips64_pt_sunw_unwind then - "SUNW_UNWIND" - else - "Invalid MIPS64 segment type") - -(** [abi_mips64_is_valid_program_interpreter s] checks whether the program interpreter - * string is valid for MIPS64 ABI. - * See Section XXX FIXME - *) -(*val abi_mips64_is_valid_program_interpreter : string -> bool*) -let abi_mips64_is_valid_program_interpreter s:bool= - (s = "/lib/ld64.so.1") diff --git a/lib/ocaml_rts/linksem/abis/mips64/abi_mips64_section_header_table.ml b/lib/ocaml_rts/linksem/abis/mips64/abi_mips64_section_header_table.ml deleted file mode 100644 index 3df8365f..00000000 --- a/lib/ocaml_rts/linksem/abis/mips64/abi_mips64_section_header_table.ml +++ /dev/null @@ -1,37 +0,0 @@ -(*Generated by Lem from abis/mips64/abi_mips64_section_header_table.lem.*) -(** [abi_mips64_section_header_table] module contains section header table - * specific definitions for the MIPS64 ABI. - *) - -open Lem_basic_classes -open Lem_map -open Lem_num - -open Elf_section_header_table - -(** MIPS64 specific flags. See Section XXX FIXME. *) - -(** MIPS64 specific section types. See Section XXX FIXME *) - -(** [string_of_abi_mips64_section_type m] produces a string based representation - * of MIPS64 section type [m]. - *) -(*val string_of_abi_mips64_section_type : natural -> string*) -let string_of_abi_mips64_section_type m:string= - "Invalid MIPS64 section type" - -(** Special sections *) - -(*val abi_mips64_special_sections : Map.map string (natural * natural)*) -let abi_amg64_special_sections0:((string),(Nat_big_num.num*Nat_big_num.num))Pmap.map= - (Lem_map.fromList (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) [ - (".got", (sht_progbits, Nat_big_num.add shf_alloc shf_write)) - ; (".plt", (sht_progbits, Nat_big_num.add shf_alloc shf_execinstr)) - (* FIXME ; (".eh_frame", (sht_abi_mips64_unwind, shf_alloc)) *) - ]) - -(*val abi_mips64_special_sections_large_code_model : Map.map string (natural * natural)*) -let abi_mips64_special_sections_large_code_model:((string),(Nat_big_num.num*Nat_big_num.num))Pmap.map= - (Lem_map.fromList (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) [ - (* FIXME *) - ]) diff --git a/lib/ocaml_rts/linksem/abis/mips64/abi_mips64_serialisation.ml b/lib/ocaml_rts/linksem/abis/mips64/abi_mips64_serialisation.ml deleted file mode 100644 index febc9c30..00000000 --- a/lib/ocaml_rts/linksem/abis/mips64/abi_mips64_serialisation.ml +++ /dev/null @@ -1,282 +0,0 @@ -(*Generated by Lem from abis/mips64/abi_mips64_serialisation.lem.*) -(** [abi_mips64_serialisation] contains code for producing an MIPS64 conformant - * ELF file from executable (machine) code. - * Used in ongoing experiments with CakeML. - * - * XXX: experimental, and outdated. Commented out for now until attention turns - * to CakeML again. - *) - -open Lem_basic_classes -open Lem_list -open Lem_maybe -open Lem_num - -open Byte_sequence -open Missing_pervasives - -open Memory_image -open Elf_file -open Elf_header -open Elf_interpreted_segment -open Elf_program_header_table -open Elf_section_header_table -open Elf_types_native_uint - -open Abi_mips64_elf_header - -(* -(** [abi_mips64_elf_ident abi_version] produces the ELF identification field for - * the ELF header based on ABI-specific information and the [abi_version] - * argument passed in. - *) -val abi_mips64_elf_ident : natural -> list unsigned_char -let abi_mips64_elf_ident abi_version = - List.map unsigned_char_of_natural - [127; 69; 76; 70; (* 127 E L F *) - abi_mips64_file_class; abi_mips64_data_encoding; abi_mips64_file_version; - elf_osabi_none; abi_version; 0; - 0; 0; 0; - 0; 0; 0] - -(** [abi_mips64_generate_elf_header entry phoff phnum] produces an ELF header for - * 64-bit PPC ELF files. The function expects the [entry] address to start - * execution from, the offset of the program header table in [phoff] and the - * number of entries in the program header table in [phnum]. - *) -val abi_mips64_generate_elf_header : elf64_addr -> elf64_off -> elf64_half -> elf64_header -let abi_mips64_generate_elf_header entry phoff phnum = - <| elf64_ident = abi_mips64_elf_ident 0; - elf64_type = elf64_half_of_natural elf_ft_exec; - elf64_machine = elf64_half_of_natural elf_ma_mips; - elf64_version = elf64_word_of_natural elf_ev_current; - elf64_entry = entry; - elf64_phoff = phoff; - elf64_shoff = elf64_off_of_natural 0; - elf64_flags = elf64_word_of_natural 0; - elf64_ehsize = elf64_half_of_natural 64; - elf64_phentsize = elf64_half_of_natural 56; - elf64_phnum = phnum; - elf64_shentsize = elf64_half_of_natural 0; - elf64_shnum = elf64_half_of_natural 0; - elf64_shstrndx = elf64_half_of_natural shn_undef - |> - -val elf64_pack_segment_flags : (bool * bool * bool) -> elf64_word -let elf64_pack_segment_flags (r, w, x) = - let xflag = 1 * natural_of_bool x in - let wflag = 2 * natural_of_bool w in - let rflag = 4 * natural_of_bool r in - elf64_word_of_natural (xflag + wflag + rflag) - -val elf64_header_size : natural -let elf64_header_size = 64 - -val elf64_program_header_table_entry_size : natural -let elf64_program_header_table_entry_size = 56 - -val exec_entry_offset : natural -let exec_entry_offset = - elf64_header_size + (elf64_program_header_table_entry_size * 3) - -val code_heap_entry_offset : natural -> natural -let code_heap_entry_offset exec_size = - elf64_header_size + (elf64_program_header_table_entry_size * 3) + exec_size - -val data_heap_entry_offset : natural -> natural -> natural -let data_heap_entry_offset exec_size code_heap_size = - elf64_header_size + (elf64_program_header_table_entry_size * 3) + exec_size + code_heap_size - -val abi_mips64_generate_program_header_table : elf64_interpreted_segment -> elf64_interpreted_segment -> elf64_interpreted_segment -> elf64_program_header_table -let abi_mips64_generate_program_header_table exec code_heap data_heap = - (* exec segment and then base *) - let exec_header = - <| elf64_p_type = elf64_word_of_natural exec.elf64_segment_type; - elf64_p_flags = elf64_pack_segment_flags exec.elf64_segment_flags; - elf64_p_offset = elf64_off_of_natural exec.elf64_segment_offset; - elf64_p_vaddr = elf64_addr_of_natural exec.elf64_segment_base; - elf64_p_paddr = elf64_addr_of_natural exec.elf64_segment_paddr; - elf64_p_filesz = elf64_xword_of_natural exec.elf64_segment_size; - elf64_p_memsz = elf64_xword_of_natural exec.elf64_segment_memsz; - elf64_p_align = elf64_xword_of_natural exec.elf64_segment_align |> - in - let code_heap_header = - <| elf64_p_type = elf64_word_of_natural code_heap.elf64_segment_type; - elf64_p_flags = elf64_pack_segment_flags code_heap.elf64_segment_flags; - elf64_p_offset = elf64_off_of_natural code_heap.elf64_segment_offset; - elf64_p_vaddr = elf64_addr_of_natural code_heap.elf64_segment_base; - elf64_p_paddr = elf64_addr_of_natural code_heap.elf64_segment_paddr; - elf64_p_filesz = elf64_xword_of_natural code_heap.elf64_segment_size; - elf64_p_memsz = elf64_xword_of_natural code_heap.elf64_segment_memsz; - elf64_p_align = elf64_xword_of_natural code_heap.elf64_segment_align |> - in - let data_heap_header = - <| elf64_p_type = elf64_word_of_natural data_heap.elf64_segment_type; - elf64_p_flags = elf64_pack_segment_flags data_heap.elf64_segment_flags; - elf64_p_offset = elf64_off_of_natural data_heap.elf64_segment_offset; - elf64_p_vaddr = elf64_addr_of_natural data_heap.elf64_segment_base; - elf64_p_paddr = elf64_addr_of_natural data_heap.elf64_segment_paddr; - elf64_p_filesz = elf64_xword_of_natural data_heap.elf64_segment_size; - elf64_p_memsz = elf64_xword_of_natural data_heap.elf64_segment_memsz; - elf64_p_align = elf64_xword_of_natural data_heap.elf64_segment_align |> - in - [exec_header; code_heap_header; data_heap_header] - -val abi_mips64_generate_exec_interpreted_segment : natural -> natural -> byte_sequence -> elf64_interpreted_segment -let abi_mips64_generate_exec_interpreted_segment vma offset exec_code = - let segment_size = Byte_sequence.length exec_code in - <| elf64_segment_body = exec_code; - elf64_segment_size = segment_size; - elf64_segment_memsz = segment_size; - elf64_segment_base = vma; - elf64_segment_paddr = 0; - elf64_segment_align = abi_mips64_page_size_max; - elf64_segment_flags = (true, false, true); - elf64_segment_type = elf_pt_load; - elf64_segment_offset = offset - |> - -val abi_mips64_generate_code_heap_interpreted_segment : natural -> natural -> natural -> elf64_interpreted_segment -let abi_mips64_generate_code_heap_interpreted_segment vma offset segment_size = - let seg = Byte_sequence.create segment_size Missing_pervasives.null_byte in - <| elf64_segment_body = seg; - elf64_segment_size = segment_size; - elf64_segment_memsz = segment_size; - elf64_segment_base = vma; - elf64_segment_paddr = 0; - elf64_segment_align = abi_mips64_page_size_max; - elf64_segment_flags = (true, true, true); - elf64_segment_type = elf_pt_load; - elf64_segment_offset = offset - |> - -val abi_mips64_entry_point_addr : natural -let abi_mips64_entry_point_addr = 4194304 (* 0x400000 *) - -val abi_mips64_code_heap_addr : natural -let abi_mips64_code_heap_addr = 67108864 (* 16 * 4194304 *) - -val abi_mips64_data_heap_addr : natural -let abi_mips64_data_heap_addr = 67108864 * 16 - -val quad_le_bytes_of_natural : natural -> byte * byte * byte * byte -let quad_le_bytes_of_natural m = - let conv = elf64_addr_of_natural m in - let b0 = byte_of_natural (natural_of_elf64_addr (elf64_addr_land conv (elf64_addr_of_natural 255))) in - let b1 = byte_of_natural (natural_of_elf64_addr (elf64_addr_land (elf64_addr_rshift conv 8) (elf64_addr_of_natural 255))) in - let b2 = byte_of_natural (natural_of_elf64_addr (elf64_addr_land (elf64_addr_rshift conv 16) (elf64_addr_of_natural 255))) in - let b3 = byte_of_natural (natural_of_elf64_addr (elf64_addr_land (elf64_addr_rshift conv 24) (elf64_addr_of_natural 255))) in - (b0, b1, b2, b3) - -val abi_mips64_generate_data_heap_interpreted_segment : natural -> natural -> natural -> natural -> elf64_interpreted_segment -let abi_mips64_generate_data_heap_interpreted_segment vma off segment_size code_heap_size = - let (d0, d1, d2, d3) = quad_le_bytes_of_natural segment_size in - let (c0, c1, c2, c3) = quad_le_bytes_of_natural abi_mips64_code_heap_addr in - let (sz0, sz1, sz2, sz3) = quad_le_bytes_of_natural code_heap_size in - let (pc0, pc1, pc2, pc3) = quad_le_bytes_of_natural 0 in - let (gc0, gc1, gc2, gc3) = quad_le_bytes_of_natural 0 in - let preamble = Byte_sequence.from_byte_lists [[ - d0; d1; d2; d3; null_byte; null_byte; null_byte; null_byte; - c0; c1; c2; c3; null_byte; null_byte; null_byte; null_byte; - sz0; sz1; sz2; sz3; null_byte; null_byte; null_byte; null_byte; - pc0; pc1; pc2; pc3; null_byte; null_byte; null_byte; null_byte; - gc0; gc1; gc2; gc3; null_byte; null_byte; null_byte; null_byte - ]] in - <| elf64_segment_body = preamble; - elf64_segment_size = Byte_sequence.length preamble; - elf64_segment_memsz = max segment_size (Byte_sequence.length preamble); - elf64_segment_base = vma; - elf64_segment_paddr = 0; - elf64_segment_align = abi_mips64_page_size_max; - elf64_segment_flags = (true, true, false); - elf64_segment_type = elf_pt_load; - elf64_segment_offset = off - |> - -val init_data_heap_instrs : byte_sequence -let init_data_heap_instrs = - let (b0, b1, b2, b3) = quad_le_bytes_of_natural abi_mips64_data_heap_addr in - Byte_sequence.from_byte_lists - [[ byte_of_natural 72 - ; byte_of_natural 199 - ; byte_of_natural 68 - ; byte_of_natural 36 - ; byte_of_natural 248 - ; b0 - ; b1 - ; b2 - ; b3 - ; byte_of_natural 72 - ; byte_of_natural 139 - ; byte_of_natural 68 - ; byte_of_natural 36 - ; byte_of_natural 248 - ]] - -val exit_syscall_instrs : byte_sequence -let exit_syscall_instrs = - Byte_sequence.from_byte_lists - [[ - byte_of_natural 72; - byte_of_natural 199; - byte_of_natural 192; - byte_of_natural 60; - byte_of_natural 0; - byte_of_natural 0; - byte_of_natural 0; - byte_of_natural 15; - byte_of_natural 5 - ]] - -val push_instr : natural -> byte_sequence -let push_instr addr = - let (b0, b1, b2, b3) = quad_le_bytes_of_natural addr in - Byte_sequence.from_byte_lists [[ - byte_of_natural 104; - b0; b1; b2; b3 - ]] - -val setup_return_code_instr : byte_sequence -let setup_return_code_instr = - Byte_sequence.from_byte_lists [[ - byte_of_natural 191; - byte_of_natural 0; - byte_of_natural 0; - byte_of_natural 0; - byte_of_natural 0 - ]] - -val abi_mips64_generate_executable_file : byte_sequence -> natural -> natural -> elf64_file -let abi_mips64_generate_executable_file exec_code code_heap_size data_heap_size = - let exec_code' = Byte_sequence.concat [ - init_data_heap_instrs; - exec_code - ] in - let pre_entry = 5 + abi_mips64_entry_point_addr + Byte_sequence.length exec_code' in - let exec_code = Byte_sequence.concat [push_instr pre_entry; exec_code'; setup_return_code_instr; exit_syscall_instrs] in - let hdr = abi_mips64_generate_elf_header - (elf64_addr_of_natural abi_mips64_entry_point_addr) - (elf64_off_of_natural 64) (elf64_half_of_natural 3) in - let exec_off_i = 64 + 3 * 56 in - let exec_off_adj = compute_virtual_address_adjustment abi_mips64_page_size_max exec_off_i abi_mips64_entry_point_addr in - let exec_off = exec_off_i + exec_off_adj in - let exec = abi_mips64_generate_exec_interpreted_segment - abi_mips64_entry_point_addr exec_off exec_code in - let code_off_i = exec_off + exec.elf64_segment_size in - let code_off_adj = compute_virtual_address_adjustment abi_mips64_page_size_max code_off_i abi_mips64_code_heap_addr in - let code_off = code_off_i + code_off_adj in - let code_heap = abi_mips64_generate_code_heap_interpreted_segment - abi_mips64_code_heap_addr code_off code_heap_size in - let data_off_i = code_off + code_heap.elf64_segment_size in - let data_off_adj = compute_virtual_address_adjustment abi_mips64_page_size_max data_off_i abi_mips64_data_heap_addr in - let data_off = data_off_i + data_off_adj in - let data_heap = abi_mips64_generate_data_heap_interpreted_segment - abi_mips64_data_heap_addr data_off data_heap_size code_heap_size in - let pht = abi_mips64_generate_program_header_table - exec code_heap data_heap in - <| elf64_file_header = hdr; elf64_file_program_header_table = pht; - elf64_file_interpreted_segments = [exec; code_heap; data_heap]; - elf64_file_interpreted_sections = []; - elf64_file_section_header_table = []; - elf64_file_bits_and_bobs = [] |> -*) diff --git a/lib/ocaml_rts/linksem/abis/mips64/abi_mips64_symbol_table.ml b/lib/ocaml_rts/linksem/abis/mips64/abi_mips64_symbol_table.ml deleted file mode 100644 index 4889556b..00000000 --- a/lib/ocaml_rts/linksem/abis/mips64/abi_mips64_symbol_table.ml +++ /dev/null @@ -1,22 +0,0 @@ -(*Generated by Lem from abis/mips64/abi_mips64_symbol_table.lem.*) -(** [abi_mips64_symbol_table], MIPS64 ABI specific definitions for the ELF symbol - * table. - *) - -open Lem_basic_classes -open Lem_num -open Gnu_ext_abi - -(** MIPS64 specific symbol types. See doc/ifunc.txt and Section XXX FIXME of the - * ABI. - *) - -(** [string_of_abi_mips64_symbol_type m] produces a string based representation - * of MIPS64 symbol type [m]. - *) -(*val string_of_abi_mips64_symbol_type : natural -> string*) -let string_of_abi_mips64_symbol_type m:string= - (if Nat_big_num.equal m stt_gnu_ifunc then - "GNU_IFUNC" - else - "Invalid MIPS64 symbol type") diff --git a/lib/ocaml_rts/linksem/abis/power64/abi_power64.ml b/lib/ocaml_rts/linksem/abis/power64/abi_power64.ml deleted file mode 100644 index aea13a79..00000000 --- a/lib/ocaml_rts/linksem/abis/power64/abi_power64.ml +++ /dev/null @@ -1,46 +0,0 @@ -(*Generated by Lem from abis/power64/abi_power64.lem.*) -(** [abi_power64] contains top-level definition for the PowerPC64 ABI. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_list -open Lem_num -open Lem_maybe - -open Byte_sequence -open Error -open Missing_pervasives - -open Elf_header -open Elf_types_native_uint -open Elf_file -open Elf_interpreted_segment - -(** [abi_power64_compute_program_entry_point segs entry] computes the program - * entry point using ABI-specific conventions. On Power64 the entry point in - * the ELF header ([entry] here) is a pointer into a program segment that - * contains the "real" entry point. On other ABIs, e.g. - * AArch64 and AMD64, the entry point in the ELF header [entry] is the actual - * program entry point. - *) -(*val abi_power64_compute_program_entry_point : list elf64_interpreted_segment -> elf64_addr -> error natural*) -let abi_power64_compute_program_entry_point segs entry:(Nat_big_num.num)error= - (let entry = (Ml_bindings.nat_big_num_of_uint64 entry) in - let filtered = (List.filter ( - fun seg -> - let base = (seg.elf64_segment_base) in - let size2 = (seg.elf64_segment_memsz) in Nat_big_num.less_equal - base entry && Nat_big_num.less_equal entry ( Nat_big_num.add base size2) - ) segs) - in - (match filtered with - | [] -> fail "abi_power64_compute_program_entry_point: no program segment contains the program entry point" - | [x] -> - let rebase = (Nat_big_num.sub_nat entry x.elf64_segment_base) in - Byte_sequence.offset_and_cut rebase(Nat_big_num.of_int 8) x.elf64_segment_body >>= (fun bytes -> - Byte_sequence.read_8_bytes_le bytes >>= (fun (bytes, _) -> - let (b1,b2,b3,b4,b5,b6,b7,b8) = bytes in - return (Ml_bindings.nat_big_num_of_uint64 (Uint64_wrapper.of_oct_native b1 b2 b3 b4 b5 b6 b7 b8)))) - | _ -> fail "abi_power64_compute_program_entry_point: multiple program segments contain the program entry point" - )) diff --git a/lib/ocaml_rts/linksem/abis/power64/abi_power64_dynamic.ml b/lib/ocaml_rts/linksem/abis/power64/abi_power64_dynamic.ml deleted file mode 100644 index b26d841f..00000000 --- a/lib/ocaml_rts/linksem/abis/power64/abi_power64_dynamic.ml +++ /dev/null @@ -1,40 +0,0 @@ -(*Generated by Lem from abis/power64/abi_power64_dynamic.lem.*) -open Lem_basic_classes -open Lem_num -open Lem_string - -open Error -open Show -open String_table - -open Elf_dynamic -open Elf_types_native_uint - -let abi_power64_dt_ppcgot : Nat_big_num.num= ( Nat_big_num.mul(Nat_big_num.of_int 939524096)(Nat_big_num.of_int 2)) (* 0x70000000 *) - -(*val string_of_abi_power64_dynamic_tag : natural -> string*) -let string_of_abi_power64_dynamic_tag m:string= - (if Nat_big_num.equal m abi_power64_dt_ppcgot then - "PPC64_GLINK" - else - "Invalid Power64 dynamic tag") - -(*val abi_power64_tag_correspondence_of_tag : natural -> error tag_correspondence*) -let abi_power64_tag_correspondence_of_tag m:(tag_correspondence)error= - (if Nat_big_num.equal m abi_power64_dt_ppcgot then - return C_Ptr - else - fail ("abi_power64_tag_correspondence_of_tag: invalid Power64 dynamic tag")) - -(*val abi_power64_elf64_value_of_elf64_dyn : elf64_dyn -> string_table -> error elf64_dyn_value*) -let abi_power64_elf64_value_of_elf64_dyn dyn stbl:(((Uint64.uint64),(Uint64.uint64))dyn_value)error= - (let tag = (Nat_big_num.abs (Nat_big_num.of_int64 dyn.elf64_dyn_tag)) in - if Nat_big_num.equal tag abi_power64_dt_ppcgot then - (match dyn.elf64_dyn_d_un with - | D_Val v -> fail "abi_power64_elf64_value_of_elf64_dyn: PPC_GOT must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "abi_power64_elf64_value_of_elf64_dyn: PPC_GOT must be a PTR" - ) >>= (fun addr -> - return (Address addr)) - else - fail ("abi_power64_elf64_value_of_elf64_dyn: invalid Power64 dynamic tag")) diff --git a/lib/ocaml_rts/linksem/abis/power64/abi_power64_elf_header.ml b/lib/ocaml_rts/linksem/abis/power64/abi_power64_elf_header.ml deleted file mode 100644 index 83826f85..00000000 --- a/lib/ocaml_rts/linksem/abis/power64/abi_power64_elf_header.ml +++ /dev/null @@ -1,48 +0,0 @@ -(*Generated by Lem from abis/power64/abi_power64_elf_header.lem.*) -(** [abi_power64_elf_header], Power64 ABI specific definitions related to the - * ELF file header. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_list -open Lem_maybe -open Missing_pervasives - -open Elf_header -open Elf_types_native_uint - -open Endianness - -(** [is_valid_abi_power64_machine_architecture m] checks whether the ELF header's - * machine architecture is valid according to the ABI-specific specification. - * Machine architecture must be Power64 (Section 4.1). - *) -(*val is_valid_abi_power64_machine_architecture : nat -> bool*) -let is_valid_abi_power64_machine_architecture m:bool= - (m = Nat_big_num.to_int elf_ma_ppc64) - -(** [is_valid_abi_power64_magic_number magic] checks whether the ELF header's - * magic number is valid according to the ABI-specific specification. - * File class must be 64-bit (Section 4.1) - * Data encoding must be little or big endian and must match the data encoding - * of the file. (Section 4.1) - *) -(*val is_valid_abi_power64_magic_number : list unsigned_char -> endianness -> bool*) -let is_valid_abi_power64_magic_number magic endian:bool= - ((match Lem_list.list_index magic (Nat_big_num.to_int elf_ii_class) with - | None -> false - | Some cls -> - (match Lem_list.list_index magic (Nat_big_num.to_int elf_ii_data) with - | None -> false - | Some ed -> - (match endian with - | Little -> - ( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string cls)) elf_class_64) && - ( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string ed)) elf_data_2lsb) - | Big -> - ( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string cls)) elf_class_64) && - ( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string ed)) elf_data_2msb) - ) - ) - )) diff --git a/lib/ocaml_rts/linksem/abis/power64/abi_power64_relocation.ml b/lib/ocaml_rts/linksem/abis/power64/abi_power64_relocation.ml deleted file mode 100644 index af9b7cfe..00000000 --- a/lib/ocaml_rts/linksem/abis/power64/abi_power64_relocation.ml +++ /dev/null @@ -1,833 +0,0 @@ -(*Generated by Lem from abis/power64/abi_power64_relocation.lem.*) -(** [abi_power64_relocation] contains types and definitions specific to - * relocations in the Power64 ABI - *) - -open Lem_basic_classes -open Lem_map -open Lem_maybe -open Lem_num -open Lem_string - -open Error -open Missing_pervasives - -open Elf_types_native_uint -open Elf_file -open Elf_header -open Elf_relocation -open Elf_symbol_table - -open Abi_utilities - -(** Power64 relocation types *) - -let r_ppc64_none : Nat_big_num.num= (Nat_big_num.of_int 0) -let r_ppc64_addr32 : Nat_big_num.num= (Nat_big_num.of_int 1) -let r_ppc64_addr24 : Nat_big_num.num= (Nat_big_num.of_int 2) -let r_ppc64_addr16 : Nat_big_num.num= (Nat_big_num.of_int 3) -let r_ppc64_addr16_lo : Nat_big_num.num= (Nat_big_num.of_int 4) -let r_ppc64_addr16_hi : Nat_big_num.num= (Nat_big_num.of_int 5) -let r_ppc64_addr16_ha : Nat_big_num.num= (Nat_big_num.of_int 6) -let r_ppc64_addr14 : Nat_big_num.num= (Nat_big_num.of_int 7) -let r_ppc64_addr14_brtaken : Nat_big_num.num= (Nat_big_num.of_int 8) -let r_ppc64_addr14_brntaken : Nat_big_num.num= (Nat_big_num.of_int 9) -let r_ppc64_rel24 : Nat_big_num.num= (Nat_big_num.of_int 10) -let r_ppc64_rel14 : Nat_big_num.num= (Nat_big_num.of_int 11) -let r_ppc64_rel14_brtaken : Nat_big_num.num= (Nat_big_num.of_int 12) -let r_ppc64_rel14_brntaken : Nat_big_num.num= (Nat_big_num.of_int 13) -let r_ppc64_got16 : Nat_big_num.num= (Nat_big_num.of_int 14) -let r_ppc64_got16_lo : Nat_big_num.num= (Nat_big_num.of_int 15) -let r_ppc64_got16_hi : Nat_big_num.num= (Nat_big_num.of_int 16) -let r_ppc64_got16_ha : Nat_big_num.num= (Nat_big_num.of_int 17) -let r_ppc64_copy : Nat_big_num.num= (Nat_big_num.of_int 19) -let r_ppc64_glob_dat : Nat_big_num.num= (Nat_big_num.of_int 20) -let r_ppc64_jmp_slot : Nat_big_num.num= (Nat_big_num.of_int 21) -let r_ppc64_relative : Nat_big_num.num= (Nat_big_num.of_int 22) -let r_ppc64_uaddr32 : Nat_big_num.num= (Nat_big_num.of_int 24) -let r_ppc64_uaddr16 : Nat_big_num.num= (Nat_big_num.of_int 25) -let r_ppc64_rel32 : Nat_big_num.num= (Nat_big_num.of_int 26) -let r_ppc64_plt32 : Nat_big_num.num= (Nat_big_num.of_int 27) -let r_ppc64_pltrel32 : Nat_big_num.num= (Nat_big_num.of_int 28) -let r_ppc64_plt16_lo : Nat_big_num.num= (Nat_big_num.of_int 29) -let r_ppc64_plt16_hi : Nat_big_num.num= (Nat_big_num.of_int 30) -let r_ppc64_plt16_ha : Nat_big_num.num= (Nat_big_num.of_int 31) -let r_ppc64_sectoff : Nat_big_num.num= (Nat_big_num.of_int 33) -let r_ppc64_sectoff_lo : Nat_big_num.num= (Nat_big_num.of_int 34) -let r_ppc64_sectoff_hi : Nat_big_num.num= (Nat_big_num.of_int 35) -let r_ppc64_sectoff_ha : Nat_big_num.num= (Nat_big_num.of_int 36) -let r_ppc64_addr30 : Nat_big_num.num= (Nat_big_num.of_int 37) -let r_ppc64_addr64 : Nat_big_num.num= (Nat_big_num.of_int 38) -let r_ppc64_addr16_higher : Nat_big_num.num= (Nat_big_num.of_int 39) -let r_ppc64_addr16_highera : Nat_big_num.num= (Nat_big_num.of_int 40) -let r_ppc64_addr16_highest : Nat_big_num.num= (Nat_big_num.of_int 41) -let r_ppc64_addr16_highesta : Nat_big_num.num= (Nat_big_num.of_int 42) -let r_ppc64_uaddr64 : Nat_big_num.num= (Nat_big_num.of_int 43) -let r_ppc64_rel64 : Nat_big_num.num= (Nat_big_num.of_int 44) -let r_ppc64_plt64 : Nat_big_num.num= (Nat_big_num.of_int 45) -let r_ppc64_pltrel64 : Nat_big_num.num= (Nat_big_num.of_int 46) -let r_ppc64_toc16 : Nat_big_num.num= (Nat_big_num.of_int 47) -let r_ppc64_toc16_lo : Nat_big_num.num= (Nat_big_num.of_int 48) -let r_ppc64_toc16_hi : Nat_big_num.num= (Nat_big_num.of_int 49) -let r_ppc64_toc16_ha : Nat_big_num.num= (Nat_big_num.of_int 50) -let r_ppc64_toc : Nat_big_num.num= (Nat_big_num.of_int 51) -let r_ppc64_pltgot16 : Nat_big_num.num= (Nat_big_num.of_int 52) -let r_ppc64_pltgot16_lo : Nat_big_num.num= (Nat_big_num.of_int 53) -let r_ppc64_pltgot16_hi : Nat_big_num.num= (Nat_big_num.of_int 54) -let r_ppc64_pltgot16_ha : Nat_big_num.num= (Nat_big_num.of_int 55) -let r_ppc64_addr16_ds : Nat_big_num.num= (Nat_big_num.of_int 56) -let r_ppc64_addr16_lo_ds : Nat_big_num.num= (Nat_big_num.of_int 57) -let r_ppc64_got16_ds : Nat_big_num.num= (Nat_big_num.of_int 58) -let r_ppc64_got16_lo_ds : Nat_big_num.num= (Nat_big_num.of_int 59) -let r_ppc64_plt16_lo_ds : Nat_big_num.num= (Nat_big_num.of_int 60) -let r_ppc64_sectoff_ds : Nat_big_num.num= (Nat_big_num.of_int 61) -let r_ppc64_sectoff_lo_ds : Nat_big_num.num= (Nat_big_num.of_int 62) -let r_ppc64_toc16_ds : Nat_big_num.num= (Nat_big_num.of_int 63) -let r_ppc64_toc16_lo_ds : Nat_big_num.num= (Nat_big_num.of_int 64) -let r_ppc64_pltgot16_ds : Nat_big_num.num= (Nat_big_num.of_int 65) -let r_ppc64_pltgot16_lo_ds : Nat_big_num.num= (Nat_big_num.of_int 66) -let r_ppc64_tls : Nat_big_num.num= (Nat_big_num.of_int 67) -let r_ppc64_dtpmod64 : Nat_big_num.num= (Nat_big_num.of_int 68) -let r_ppc64_tprel16 : Nat_big_num.num= (Nat_big_num.of_int 69) -let r_ppc64_tprel16_lo : Nat_big_num.num= (Nat_big_num.of_int 60) -let r_ppc64_tprel16_hi : Nat_big_num.num= (Nat_big_num.of_int 71) -let r_ppc64_tprel16_ha : Nat_big_num.num= (Nat_big_num.of_int 72) -let r_ppc64_tprel64 : Nat_big_num.num= (Nat_big_num.of_int 73) -let r_ppc64_dtprel16 : Nat_big_num.num= (Nat_big_num.of_int 74) -let r_ppc64_dtprel16_lo : Nat_big_num.num= (Nat_big_num.of_int 75) -let r_ppc64_dtprel16_hi : Nat_big_num.num= (Nat_big_num.of_int 76) -let r_ppc64_dtprel16_ha : Nat_big_num.num= (Nat_big_num.of_int 77) -let r_ppc64_dtprel64 : Nat_big_num.num= (Nat_big_num.of_int 78) -let r_ppc64_got_tlsgd16 : Nat_big_num.num= (Nat_big_num.of_int 79) -let r_ppc64_got_tlsgd16_lo : Nat_big_num.num= (Nat_big_num.of_int 80) -let r_ppc64_got_tlsgd16_hi : Nat_big_num.num= (Nat_big_num.of_int 81) -let r_ppc64_got_tlsgd16_ha : Nat_big_num.num= (Nat_big_num.of_int 82) -let r_ppc64_got_tlsld16 : Nat_big_num.num= (Nat_big_num.of_int 83) -let r_ppc64_got_tlsld16_lo : Nat_big_num.num= (Nat_big_num.of_int 84) -let r_ppc64_got_tlsld16_hi : Nat_big_num.num= (Nat_big_num.of_int 85) -let r_ppc64_got_tlsld16_ha : Nat_big_num.num= (Nat_big_num.of_int 86) -let r_ppc64_got_tprel16_ds : Nat_big_num.num= (Nat_big_num.of_int 87) -let r_ppc64_got_tprel16_lo_ds : Nat_big_num.num= (Nat_big_num.of_int 88) -let r_ppc64_got_tprel16_hi : Nat_big_num.num= (Nat_big_num.of_int 89) -let r_ppc64_got_tprel16_ha : Nat_big_num.num= (Nat_big_num.of_int 90) -let r_ppc64_got_dtprel16_ds : Nat_big_num.num= (Nat_big_num.of_int 91) -let r_ppc64_got_dtprel16_lo_ds : Nat_big_num.num= (Nat_big_num.of_int 92) -let r_ppc64_got_dtprel16_hi : Nat_big_num.num= (Nat_big_num.of_int 93) -let r_ppc64_got_dtprel16_ha : Nat_big_num.num= (Nat_big_num.of_int 94) -let r_ppc64_tprel16_ds : Nat_big_num.num= (Nat_big_num.of_int 95) -let r_ppc64_tprel16_lo_ds : Nat_big_num.num= (Nat_big_num.of_int 96) -let r_ppc64_tprel16_higher : Nat_big_num.num= (Nat_big_num.of_int 97) -let r_ppc64_tprel16_highera : Nat_big_num.num= (Nat_big_num.of_int 98) -let r_ppc64_tprel16_highest : Nat_big_num.num= (Nat_big_num.of_int 99) -let r_ppc64_tprel16_highesta : Nat_big_num.num= (Nat_big_num.of_int 100) -let r_ppc64_dtprel16_ds : Nat_big_num.num= (Nat_big_num.of_int 101) -let r_ppc64_dtprel16_lo_ds : Nat_big_num.num= (Nat_big_num.of_int 102) -let r_ppc64_dtprel16_higher : Nat_big_num.num= (Nat_big_num.of_int 103) -let r_ppc64_dtprel16_highera : Nat_big_num.num= (Nat_big_num.of_int 104) -let r_ppc64_dtprel16_highest : Nat_big_num.num= (Nat_big_num.of_int 105) -let r_ppc64_dtprel16_highesta : Nat_big_num.num= (Nat_big_num.of_int 106) - -(** [string_of_ppc64_relocation_type rel_type] produces a string representation - * of relocation type [rel_type]. - *) -(*val string_of_ppc64_relocation_type : natural -> string*) -let string_of_ppc64_relocation_type rel_type1:string= - (if Nat_big_num.equal rel_type1 r_ppc64_none then - "R_PPC64_NONE" - else if Nat_big_num.equal rel_type1 r_ppc64_addr32 then - "R_PPC64_ADDR32" - else if Nat_big_num.equal rel_type1 r_ppc64_addr24 then - "R_PPC64_ADDR24" - else if Nat_big_num.equal rel_type1 r_ppc64_addr16 then - "R_PPC64_ADDR16" - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_lo then - "R_PPC64_ADDR16_LO" - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_hi then - "R_PPC64_ADDR16_HI" - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_ha then - "R_PPC64_ADDR16_HA" - else if Nat_big_num.equal rel_type1 r_ppc64_addr14 then - "R_PPC64_ADDR14" - else if Nat_big_num.equal rel_type1 r_ppc64_addr14_brtaken then - "R_PPC64_ADDR14_BRTAKEN" - else if Nat_big_num.equal rel_type1 r_ppc64_addr14_brntaken then - "R_PPC64_ADDR14_BRNTAKEN" - else if Nat_big_num.equal rel_type1 r_ppc64_rel24 then - "R_PPC64_REL24" - else if Nat_big_num.equal rel_type1 r_ppc64_rel14 then - "R_PPC64_REL14" - else if Nat_big_num.equal rel_type1 r_ppc64_rel14_brtaken then - "R_PPC64_REL14_BRTAKEN" - else if Nat_big_num.equal rel_type1 r_ppc64_rel14_brntaken then - "R_PPC64_REL14_BRNTAKEN" - else if Nat_big_num.equal rel_type1 r_ppc64_got16 then - "R_PPC64_GOT16" - else if Nat_big_num.equal rel_type1 r_ppc64_got16_lo then - "R_PPC64_GOT16_LO" - else if Nat_big_num.equal rel_type1 r_ppc64_got16_hi then - "R_PPC64_GOT16_HI" - else if Nat_big_num.equal rel_type1 r_ppc64_got16_ha then - "R_PPC64_GOT16_HA" - else if Nat_big_num.equal rel_type1 r_ppc64_copy then - "R_PPC64_COPY" - else if Nat_big_num.equal rel_type1 r_ppc64_glob_dat then - "R_PPC64_GLOB_DAT" - else if Nat_big_num.equal rel_type1 r_ppc64_jmp_slot then - "R_PPC64_JMP_SLOT" - else if Nat_big_num.equal rel_type1 r_ppc64_relative then - "R_PPC64_RELATIVE" - else if Nat_big_num.equal rel_type1 r_ppc64_uaddr32 then - "R_PPC64_UADDR32" - else if Nat_big_num.equal rel_type1 r_ppc64_uaddr16 then - "R_PPC64_UADDR16" - else if Nat_big_num.equal rel_type1 r_ppc64_rel32 then - "R_PPC64_REL32" - else if Nat_big_num.equal rel_type1 r_ppc64_plt32 then - "R_PPC64_PLT32" - else if Nat_big_num.equal rel_type1 r_ppc64_pltrel32 then - "R_PPC64_PLTREL32" - else if Nat_big_num.equal rel_type1 r_ppc64_plt16_lo then - "R_PPC64_PLT16_LO" - else if Nat_big_num.equal rel_type1 r_ppc64_plt16_hi then - "R_PPC64_PLT16_HI" - else if Nat_big_num.equal rel_type1 r_ppc64_plt16_ha then - "R_PPC64_PLT16_HA" - else if Nat_big_num.equal rel_type1 r_ppc64_sectoff then - "R_PPC64_SECTOFF" - else if Nat_big_num.equal rel_type1 r_ppc64_sectoff_lo then - "R_PPC64_SECTOFF_LO" - else if Nat_big_num.equal rel_type1 r_ppc64_sectoff_hi then - "R_PPC64_SECTOFF_HI" - else if Nat_big_num.equal rel_type1 r_ppc64_sectoff_ha then - "R_PPC64_SECTOFF_HA" - else if Nat_big_num.equal rel_type1 r_ppc64_addr30 then - "R_PPC64_ADDR30" - else if Nat_big_num.equal rel_type1 r_ppc64_addr64 then - "R_PPC64_ADDR64" - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_higher then - "R_PPC64_ADDR16_HIGHER" - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_highera then - "R_PPC64_ADDR16_HIGHERA" - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_highest then - "R_PPC64_ADDR16_HIGHEST" - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_highesta then - "R_PPC64_ADDR16_HIGHESTA" - else if Nat_big_num.equal rel_type1 r_ppc64_uaddr64 then - "R_PPC64_UADDR64" - else if Nat_big_num.equal rel_type1 r_ppc64_rel64 then - "R_PPC64_REL64" - else if Nat_big_num.equal rel_type1 r_ppc64_plt64 then - "R_PPC64_PLT64" - else if Nat_big_num.equal rel_type1 r_ppc64_pltrel64 then - "R_PPC64_PLTREL64" - else if Nat_big_num.equal rel_type1 r_ppc64_toc16 then - "R_PPC64_TOC16" - else if Nat_big_num.equal rel_type1 r_ppc64_toc16_lo then - "R_PPC64_TOC16_LO" - else if Nat_big_num.equal rel_type1 r_ppc64_toc16_hi then - "R_PPC64_TOC16_HI" - else if Nat_big_num.equal rel_type1 r_ppc64_toc16_ha then - "R_PPC64_TOC16_HA" - else if Nat_big_num.equal rel_type1 r_ppc64_toc then - "R_PPC64_TOC" - else if Nat_big_num.equal rel_type1 r_ppc64_pltgot16 then - "R_PPC64_PLTGOT16" - else if Nat_big_num.equal rel_type1 r_ppc64_pltgot16_lo then - "R_PPC64_PLTGOT16_LO" - else if Nat_big_num.equal rel_type1 r_ppc64_pltgot16_hi then - "R_PPC64_PLTGOT16_HI" - else if Nat_big_num.equal rel_type1 r_ppc64_pltgot16_ha then - "R_PPC64_PLTGOT16_HA" - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_ds then - "R_PPC64_ADDR16_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_lo_ds then - "R_PPC64_ADDR16_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_got16_ds then - "R_PPC64_GOT16_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_got16_lo_ds then - "R_PPC64_GOT16_LO_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_plt16_lo_ds then - "R_PPC64_PLT16_LO_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_sectoff_ds then - "R_PPC64_SECTOFF_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_sectoff_lo_ds then - "R_PPC64_SECTOFF_LO_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_toc16_ds then - "R_PPC64_TOC16_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_toc16_lo_ds then - "R_PPC64_TOC16_LO_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_pltgot16_ds then - "R_PPC64_PLTGOT16_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_pltgot16_lo_ds then - "R_PPC64_PLTGOT16_LO_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_tls then - "R_PPC64_TLS" - else if Nat_big_num.equal rel_type1 r_ppc64_dtpmod64 then - "R_PPC64_DTPMOD64" - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16 then - "R_PPC64_TPREL16" - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_lo then - "R_PPC64_TPREL16_LO" - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_hi then - "R_PPC64_TPREL16_HI" - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_ha then - "R_PPC64_TPREL16_HA" - else if Nat_big_num.equal rel_type1 r_ppc64_tprel64 then - "R_PPC64_TPREL64" - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16 then - "R_PPC64_DTPREL16" - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_lo then - "R_PPC64_DTPREL16_LO" - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_hi then - "R_PPC64_DTPREL16_HI" - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_ha then - "R_PPC64_DTPREL16_HA" - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel64 then - "R_PPC64_DTPREL64" - else if Nat_big_num.equal rel_type1 r_ppc64_got_tlsgd16 then - "R_PPC64_GOT_TLSGD16" - else if Nat_big_num.equal rel_type1 r_ppc64_got_tlsgd16_lo then - "R_PPC64_GOT_TLSGD16_LO" - else if Nat_big_num.equal rel_type1 r_ppc64_got_tlsgd16_hi then - "R_PPC64_GOT_TLSGD16_HI" - else if Nat_big_num.equal rel_type1 r_ppc64_got_tlsgd16_ha then - "R_PPC64_GOT_TLSGD16_HA" - else if Nat_big_num.equal rel_type1 r_ppc64_got_tlsld16 then - "R_PPC64_GOT_TLSLD16" - else if Nat_big_num.equal rel_type1 r_ppc64_got_tlsld16_lo then - "R_PPC64_GOT_TLSLD16_LO" - else if Nat_big_num.equal rel_type1 r_ppc64_got_tlsld16_hi then - "R_PPC64_GOT_TLSLD16_HI" - else if Nat_big_num.equal rel_type1 r_ppc64_got_tlsld16_ha then - "R_PPC64_GOT_TLSLD16_HA" - else if Nat_big_num.equal rel_type1 r_ppc64_got_tprel16_ds then - "R_PPC64_GOT_TPREL16_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_got_tprel16_lo_ds then - "R_PPC64_GOT_TPREL16_LO_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_got_tprel16_hi then - "R_PPC64_GOT_TPREL16_HI" - else if Nat_big_num.equal rel_type1 r_ppc64_got_tprel16_ha then - "R_PPC64_GOT_TPREL16_HA" - else if Nat_big_num.equal rel_type1 r_ppc64_got_dtprel16_ds then - "R_PPC64_GOT_DTPREL16_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_got_dtprel16_lo_ds then - "R_PPC64_GOT_DTPREL16_LO_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_got_dtprel16_hi then - "R_PPC64_GOT_DTPREL16_HI" - else if Nat_big_num.equal rel_type1 r_ppc64_got_dtprel16_ha then - "R_PPC64_GOT_DTPREL16_HA" - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_ds then - "R_PPC64_TPREL16_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_lo_ds then - "R_PPC64_TPREL16_LO_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_higher then - "R_PPC64_TPREL16_HIGHER" - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_highera then - "R_PPC64_TPREL16_HIGHERA" - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_highest then - "R_PPC64_TPREL16_HIGHEST" - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_highesta then - "R_PPC64_TPREL16_HIGHESTA" - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_ds then - "R_PPC64_DTPREL16_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_lo_ds then - "R_PPC64_DTPREL16_LO_DS" - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_higher then - "R_PPC64_DTPREL16_HIGHER" - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_highera then - "R_PPC64_DTPREL16_HIGHERA" - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_highest then - "R_PPC64_DTPREL16_HIGHEST" - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_highesta then - "R_PPC64_DTPREL16_HIGHESTA" - else - "Invalid Power64 relocation type") - -(*val abi_ppc64_apply_relocation : elf64_relocation_a -> integer -> integer -> - integer -> integer -> integer -> integer -> integer -> integer -> integer -> - integer -> integer -> integer -> integer -> integer -> integer -> elf64_file -> - error (Map.map elf64_addr (relocation_operator_expression integer * integer_bit_width * can_fail integer))*) -let abi_ppc64_apply_relocation rel s_val b_val p_val l_val g_val r_val m_val - toc_val dtpmod_val tprel_val dtprel_val gottlsgd_val gottlsld_val - gottprel_val gotdtprel_val ef:(((Uint64.uint64),((Nat_big_num.num)relocation_operator_expression*integer_bit_width*(Nat_big_num.num)can_fail))Pmap.map)error= - (if is_elf64_relocatable_file ef.elf64_file_header then - let rel_type1 = (extract_elf64_relocation_r_type rel.elf64_ra_info) in - let a_val = (Nat_big_num.of_int64 rel.elf64_ra_addend) in - (** No width, no calculation *) - if Nat_big_num.equal rel_type1 r_ppc64_none then - return (Pmap.empty compare) - (** Width: 32 Calculation: S + A *) - else if Nat_big_num.equal rel_type1 r_ppc64_addr32 then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - (** Width: Low24 Calculation: (S + A) >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_addr24 then - let result = (RShift (Lift( Nat_big_num.add s_val a_val),Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Low24, CanFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: S + A *) - else if Nat_big_num.equal rel_type1 r_ppc64_addr16 then - let result = (Lift ( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #lo(S + A) *) - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_lo then - let result = (Apply(Lo, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #hi(S + A) *) - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_hi then - let result = (Apply(Hi, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #ha(S + A) *) - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_ha then - let result = (Apply(Ha, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: Low14 Calculation: (S + A) >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_addr14 then - let result = (RShift(Lift( Nat_big_num.add s_val a_val),Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Low14, CanFail) (Pmap.empty compare)) - (** Width: Low14 Calculation: (S + A) >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_addr14_brtaken then - let result = (RShift(Lift( Nat_big_num.add s_val a_val),Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Low14, CanFail) (Pmap.empty compare)) - (** Width: Low14 Calculation: (S + A) >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_addr14_brntaken then - let result = (RShift(Lift( Nat_big_num.add s_val a_val),Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Low14, CanFail) (Pmap.empty compare)) - (** Width: Low24 Calculation: ((S + A) - P) >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_rel24 then - let result = (RShift(Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val),Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Low24, CanFail) (Pmap.empty compare)) - (** Width: Low14 Calculation: ((S + A) - P) >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_rel14 then - let result = (RShift(Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val),Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Low14, CanFail) (Pmap.empty compare)) - (** Width: Low14 Calculation: ((S + A) - P) >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_rel14_brtaken then - let result = (RShift(Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val),Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Low14, CanFail) (Pmap.empty compare)) - (** Width: Low14 Calculation: ((S + A) - P) >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_rel14_brntaken then - let result = (RShift(Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val),Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Low14, CanFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: G *) - else if Nat_big_num.equal rel_type1 r_ppc64_got16 then - let result = (Lift g_val) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #lo(G) *) - else if Nat_big_num.equal rel_type1 r_ppc64_got16_lo then - let result = (Apply(Lo, Lift g_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #hi(G) *) - else if Nat_big_num.equal rel_type1 r_ppc64_got16_hi then - let result = (Apply(Hi, Lift g_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #ha(G) *) - else if Nat_big_num.equal rel_type1 r_ppc64_got16_ha then - let result = (Apply(Ha, Lift g_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** No width, no calculation *) - else if Nat_big_num.equal rel_type1 r_ppc64_copy then - fail "abi_ppc64_apply_relocation: r_ppc64_copy not implemented" - (** Width I64, Calculation: S + A *) - else if Nat_big_num.equal rel_type1 r_ppc64_glob_dat then - let result = (Lift( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - (** No width, dynamic link calculation *) - else if Nat_big_num.equal rel_type1 r_ppc64_jmp_slot then - fail "abi_ppc64_apply_relocation: r_ppc64_jmp_slot not implemented" - (** Width I64, Calculation: B + A *) - else if Nat_big_num.equal rel_type1 r_ppc64_relative then - let result = (Lift( Nat_big_num.add b_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - (** Width: I32 Calculation: S + A *) - else if Nat_big_num.equal rel_type1 r_ppc64_uaddr32 then - let result = (Lift( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: S + A *) - else if Nat_big_num.equal rel_type1 r_ppc64_uaddr16 then - let result = (Lift( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - (** Width: I32 Calculation: (S + A) - P *) - else if Nat_big_num.equal rel_type1 r_ppc64_rel32 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - (** Width: I32 Calculation: L *) - else if Nat_big_num.equal rel_type1 r_ppc64_plt32 then - let result = (Lift l_val) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - (** Width: I32 Calculation: L - P *) - else if Nat_big_num.equal rel_type1 r_ppc64_pltrel32 then - let result = (Lift ( Nat_big_num.sub l_val p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I32, CanFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #lo(L) *) - else if Nat_big_num.equal rel_type1 r_ppc64_plt16_lo then - let result = (Apply(Lo, Lift l_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #hi(L) *) - else if Nat_big_num.equal rel_type1 r_ppc64_plt16_hi then - let result = (Apply(Hi, Lift l_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #ha(L) *) - else if Nat_big_num.equal rel_type1 r_ppc64_plt16_ha then - let result = (Apply(Ha, Lift l_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: R + A *) - else if Nat_big_num.equal rel_type1 r_ppc64_sectoff then - let result = (Lift( Nat_big_num.add r_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #lo(R + A) *) - else if Nat_big_num.equal rel_type1 r_ppc64_sectoff_lo then - let result = (Apply(Lo, Lift ( Nat_big_num.add r_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #hi(R + A) *) - else if Nat_big_num.equal rel_type1 r_ppc64_sectoff_hi then - let result = (Apply(Hi, Lift ( Nat_big_num.add r_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #ha(R + A) *) - else if Nat_big_num.equal rel_type1 r_ppc64_sectoff_ha then - let result = (Apply(Ha, Lift ( Nat_big_num.add r_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: Word30 Calculation: ((S + A) - P) >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_addr30 then - let result = (RShift(Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val),Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Word30, CannotFail) (Pmap.empty compare)) - (** Width: I64 Calculation: S + A *) - else if Nat_big_num.equal rel_type1 r_ppc64_addr64 then - let result = (Lift( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #higher(S + A) *) - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_higher then - let result = (Apply(Higher, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #highera(S + A) *) - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_highera then - let result = (Apply(HigherA, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #highest(S + A) *) - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_highest then - let result = (Apply(Highest, Lift ( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #highesta(S + A) *) - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_highesta then - let result = (Apply(HighestA, Lift( Nat_big_num.add s_val a_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: I64 Calculation: S + A *) - else if Nat_big_num.equal rel_type1 r_ppc64_uaddr64 then - let result = (Lift( Nat_big_num.add s_val a_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - (** Width: I64 Calculation: (S + A) - P *) - else if Nat_big_num.equal rel_type1 r_ppc64_rel64 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - (** Width: I64 Calculation: L *) - else if Nat_big_num.equal rel_type1 r_ppc64_plt64 then - let result = (Lift l_val) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - (** Width: I64 Calculation: L - P *) - else if Nat_big_num.equal rel_type1 r_ppc64_pltrel64 then - let result = (Lift( Nat_big_num.sub l_val p_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: (S + A) - TOC *) - else if Nat_big_num.equal rel_type1 r_ppc64_toc16 then - let result = (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) toc_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #lo((S + A) - TOC) *) - else if Nat_big_num.equal rel_type1 r_ppc64_toc16_lo then - let result = (Apply (Lo, Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) toc_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #hi((S + A) - TOC) *) - else if Nat_big_num.equal rel_type1 r_ppc64_toc16_hi then - let result = (Apply(Hi, Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) toc_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #ha((S + A) - TOC) *) - else if Nat_big_num.equal rel_type1 r_ppc64_toc16_ha then - let result = (Apply(Ha, Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) toc_val))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - (** Width: I64 Calculation: .TOC *) - else if Nat_big_num.equal rel_type1 r_ppc64_toc then - let result = (Lift toc_val) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: M *) - else if Nat_big_num.equal rel_type1 r_ppc64_pltgot16 then - let result = (Lift m_val) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #lo(M) *) - else if Nat_big_num.equal rel_type1 r_ppc64_pltgot16_lo then - let result = (Apply(Lo, Lift m_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #hi(M) *) - else if Nat_big_num.equal rel_type1 r_ppc64_pltgot16_hi then - let result = (Apply(Hi, Lift m_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: Half16 Calculation: #ha(M) *) - else if Nat_big_num.equal rel_type1 r_ppc64_pltgot16_ha then - let result = (Apply(Ha, Lift m_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - (** Width: Half16ds Calculation: (S + A) >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_ds then - let result = (RShift(Lift ( Nat_big_num.add s_val a_val),Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CanFail) (Pmap.empty compare)) - (** Width: Half16ds Calculation: #lo((S + A) >> 2) *) - else if Nat_big_num.equal rel_type1 r_ppc64_addr16_lo_ds then - let result = (Apply(Lo, RShift(Lift ( Nat_big_num.add s_val a_val),Nat_big_num.of_int 2))) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CannotFail) (Pmap.empty compare)) - (** Width: Half16ds Calculation: G >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_got16_ds then - let result = (RShift(Lift g_val,Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CanFail) (Pmap.empty compare)) - (** Width: Half16ds Calculation: #lo(G) >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_got16_lo_ds then - let result = (RShift(Apply(Lo, Lift g_val),Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CannotFail) (Pmap.empty compare)) - (** Width: Half16ds Calculation: #lo(L) >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_plt16_lo_ds then - let result = (RShift (Apply(Lo, Lift l_val),Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CannotFail) (Pmap.empty compare)) - (** Width: Half16ds Calculation: (R + A) >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_sectoff_ds then - let result = (RShift (Lift ( Nat_big_num.add r_val a_val),Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CanFail) (Pmap.empty compare)) - (** Width: Half16ds Calculation: #lo(R + A) >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_sectoff_lo_ds then - let result = (RShift(Apply(Lo, Lift ( Nat_big_num.add r_val a_val)),Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CannotFail) (Pmap.empty compare)) - (** Width: Half16ds Calculation: ((S + A) - TOC) >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_toc16_ds then - let result = (RShift (Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) toc_val),Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CanFail) (Pmap.empty compare)) - (** Width: Half16ds Calculation: #lo((S + A) - TOC) >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_toc16_lo_ds then - let result = (RShift (Apply(Lo, Lift ( Nat_big_num.sub( Nat_big_num.add s_val a_val) toc_val)),Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CannotFail) (Pmap.empty compare)) - (** Width: Half16ds Calculation: M >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_pltgot16_ds then - let result = (RShift(Lift m_val,Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CanFail) (Pmap.empty compare)) - (** Width: Half16ds Calculation: #lo(M) >> 2 *) - else if Nat_big_num.equal rel_type1 r_ppc64_pltgot16_lo_ds then - let result = (RShift (Apply(Lo, Lift m_val),Nat_big_num.of_int 2)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CannotFail) (Pmap.empty compare)) - (** No width, no calculation *) - else if Nat_big_num.equal rel_type1 r_ppc64_tls then - fail "abi_ppc64_apply_relocation: r_ppc64_tls not implemented" - (** Width I64 Calculation: @dtpmod *) - else if Nat_big_num.equal rel_type1 r_ppc64_dtpmod64 then - let result = (Lift dtpmod_val) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16 then - let result = (Lift tprel_val) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_lo then - let result = (Apply(Lo, Lift tprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_hi then - let result = (Apply(Hi, Lift tprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_ha then - let result = (Apply(Ha, Lift tprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_tprel64 then - let result = (Lift tprel_val) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16 then - let result = (Lift dtprel_val) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_lo then - let result = (Apply(Lo, Lift dtprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_hi then - let result = (Apply(Hi, Lift dtprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_ha then - let result = (Apply(Ha, Lift dtprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel64 then - let result = (Lift dtprel_val) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I64, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_got_tlsgd16 then - let result = (Lift gottlsgd_val) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_got_tlsgd16_lo then - let result = (Apply(Lo, Lift gottlsgd_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_got_tlsgd16_hi then - let result = (Apply(Hi, Lift gottlsgd_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_got_tlsgd16_ha then - let result = (Apply(Ha, Lift gottlsgd_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_got_tlsld16 then - let result = (Lift gottlsgd_val) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_got_tlsld16_lo then - let result = (Apply(Lo, Lift gottlsgd_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_got_tlsld16_hi then - let result = (Apply(Hi, Lift gottlsgd_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_got_tlsld16_ha then - let result = (Apply(Ha, Lift gottlsgd_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_got_tprel16_ds then - let result = (Lift gottprel_val) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_got_tprel16_lo_ds then - let result = (Apply(Lo, Lift gottprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_got_tprel16_hi then - let result = (Apply(Hi, Lift gottprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_got_tprel16_ha then - let result = (Apply(Ha, Lift gottprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_got_dtprel16_ds then - let result = (Lift gotdtprel_val) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_got_dtprel16_lo_ds then - let result = (Apply(Lo, Lift gotdtprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_got_dtprel16_hi then - let result = (Apply(Hi, Lift gotdtprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_got_dtprel16_ha then - let result = (Apply(Ha, Lift gotdtprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_ds then - let result = (Lift tprel_val) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_lo_ds then - let result = (Apply(Lo, Lift tprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_higher then - let result = (Apply(Higher, Lift tprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_highera then - let result = (Apply(HigherA, Lift tprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_highest then - let result = (Apply(Highest, Lift tprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_tprel16_highesta then - let result = (Apply(HighestA, Lift tprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_ds then - let result = (Lift dtprel_val) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CanFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_lo_ds then - let result = (Apply(Lo, Lift dtprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, Half16ds, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_higher then - let result = (Apply(Higher, Lift dtprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_highera then - let result = (Apply(HigherA, Lift dtprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_highest then - let result = (Apply(Highest, Lift dtprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else if Nat_big_num.equal rel_type1 r_ppc64_dtprel16_highesta then - let result = (Apply(HighestA, Lift dtprel_val)) in - let addr = (rel.elf64_ra_offset) in - return (Pmap.add addr (result, I16, CannotFail) (Pmap.empty compare)) - else - fail "abi_ppc64_apply_relocation: unrecognised relocation type" - else - fail "abi_ppc64_apply_relocation: not a relocatable file") diff --git a/lib/ocaml_rts/linksem/abis/power64/abi_power64_section_header_table.ml b/lib/ocaml_rts/linksem/abis/power64/abi_power64_section_header_table.ml deleted file mode 100644 index a68f81cf..00000000 --- a/lib/ocaml_rts/linksem/abis/power64/abi_power64_section_header_table.ml +++ /dev/null @@ -1,24 +0,0 @@ -(*Generated by Lem from abis/power64/abi_power64_section_header_table.lem.*) -(** [abi_power64_section_header_table] contains Power64 ABI specific definitions - * related to the section header table. - *) - -open Lem_map -open Lem_num - -open Elf_section_header_table - -(** Special sections. *) - -(** See Section 4.2 *) - -(*val abi_power64_special_sections : Map.map string (natural * natural)*) -let abi_power64_special_sections:((string),(Nat_big_num.num*Nat_big_num.num))Pmap.map= - (Lem_map.fromList (instance_Map_MapKeyType_var_dict - Lem_basic_classes.instance_Basic_classes_SetType_var_dict) [ - (".glink", (sht_progbits, Nat_big_num.add shf_alloc shf_execinstr)) - ; (".got", (sht_progbits, Nat_big_num.add shf_alloc shf_write)) - ; (".toc", (sht_progbits, Nat_big_num.add shf_alloc shf_write)) - ; (".tocbss", (sht_nobits, Nat_big_num.add shf_alloc shf_write)) - ; (".plt", (sht_nobits, Nat_big_num.add shf_alloc shf_write)) - ]) diff --git a/lib/ocaml_rts/linksem/abis/x86/abi_x86_relocation.ml b/lib/ocaml_rts/linksem/abis/x86/abi_x86_relocation.ml deleted file mode 100644 index ee57be63..00000000 --- a/lib/ocaml_rts/linksem/abis/x86/abi_x86_relocation.ml +++ /dev/null @@ -1,69 +0,0 @@ -(*Generated by Lem from abis/x86/abi_x86_relocation.lem.*) -(** [abi_x86_relocation] contains X86 ABI specific definitions relating to - * relocations. - *) - -open Lem_basic_classes -open Lem_num -open Lem_string - -open Show - -(** Relocation types. *) - -let r_386_none : Nat_big_num.num= (Nat_big_num.of_int 0) -let r_386_32 : Nat_big_num.num= (Nat_big_num.of_int 1) -let r_386_pc32 : Nat_big_num.num= (Nat_big_num.of_int 2) -let r_386_got32 : Nat_big_num.num= (Nat_big_num.of_int 3) -let r_386_plt32 : Nat_big_num.num= (Nat_big_num.of_int 4) -let r_386_copy : Nat_big_num.num= (Nat_big_num.of_int 5) -let r_386_glob_dat : Nat_big_num.num= (Nat_big_num.of_int 6) -let r_386_jmp_slot : Nat_big_num.num= (Nat_big_num.of_int 7) -let r_386_relative : Nat_big_num.num= (Nat_big_num.of_int 8) -let r_386_gotoff : Nat_big_num.num= (Nat_big_num.of_int 9) -let r_386_gotpc : Nat_big_num.num= (Nat_big_num.of_int 10) - -(** Found in the "wild" but not in the ABI docs: *) - -let r_386_tls_tpoff : Nat_big_num.num= (Nat_big_num.of_int 14) -let r_386_tls_dtpmod32 : Nat_big_num.num= (Nat_big_num.of_int 35) -let r_386_tls_dtpoff32 : Nat_big_num.num= (Nat_big_num.of_int 36) -let r_386_irelative : Nat_big_num.num= (Nat_big_num.of_int 42) - -(** [string_of_x86_relocation_type m] produces a string based representation of - * X86 ABI relocation type [m]. - *) -(*val string_of_x86_relocation_type : natural -> string*) -let string_of_x86_relocation_type m:string= - (if Nat_big_num.equal m r_386_none then - "R_386_NONE" - else if Nat_big_num.equal m r_386_32 then - "R_386_32" - else if Nat_big_num.equal m r_386_pc32 then - "R_386_PC32" - else if Nat_big_num.equal m r_386_got32 then - "R_386_GOT32" - else if Nat_big_num.equal m r_386_plt32 then - "R_386_PLT32" - else if Nat_big_num.equal m r_386_copy then - "R_386_COPY" - else if Nat_big_num.equal m r_386_glob_dat then - "R_386_GLOB_DAT" - else if Nat_big_num.equal m r_386_jmp_slot then - "R_386_JUMP_SLOT" - else if Nat_big_num.equal m r_386_relative then - "R_386_RELATIVE" - else if Nat_big_num.equal m r_386_gotoff then - "R_386_GOTOFF" - else if Nat_big_num.equal m r_386_gotpc then - "R_386_GOTPC" - else if Nat_big_num.equal m r_386_tls_tpoff then - "R_386_TLS_TPOFF" - else if Nat_big_num.equal m r_386_tls_dtpmod32 then - "R_386_TLS_DTPMOD32" - else if Nat_big_num.equal m r_386_tls_dtpoff32 then - "R_386_TLS_DTPOFF32" - else if Nat_big_num.equal m r_386_irelative then - "R_386_IRELATIVE" - else - "Invalid x86 relocation") diff --git a/lib/ocaml_rts/linksem/abstract_linker_script.ml b/lib/ocaml_rts/linksem/abstract_linker_script.ml deleted file mode 100644 index 547b3b2d..00000000 --- a/lib/ocaml_rts/linksem/abstract_linker_script.ml +++ /dev/null @@ -1,59 +0,0 @@ -(*Generated by Lem from abstract_linker_script.lem.*) -open Lem_basic_classes -open Lem_list -open Lem_num - -type binary_relation - = Eq0 - | Lt0 - -type binary_connective - = And0 (** Conjunction *) - | Or0 (** Disjunction *) - -(** The type [expression] denotes addresses, whether known or to be ascertained. - *) -type expression - = Var0 of string (** Ranges over memory addresses *) - | Const of Nat_big_num.num (** Fixed memory address *) - -(* These are *one-place* predicates on unsigned integer solutions (usually representing - * addresses). Implicitly, every binary relation is being applied to the solution. HMM: is - * this sane? Taking my lead from KLEE / SMT solver formulae. What we're describing is a - * big SMT instance; it's sane if we can always factor the instances we want into this - * form, i.e. into a big conjunction of per-variable formulae where each two-place relation - * has the variable in one of its places. - * - * Could try to claim it follows from taking CNF and assigning - * each conjunct to one of the variables it contains. But what if that conjunct is a big - * disjunction including some other binary operators applied to two other variables? - * Might need to factor those out into a "global" extra conjunct. YES. *) -type value_formula - = VFTrue - | VFFalse - | VFBinaryRelation of (binary_relation * expression) - | VFBinaryConnective of (binary_connective * value_formula * value_formula) - | VFNot of value_formula - -type memory_image_formula - = MIFTrue - | MIFFalse - | MIFExists of (string * memory_image_formula) - | MIFBinaryRelation of (binary_relation * expression * expression) - | MIFBinaryConnective of (binary_connective * memory_image_formula * memory_image_formula) - | MIFAssertValueFormula of (expression * value_formula) - | MIFNot of memory_image_formula - -type memory_image0 - = MemoryImage of memory_image_formula - -(*val mk_range : natural -> natural -> value_formula*) -let rec mk_range left right:value_formula= - (if Nat_big_num.equal left right then - VFTrue - else if Nat_big_num.less right left then - VFFalse - else - let l = (Const left) in - let r = (Const right) in - VFBinaryConnective(And0, VFBinaryRelation(Lt0, r), VFNot(VFBinaryRelation(Lt0, l)))) diff --git a/lib/ocaml_rts/linksem/adaptors/harness_interface.ml b/lib/ocaml_rts/linksem/adaptors/harness_interface.ml deleted file mode 100644 index 8ce4f6bd..00000000 --- a/lib/ocaml_rts/linksem/adaptors/harness_interface.ml +++ /dev/null @@ -1,1154 +0,0 @@ -(*Generated by Lem from adaptors/harness_interface.lem.*) -open Lem_basic_classes -open Lem_bool -open Lem_function -open Lem_maybe -open Lem_num -open Lem_string - -open Byte_sequence -open Error -open Hex_printing -open Missing_pervasives -open Show - -open Default_printing - -open Endianness -open String_table - -open Elf_dynamic -open Elf_file -open Elf_header -open Elf_program_header_table -open Elf_relocation -open Elf_section_header_table -open Elf_symbol_table -open Elf_types_native_uint - -open Gnu_ext_dynamic -open Gnu_ext_section_header_table -open Gnu_ext_section_to_segment_mapping -open Gnu_ext_symbol_versioning - -(*val concatS' : list string -> string -> string*) -let rec concatS' ss accum:string= - ((match ss with - | [] -> accum - | s::ss -> concatS' ss (accum^s) - )) - -(*val concatS : list string -> string*) -let concatS ss:string= (concatS' ss "") - -(*val harness_string_of_elf32_file_header : elf32_header -> string*) -let harness_string_of_elf32_file_header hdr:string= - (unlines [ - "ELF Header:" - ; (" Magic:" ^ (" " ^ unsafe_hex_string_of_uc_list (hdr.elf32_ident))) - ; (" Class:" ^ (" " ^ string_of_elf_file_class (get_elf32_file_class hdr))) - ; (" Data:" ^ (" " ^ string_of_elf_data_encoding (get_elf32_data_encoding hdr))) - ; (" Version:" ^ (" " ^ string_of_elf_version_number (get_elf32_version_number hdr))) - ; (" OS/ABI:" ^ (" " ^ string_of_elf_osabi_version ((fun y->"Architecture defined")) (get_elf32_osabi hdr))) - ; (" ABI Version:" ^ (" " ^ Nat_big_num.to_string (get_elf32_abi_version hdr))) - ; (" Type:" ^ (" " ^ string_of_elf_file_type default_os_specific_print default_proc_specific_print (Nat_big_num.of_string (Uint32.to_string hdr.elf32_type)))) - ; (" Machine:" ^ (" " ^ string_of_elf_machine_architecture (Nat_big_num.of_string (Uint32.to_string hdr.elf32_machine)))) - ; (" Version:" ^ (" " ^ ("0x" ^ unsafe_hex_string_of_natural( 1) (Nat_big_num.of_string (Uint32.to_string hdr.elf32_version))))) - ; (" Entry point address:" ^ (" " ^ ("0x" ^ unsafe_hex_string_of_natural( 1) (Nat_big_num.of_string (Uint32.to_string hdr.elf32_entry))))) - ; (" Start of program headers:" ^ (" " ^ (Uint32.to_string hdr.elf32_phoff ^ " (bytes into file)"))) - ; (" Start of section headers:" ^ (" " ^ (Uint32.to_string hdr.elf32_shoff ^ " (bytes into file)"))) - ; (" Flags:" ^ (" " ^ ("0x" ^ unsafe_hex_string_of_natural( 1) (Nat_big_num.of_string (Uint32.to_string hdr.elf32_flags))))) - ; (" Size of this header:" ^ (" " ^ (Uint32.to_string hdr.elf32_ehsize ^ " (bytes)"))) - ; (" Size of program headers:" ^ (" " ^ (Uint32.to_string hdr.elf32_phentsize ^ " (bytes)"))) - ; (" Number of program headers:" ^ (" " ^ Uint32.to_string hdr.elf32_phnum)) - ; (" Size of section headers:" ^ (" " ^ (Uint32.to_string hdr.elf32_shentsize ^ " (bytes)"))) - ; (" Number of section headers:" ^ (" " ^ Uint32.to_string hdr.elf32_shnum)) - ; (" Section header string table index:" ^ (" " ^ Uint32.to_string hdr.elf32_shstrndx)) - ]) - -(*val harness_string_of_elf64_file_header : elf64_header -> string*) -let harness_string_of_elf64_file_header hdr:string= - (unlines [ - "ELF Header:" - ; (" Magic:" ^ (" " ^ unsafe_hex_string_of_uc_list (hdr.elf64_ident))) - ; (" Class:" ^ (" " ^ string_of_elf_file_class (get_elf64_file_class hdr))) - ; (" Data:" ^ (" " ^ string_of_elf_data_encoding (get_elf64_data_encoding hdr))) - ; (" Version:" ^ (" " ^ string_of_elf_version_number (get_elf64_version_number hdr))) - ; (" OS/ABI:" ^ (" " ^ string_of_elf_osabi_version ((fun y->"Architecture defined")) (get_elf64_osabi hdr))) - ; (" ABI Version:" ^ (" " ^ Nat_big_num.to_string (get_elf64_abi_version hdr))) - ; (" Type:" ^ (" " ^ string_of_elf_file_type default_os_specific_print default_proc_specific_print (Nat_big_num.of_string (Uint32.to_string hdr.elf64_type)))) - ; (" Machine:" ^ (" " ^ string_of_elf_machine_architecture (Nat_big_num.of_string (Uint32.to_string hdr.elf64_machine)))) - ; (" Version:" ^ (" " ^ ("0x" ^ unsafe_hex_string_of_natural( 1) (Nat_big_num.of_string (Uint32.to_string hdr.elf64_version))))) - ; (" Entry point address:" ^ (" " ^ ("0x" ^ unsafe_hex_string_of_natural( 1) (Ml_bindings.nat_big_num_of_uint64 hdr.elf64_entry)))) - ; (" Start of program headers:" ^ (" " ^ (Uint64.to_string hdr.elf64_phoff ^ " (bytes into file)"))) - ; (" Start of section headers:" ^ (" " ^ (Uint64.to_string hdr.elf64_shoff ^ " (bytes into file)"))) - ; (" Flags:" ^ (" " ^ ("0x" ^ unsafe_hex_string_of_natural( 1) (Nat_big_num.of_string (Uint32.to_string hdr.elf64_flags))))) - ; (" Size of this header:" ^ (" " ^ (Uint32.to_string hdr.elf64_ehsize ^ " (bytes)"))) - ; (" Size of program headers:" ^ (" " ^ (Uint32.to_string hdr.elf64_phentsize ^ " (bytes)"))) - ; (" Number of program headers:" ^ (" " ^ Uint32.to_string hdr.elf64_phnum)) - ; (" Size of section headers:" ^ (" " ^ (Uint32.to_string hdr.elf64_shentsize ^ " (bytes)"))) - ; (" Number of section headers:" ^ (" " ^ Uint32.to_string hdr.elf64_shnum)) - ; (" Section header string table index:" ^ (" " ^ Uint32.to_string hdr.elf64_shstrndx)) - ]) - -(*val harness_string_of_elf32_program_header_table_entry : (natural -> string) -> (natural -> string) -> byte_sequence -> elf32_program_header_table_entry -> string*) -let harness_string_of_elf32_program_header_table_entry os proc bs0 pent:string= - (let typ = (string_of_segment_type os proc (Nat_big_num.of_string (Uint32.to_string pent.elf32_p_type))) in - let typ_s = -(let len = (Nat_num.nat_monus( 15) (String.length typ)) in - if len <= 0 then - "" - else - concatS (replicate0 (Nat_big_num.of_int len) " ")) - in - concatS [ - " " - ; typ ; typ_s - ; ("0x" ^ unsafe_hex_string_of_natural( 6) (Nat_big_num.of_string (Uint32.to_string pent.elf32_p_offset))) - ; " " - ; ("0x" ^ unsafe_hex_string_of_natural( 8) (Nat_big_num.of_string (Uint32.to_string pent.elf32_p_vaddr))) - ; " " - ; ("0x" ^ unsafe_hex_string_of_natural( 8) (Nat_big_num.of_string (Uint32.to_string pent.elf32_p_paddr))) - ; " " - ; ("0x" ^ unsafe_hex_string_of_natural( 5) (Nat_big_num.of_string (Uint32.to_string pent.elf32_p_filesz))) - ; " " - ; ("0x" ^ unsafe_hex_string_of_natural( 5) (Nat_big_num.of_string (Uint32.to_string pent.elf32_p_memsz))) - ; " " - ; string_of_elf_segment_permissions (Nat_big_num.of_string (Uint32.to_string pent.elf32_p_flags)) - ; " " - ; ("0x" ^ unsafe_hex_string_of_natural( 1) (Nat_big_num.of_string (Uint32.to_string pent.elf32_p_align))) - ] ^ -(if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string pent.elf32_p_type)) elf_pt_interp then - (match Elf_program_header_table.get_elf32_requested_interpreter pent bs0 with - | Fail f -> "\n [Requesting program interpreter: " ^ (f ^ "]") - | Success s -> "\n [Requesting program interpreter: " ^ (s ^ "]") - ) - else - "")) - -(*val harness_string_of_elf64_program_header_table_entry : (natural -> string) -> (natural -> string) -> byte_sequence -> elf64_program_header_table_entry -> string*) -let harness_string_of_elf64_program_header_table_entry os proc bs0 pent:string= - (let typ = (string_of_segment_type os proc (Nat_big_num.of_string (Uint32.to_string pent.elf64_p_type))) in - let typ_s = -(let len = (Nat_num.nat_monus( 15) (String.length typ)) in - if len <= 0 then - "" - else - concatS (replicate0 (Nat_big_num.of_int len) " ")) - in - concatS [ - " " - ; typ ; typ_s - ; ("0x" ^ unsafe_hex_string_of_natural( 6) (Nat_big_num.of_string (Uint64.to_string pent.elf64_p_offset))) - ; " " - ; ("0x" ^ unsafe_hex_string_of_natural( 16) (Ml_bindings.nat_big_num_of_uint64 pent.elf64_p_vaddr)) - ; " " - ; ("0x" ^ unsafe_hex_string_of_natural( 16) (Ml_bindings.nat_big_num_of_uint64 pent.elf64_p_paddr)) - ; " " - ; ("0x" ^ unsafe_hex_string_of_natural( 6) (Ml_bindings.nat_big_num_of_uint64 pent.elf64_p_filesz)) - ; " " - ; ("0x" ^ unsafe_hex_string_of_natural( 6) (Ml_bindings.nat_big_num_of_uint64 pent.elf64_p_memsz)) - ; " " - ; string_of_elf_segment_permissions (Nat_big_num.of_string (Uint32.to_string pent.elf64_p_flags)) - ; " " - ; ("0x" ^ unsafe_hex_string_of_natural( 1) (Ml_bindings.nat_big_num_of_uint64 pent.elf64_p_align)) - ] ^ -(if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string pent.elf64_p_type)) elf_pt_interp then - (match Elf_program_header_table.get_elf64_requested_interpreter pent bs0 with - | Fail f -> "\n [Requesting program interpreter: " ^ (f ^ "]") - | Success s -> "\n [Requesting program interpreter: " ^ (s ^ "]") - ) - else - "")) - -(*val harness_string_of_efl32_pht : (natural -> string) -> (natural -> string) -> elf32_program_header_table -> byte_sequence -> string*) -let harness_string_of_elf32_pht os proc pht bs0:string= - (" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n" ^ - unlines (Lem_list.map (harness_string_of_elf32_program_header_table_entry os proc bs0) pht)) - -(*val harness_string_of_efl64_pht : (natural -> string) -> (natural -> string) -> elf64_program_header_table -> byte_sequence -> string*) -let harness_string_of_elf64_pht os proc pht bs0:string= - (" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n" ^ - unlines (Lem_list.map (harness_string_of_elf64_program_header_table_entry os proc bs0) pht)) - -(*val harness_string_of_elf32_segment_section_mappings : elf32_header -> elf32_program_header_table -> elf32_section_header_table -> string_table -> string*) -let harness_string_of_elf32_segment_section_mappings hdr pht sht stbl:string= - (let map1 = -(Lem_list.mapi (fun i -> fun pent -> - let mapping = -((match get_elf32_section_to_segment_mapping hdr sht pent elf32_section_in_segment stbl with - | Fail err -> [("ERR: " ^ err)] - | Success mp -> intercalate " " mp - )) - in - let str = -(let temp = (concatS mapping) in - if temp = "" then - temp - else - temp ^ " ") - in - concatS [ -(" " ^ Ml_bindings.hex_string_of_nat_pad2 i) - ; " " - ; str - ] - ) pht) - in - concatS (intercalate "\n" map1)) - -(*val harness_string_of_elf64_segment_section_mappings : elf64_header -> elf64_program_header_table -> elf64_section_header_table -> string_table -> string*) -let harness_string_of_elf64_segment_section_mappings hdr pht sht stbl:string= - (let map1 = -(Lem_list.mapi (fun i -> fun pent -> - let mapping = -((match get_elf64_section_to_segment_mapping hdr sht pent elf64_section_in_segment stbl with - | Fail err -> [("ERR: " ^ err)] - | Success mp -> intercalate " " mp - )) - in - let str = -(let temp = (concatS mapping) in - if temp = "" then - temp - else - temp ^ " ") - in - concatS [ -(" " ^ Ml_bindings.hex_string_of_nat_pad2 i) - ; " " - ; str - ] - ) pht) - in - concatS (intercalate "\n" map1)) - -(*val harness_string_of_elf32_program_headers : (natural -> string) -> (natural -> string) -> elf32_header -> elf32_program_header_table -> elf32_section_header_table -> string_table -> byte_sequence -> string*) -let harness_string_of_elf32_program_headers os proc hdr pht sht stbl bs0:string= - (let pht_len = (List.length pht) in - if pht_len = 0 then - "\nThere are no program headers in this file." - else - unlines [ - "" - ; ("Elf file type is " ^ string_of_elf_file_type default_os_specific_print default_proc_specific_print (Nat_big_num.of_string (Uint32.to_string hdr.elf32_type))) - ; ("Entry point " ^ ("0x" ^ unsafe_hex_string_of_natural( 1) (Nat_big_num.of_string (Uint32.to_string hdr.elf32_entry)))) - ; ("There are " ^ (Pervasives.string_of_int (List.length pht) ^ (" program headers, starting at offset " ^ Uint32.to_string hdr.elf32_phoff))) - ; "" - ; "Program Headers:" - ; harness_string_of_elf32_pht os proc pht bs0 - ; "" - ; " Section to Segment mapping:" - ; " Segment Sections..." - ; harness_string_of_elf32_segment_section_mappings hdr pht sht stbl - ]) - -(*val harness_string_of_elf64_program_headers : (natural -> string) -> (natural -> string) -> elf64_header -> elf64_program_header_table -> elf64_section_header_table -> string_table -> byte_sequence -> string*) -let harness_string_of_elf64_program_headers os proc hdr pht sht stbl bs0:string= - (let pht_len = (List.length pht) in - if pht_len = 0 then - "\nThere are no program headers in this file." - else - unlines [ - "" - ; ("Elf file type is " ^ string_of_elf_file_type default_os_specific_print default_proc_specific_print (Nat_big_num.of_string (Uint32.to_string hdr.elf64_type))) - ; ("Entry point " ^ ("0x" ^ unsafe_hex_string_of_natural( 1) (Ml_bindings.nat_big_num_of_uint64 hdr.elf64_entry))) - ; ("There are " ^ (Pervasives.string_of_int (List.length pht) ^ (" program headers, starting at offset " ^ Uint64.to_string hdr.elf64_phoff))) - ; "" - ; "Program Headers:" - ; harness_string_of_elf64_pht os proc pht bs0 - ; "" - ; " Section to Segment mapping:" - ; " Segment Sections..." - ; harness_string_of_elf64_segment_section_mappings hdr pht sht stbl - ]) - -(*val harness_sht32_flag_legend : string*) -let harness_sht32_flag_legend:string= - "\nKey to Flags: - W (write), A (alloc), X (execute), M (merge), S (strings) - I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) - O (extra OS processing required) o (OS specific), p (processor specific)" - -(*val harness_sht64_flag_legend : natural -> string*) -let harness_sht64_flag_legend mach:string= - (if Nat_big_num.equal mach elf_ma_x86_64 || (Nat_big_num.equal - mach elf_ma_l10m || Nat_big_num.equal - mach elf_ma_k10m) then - "\nKey to Flags: - W (write), A (alloc), X (execute), M (merge), S (strings), l (large) - I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) - O (extra OS processing required) o (OS specific), p (processor specific)" - else - "\nKey to Flags: - W (write), A (alloc), X (execute), M (merge), S (strings) - I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) - O (extra OS processing required) o (OS specific), p (processor specific)") - -(*val harness_string_of_elf32_sht : (natural -> string) -> (natural -> string) -> (natural -> string) -> elf32_section_header_table -> string_table -> string*) -let harness_string_of_elf32_sht os proc usr sht stbl:string= - (" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n" ^ - unlines (Lem_list.mapi (fun i -> fun sec -> - let is = -(let temp = (Pervasives.string_of_int i) in - if String.length temp = 1 then - " " ^ temp - else - temp) - in - let str = (" [" ^ (is ^ "]")) in - let ((gap : string), name1) = -((match String_table.get_string_at (Nat_big_num.of_string (Uint32.to_string sec.elf32_sh_name)) stbl with - | Fail err -> ("", ("ERR " ^ err)) - | Success nm -> - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string sec.elf32_sh_type)) sht_null then - let gap = (List.fold_right (^) (Missing_pervasives.replicate0(Nat_big_num.of_int 17) " ") " ") in - (gap, "") - else - let glen = (Nat_big_num.of_int ( Nat_num.nat_monus( 17) (String.length nm))) in - let gap = (List.fold_right (^) (Missing_pervasives.replicate0 glen " ") " ") in - (gap, nm) - )) - in - let str = (str ^ (" " ^ (name1 ^ gap))) in - let typ = (string_of_section_type os proc usr (Nat_big_num.of_string (Uint32.to_string sec.elf32_sh_type))) in - let str = (str ^ typ) in - let (gap, addr) = -(let mx = (Nat_big_num.of_int ( Nat_num.nat_monus( 15) (String.length typ))) in - let gap = (List.fold_right (^) (Missing_pervasives.replicate0 mx " ") " ") in - (gap, unsafe_hex_string_of_natural( 8) (Nat_big_num.of_string (Uint32.to_string sec.elf32_sh_addr)))) - in - let str = (str ^ (gap ^ addr)) in - let off = (unsafe_hex_string_of_natural( 6) (Nat_big_num.of_string (Uint32.to_string sec.elf32_sh_offset))) in - let str = (str ^ (" " ^ off)) in - let size2 = (unsafe_hex_string_of_natural( 6) (Nat_big_num.of_string (Uint32.to_string sec.elf32_sh_size))) in - let str = (str ^ (" " ^ size2)) in - let es = (unsafe_hex_string_of_natural( 2) (Nat_big_num.of_string (Uint32.to_string sec.elf32_sh_entsize))) in - let str = (str ^ (" " ^ es)) in - let flg = (string_of_section_flags os proc (Nat_big_num.of_string (Uint32.to_string sec.elf32_sh_flags))) in - let str = (str ^ (" " ^ flg)) in - let (gap, lnk) = -(let l = (Nat_big_num.to_string (Nat_big_num.of_string (Uint32.to_string sec.elf32_sh_link))) in - let gp = (Nat_big_num.of_int ( Nat_num.nat_monus( 2) (String.length l))) in - let gp = (List.fold_right (^) (replicate0 gp " ") " ") in - (gp, l)) - in - let str = (str ^ (gap ^ lnk)) in - let (gap, info) = -(let i = (Nat_big_num.to_string (Nat_big_num.of_string (Uint32.to_string sec.elf32_sh_info))) in - let gp = (Nat_big_num.of_int ( Nat_num.nat_monus( 3) (String.length i))) in - let gp = (List.fold_right (^) (replicate0 gp " ") " ") in - (gp, i)) - in - let str = (str ^ (gap ^ info)) in - let (gap, align) = -(let a = (Nat_big_num.to_string (Nat_big_num.of_string (Uint32.to_string sec.elf32_sh_addralign))) in - let gp = (Nat_big_num.of_int ( Nat_num.nat_monus( 2) (String.length a))) in - let gp = (List.fold_right (^) (replicate0 gp " ") " ") in - (gp, a)) - in - let str = (str ^ (gap ^ align)) in - str) sht)) - -(*val harness_string_of_elf64_sht : (natural -> string) -> (natural -> string) -> (natural -> string) -> elf64_section_header_table -> string_table -> string*) -let harness_string_of_elf64_sht os proc usr sht stbl:string= - (" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n" ^ - unlines (Lem_list.mapi (fun i -> fun sec -> - let is = -(let temp = (Pervasives.string_of_int i) in - if String.length temp = 1 then - " " ^ temp - else - temp) - in - let str = (" [" ^ (is ^ "]")) in - let ((gap : string), name1) = -((match String_table.get_string_at (Nat_big_num.of_string (Uint32.to_string sec.elf64_sh_name)) stbl with - | Fail err -> ("", ("ERR " ^ err)) - | Success nm -> - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string sec.elf64_sh_type)) sht_null then - let gap = (List.fold_right (^) (Missing_pervasives.replicate0(Nat_big_num.of_int 17) " ") " ") in - (gap, "") - else - let glen = (Nat_big_num.of_int ( Nat_num.nat_monus( 17) (String.length nm))) in - let gap = (List.fold_right (^) (Missing_pervasives.replicate0 glen " ") " ") in - (gap, nm) - )) - in - let str = (str ^ (" " ^ (name1 ^ gap))) in - let typ = (string_of_section_type os proc usr (Nat_big_num.of_string (Uint32.to_string sec.elf64_sh_type))) in - let str = (str ^ typ) in - let (gap, addr) = -(let mx = (Nat_big_num.of_int ( Nat_num.nat_monus( 15) (String.length typ))) in - let gap = (List.fold_right (^) (Missing_pervasives.replicate0 mx " ") " ") in - (gap, unsafe_hex_string_of_natural( 16) (Ml_bindings.nat_big_num_of_uint64 sec.elf64_sh_addr))) - in - let str = (str ^ (gap ^ addr)) in - let off = (unsafe_hex_string_of_natural( 6) (Nat_big_num.of_string (Uint64.to_string sec.elf64_sh_offset))) in - let str = (str ^ (" " ^ off)) in - let size2 = (unsafe_hex_string_of_natural( 6) (Ml_bindings.nat_big_num_of_uint64 sec.elf64_sh_size)) in - let str = (str ^ (" " ^ size2)) in - let es = (unsafe_hex_string_of_natural( 2) (Ml_bindings.nat_big_num_of_uint64 sec.elf64_sh_entsize)) in - let str = (str ^ (" " ^ es)) in - let flg = (string_of_section_flags os proc (Ml_bindings.nat_big_num_of_uint64 sec.elf64_sh_flags)) in - let str = (str ^ (" " ^ flg)) in - let (gap, lnk) = -(let l = (Nat_big_num.to_string (Nat_big_num.of_string (Uint32.to_string sec.elf64_sh_link))) in - let gp = (Nat_big_num.of_int ( Nat_num.nat_monus( 2) (String.length l))) in - let gp = (List.fold_right (^) (replicate0 gp " ") " ") in - (gp, l)) - in - let str = (str ^ (gap ^ lnk)) in - let (gap, info) = -(let i = (Nat_big_num.to_string (Nat_big_num.of_string (Uint32.to_string sec.elf64_sh_info))) in - let gp = (Nat_big_num.of_int ( Nat_num.nat_monus( 3) (String.length i))) in - let gp = (List.fold_right (^) (replicate0 gp " ") " ") in - (gp, i)) - in - let str = (str ^ (gap ^ info)) in - let (gap, align) = -(let a = (Nat_big_num.to_string (Ml_bindings.nat_big_num_of_uint64 sec.elf64_sh_addralign)) in - let gp = (Nat_big_num.of_int ( Nat_num.nat_monus( 2) (String.length a))) in - let gp = (List.fold_right (^) (replicate0 gp " ") " ") in - (gp, a)) - in - let str = (str ^ (gap ^ align)) in - str) sht)) - - -(*val harness_string_of_elf32_section_headers : (natural -> string) -> (natural -> string) -> (natural -> string) -> elf32_header -> elf32_section_header_table -> string_table -> string*) -let harness_string_of_elf32_section_headers os proc usr hdr sht stbl:string= - (unlines [ -("There are " ^ (Pervasives.string_of_int (List.length sht) ^ (" section headers, starting at offset 0x" ^ (unsafe_hex_string_of_natural( 0) (Nat_big_num.of_string (Uint32.to_string hdr.elf32_shoff)) ^ ":")))) - ; "" - ; "Section Headers:" - ; harness_string_of_elf32_sht os proc usr sht stbl - ] ^ harness_sht32_flag_legend) - -(*val harness_string_of_elf64_section_headers : (natural -> string) -> (natural -> string) -> (natural -> string) -> elf64_header -> elf64_section_header_table -> string_table -> string*) -let harness_string_of_elf64_section_headers os proc usr hdr sht stbl:string= - (unlines [ -("There are " ^ (Pervasives.string_of_int (List.length sht) ^ (" section headers, starting at offset 0x" ^ (unsafe_hex_string_of_natural( 0) (Nat_big_num.of_string (Uint64.to_string hdr.elf64_shoff)) ^ ":")))) - ; "" - ; "Section Headers:" - ; harness_string_of_elf64_sht os proc usr sht stbl - ] ^ harness_sht64_flag_legend (Nat_big_num.of_string (Uint32.to_string hdr.elf64_machine))) - -(*val harness_string_of_elf32_reloc_entry : (natural -> string) -> elf32_section_header_table -> - elf32_symbol_table -> string_table -> string_table -> elf32_relocation -> string*) -let harness_string_of_elf32_reloc_entry os sht symtab stbl sechdr_stbl rel:string= - (let off = (Nat_big_num.of_string (Uint32.to_string rel.elf32_r_offset)) in - let inf = (Nat_big_num.of_string (Uint32.to_string rel.elf32_r_info)) in - let typ = (Missing_pervasives.unsafe_string_take(Nat_big_num.of_int 22) (os (extract_elf32_relocation_r_type rel.elf32_r_info))) in - let typs = -(let len = (Nat_big_num.of_int ( Nat_num.nat_monus( 22) (String.length typ))) in - concatS (replicate0 len " ")) - in - let idx1 = (extract_elf32_relocation_r_sym rel.elf32_r_info) in - (match Lem_list.list_index symtab (Nat_big_num.to_int idx1) with - | None -> "harness_string_of_elf32_reloc_entry: Nothing returned" - | Some sym -> - let (nm, value, symtyp, secthdr) = -((match Lem_list.list_index symtab (Nat_big_num.to_int idx1) with - | None -> (stn_undef,Nat_big_num.of_int 0,Nat_big_num.of_int 0,Nat_big_num.of_int 0) - | Some sym -> (Nat_big_num.of_string (Uint32.to_string sym.elf32_st_name), - Nat_big_num.of_string (Uint32.to_string sym.elf32_st_value), get_elf32_symbol_type sym, - Nat_big_num.of_string (Uint32.to_string sym.elf32_st_shndx)) - )) - in - if Nat_big_num.equal symtyp stt_section then - let vlu = (" " ^ unsafe_hex_string_of_natural( 8) value) in - let nm = -((match Lem_list.list_index sht (Nat_big_num.to_int secthdr) with - | None -> "XXX" - | Some shdr -> - (match String_table.get_string_at (Nat_big_num.of_string (Uint32.to_string shdr.elf32_sh_name)) sechdr_stbl with - | Fail f -> f - | Success n -> n - ) - )) - in - concatS [ - unsafe_hex_string_of_natural( 8) off - ; " " - ; unsafe_hex_string_of_natural( 8) inf - ; " " - ; typ - ; typs - ; vlu - ; " " - ; nm - ] - else if Nat_big_num.equal nm stn_undef then - concatS [ - unsafe_hex_string_of_natural( 8) off - ; " " - ; unsafe_hex_string_of_natural( 8) inf - ; " " - ; typ - ; typs - ] - else - let vlu = (" " ^ unsafe_hex_string_of_natural( 8) (Nat_big_num.of_string (Uint32.to_string sym.elf32_st_value))) in - let nm = -((match String_table.get_string_at nm stbl with - | Fail f -> f - | Success n -> n - )) - in - concatS [ - unsafe_hex_string_of_natural( 8) off - ; " " - ; unsafe_hex_string_of_natural( 8) inf - ; " " - ; typ - ; typs - ; vlu - ; " " - ; nm - ] - )) - -(*val harness_string_of_elf64_reloc_a_entry : (natural -> string) -> elf64_symbol_table -> - elf64_section_header_table -> string_table -> string_table -> elf64_relocation_a -> string*) -let harness_string_of_elf64_reloc_a_entry os symtab sht stbl sechdr_stbl rel:string= - (let off = (Ml_bindings.nat_big_num_of_uint64 rel.elf64_ra_offset) in - let inf = (Ml_bindings.nat_big_num_of_uint64 rel.elf64_ra_info) in - let add = (Nat_big_num.of_int64 rel.elf64_ra_addend) in - let typ = (Missing_pervasives.unsafe_string_take(Nat_big_num.of_int 22) (os (extract_elf64_relocation_r_type rel.elf64_ra_info))) in - let typs = -(let len = (Nat_big_num.of_int ( Nat_num.nat_monus( 22) (String.length typ))) in - concatS (replicate0 len " ")) - in - let idx1 = (extract_elf64_relocation_r_sym rel.elf64_ra_info) in - let (nm, value, symtyp, secthdr) = -((match Lem_list.list_index symtab (Nat_big_num.to_int idx1) with - | None -> (stn_undef,Nat_big_num.of_int 0,Nat_big_num.of_int 0,Nat_big_num.of_int 0) - | Some sym -> (Nat_big_num.of_string (Uint32.to_string sym.elf64_st_name), - Ml_bindings.nat_big_num_of_uint64 sym.elf64_st_value, get_elf64_symbol_type sym, - Nat_big_num.of_string (Uint32.to_string sym.elf64_st_shndx)) - )) - in - if Nat_big_num.equal symtyp stt_section then - let vlu = (" " ^ unsafe_hex_string_of_natural( 16) value) in - let nm = -((match Lem_list.list_index sht (Nat_big_num.to_int secthdr) with - | None -> "XXX" - | Some shdr -> - (match String_table.get_string_at (Nat_big_num.of_string (Uint32.to_string shdr.elf64_sh_name)) sechdr_stbl with - | Fail f -> f - | Success n -> n - ) - )) - in - concatS [ - unsafe_hex_string_of_natural( 16) off - ; " " - ; unsafe_hex_string_of_natural( 16) inf - ; " " - ; typ - ; typs - ; vlu - ; " " - ; nm - ; " + " - ; Ml_bindings.hex_string_of_big_int_no_padding add - ] - else if Nat_big_num.equal nm stn_undef then - concatS [ - unsafe_hex_string_of_natural( 16) off - ; " " - ; unsafe_hex_string_of_natural( 16) inf - ; " " - ; typ - ; typs - ; " " - ; Ml_bindings.hex_string_of_big_int_no_padding add - ] - else - let vlu = (" " ^ unsafe_hex_string_of_natural( 16) value) in - let nm = -((match String_table.get_string_at nm stbl with - | Fail f -> f - | Success n -> n - )) - in - concatS [ - unsafe_hex_string_of_natural( 16) off - ; " " - ; unsafe_hex_string_of_natural( 16) inf - ; " " - ; typ - ; typs - ; vlu - ; " " - ; nm - ; " + " - ; Ml_bindings.hex_string_of_big_int_no_padding add - ]) - -(*val harness_string_of_elf32_relocs' : endianness -> (natural -> string) -> elf32_file -> elf32_section_header_table -> - elf32_section_header_table -> string_table -> string_table -> byte_sequence -> string*) -let harness_string_of_elf32_relocs' endian os f1 sht_relocs sht shdr stbl bs0:string= - (let rels = -(mapM (fun ent -> - let off = (Nat_big_num.of_string (Uint32.to_string ent.elf32_sh_offset)) in - let siz = (Nat_big_num.of_string (Uint32.to_string ent.elf32_sh_size)) in - let lnk = (Nat_big_num.of_string (Uint32.to_string ent.elf32_sh_link)) in - Byte_sequence.offset_and_cut off siz bs0 >>= (fun rels -> - Elf_relocation.read_elf32_relocation_section' endian rels >>= (fun sect -> - Elf_file.get_elf32_symbol_table_by_index f1 lnk >>= (fun symtab -> - return (sect, ent, symtab)))) - ) sht_relocs - >>= - mapM (fun (rels, ent, symtab) -> - let nm = (Nat_big_num.of_string (Uint32.to_string ent.elf32_sh_name)) in - let off = (unsafe_hex_string_of_natural( 0) (Nat_big_num.of_string (Uint32.to_string ent.elf32_sh_offset))) in - let len = (Pervasives.string_of_int (List.length rels)) in - String_table.get_string_at nm shdr >>= (fun nm -> - let hdr = ("Relocation section '" ^ (nm ^ ("' at offset 0x" ^ (off ^ (" contains " ^ (len ^ " entries:\n")))))) in - let ttl = " Offset Info Type Sym. Value Symbol's Name\n" in - let body = (concatS (intercalate "\n" (Lem_list.map (harness_string_of_elf32_reloc_entry os sht symtab stbl shdr) rels))) in - return (hdr ^ (ttl ^ body))))) - in - (match rels with - | Fail err -> err - | Success s -> concatS (intercalate "\n\n" s) - )) - -(*val harness_string_of_elf64_relocs' : endianness -> (natural -> string) -> elf64_file -> - elf64_section_header_table -> elf64_section_header_table -> - string_table -> string_table -> byte_sequence -> string*) -let harness_string_of_elf64_relocs' endian os f1 reloc_sht sht shdr stbl bs0:string= - (let rels = -(mapM (fun ent -> - let off = (Nat_big_num.of_string (Uint64.to_string ent.elf64_sh_offset)) in - let siz = (Ml_bindings.nat_big_num_of_uint64 ent.elf64_sh_size) in - let lnk = (Nat_big_num.of_string (Uint32.to_string ent.elf64_sh_link)) in - Byte_sequence.offset_and_cut off siz bs0 >>= (fun rels -> - Elf_relocation.read_elf64_relocation_a_section' endian rels >>= (fun sect -> - Elf_file.get_elf64_symbol_table_by_index f1 lnk >>= (fun symtab -> - return (sect, ent, symtab)))) - ) reloc_sht - >>= - mapM (fun (rels, ent, symtab) -> - let nm = (Nat_big_num.of_string (Uint32.to_string ent.elf64_sh_name)) in - let off = (unsafe_hex_string_of_natural( 0) (Nat_big_num.of_string (Uint64.to_string ent.elf64_sh_offset))) in - let len = (Pervasives.string_of_int (List.length rels)) in - String_table.get_string_at nm shdr >>= (fun nm -> - let hdr = ("Relocation section '" ^ (nm ^ ("' at offset 0x" ^ (off ^ (" contains " ^ (len ^ " entries:\n")))))) in - let ttl = " Offset Info Type Symbol's Value Symbol's Name + Addend\n" in - let body = (concatS (intercalate "\n" (Lem_list.map (harness_string_of_elf64_reloc_a_entry os symtab sht stbl shdr) rels))) in - return (hdr ^ (ttl ^ body))))) - in - (match rels with - | Fail err -> err - | Success s -> concatS (intercalate "\n\n" s) - )) - -(*val harness_string_of_elf32_relocs : elf32_file -> (natural -> string) -> byte_sequence -> string*) -let harness_string_of_elf32_relocs f1 os bs0:string= - (let hdr = (f1.elf32_file_header) in - let sht = (f1.elf32_file_section_header_table) in - let endian = (get_elf32_header_endianness hdr) in - let rel_secs = (List.filter (fun x -> - x.elf32_sh_type = Uint32.of_string (Nat_big_num.to_string sht_rel)) sht) in - if List.length rel_secs = 0 then - "\nThere are no relocations in this file." - else - (match get_elf32_file_symbol_string_table f1 with - | Fail err -> err - | Success stbl -> - (match get_elf32_file_section_header_string_table f1 with - | Fail err -> err - | Success shdr -> "\n" ^ harness_string_of_elf32_relocs' endian os f1 rel_secs sht shdr stbl bs0 - ) - )) - -(*val harness_string_of_elf64_relocs : elf64_file -> (natural -> string) -> byte_sequence -> string*) -let harness_string_of_elf64_relocs f1 os bs0:string= - (let hdr = (f1.elf64_file_header) in - let sht = (f1.elf64_file_section_header_table) in - let endian = (get_elf64_header_endianness hdr) in - let rel_secs = (List.filter (fun x -> - x.elf64_sh_type = Uint32.of_string (Nat_big_num.to_string sht_rela)) sht) in - if List.length rel_secs = 0 then - "\nThere are no relocations in this file." - else - (match get_elf64_file_symbol_string_table f1 with - | Fail err -> err - | Success stbl -> - (match get_elf64_file_section_header_string_table f1 with - | Fail err -> err - | Success shdr -> "\n" ^ harness_string_of_elf64_relocs' endian os f1 rel_secs sht shdr stbl bs0 - ) - )) - -(*val harness_string_of_elf32_symbol_table_entry : nat -> (natural -> string) -> - (natural -> string) -> byte_sequence -> string_table -> elf32_symbol_table_entry -> string*) -let harness_string_of_elf32_symbol_table_entry num os proc bs0 stbl ent:string= - (let vlu = (unsafe_hex_string_of_natural( 8) (Nat_big_num.of_string (Uint32.to_string ent.elf32_st_value))) in - let siz = (Nat_big_num.to_string (Nat_big_num.of_string (Uint32.to_string ent.elf32_st_size))) in - let siz_pad = - (let pad = (Nat_num.nat_monus( 5) (String.length siz)) in - if pad = 0 then - "" - else - concatS (replicate0 (Nat_big_num.of_int pad) " ")) - in - let typ = (string_of_symbol_type (get_elf32_symbol_type ent) os proc) in - let bnd = (string_of_symbol_binding (get_elf32_symbol_binding ent) os proc) in - let bnd_pad = -(let pad = (Nat_num.nat_monus( 6) (String.length typ)) in - if pad = 0 then - "" - else - concatS (replicate0 (Nat_big_num.of_int pad) " ")) - in - let vis = (string_of_symbol_visibility (Nat_big_num.of_string (Uint32.to_string ent.elf32_st_other))) in - let vis_pad = -(let pad = (Nat_num.nat_monus( 6) (String.length bnd)) in - if pad = 0 then - "" - else - concatS (replicate0 (Nat_big_num.of_int pad) " ")) - in - let ndx = -(let tmp = (Nat_big_num.of_string (Uint32.to_string ent.elf32_st_shndx)) in - if Nat_big_num.equal tmp shn_undef then - "UND" - else if Nat_big_num.equal tmp shn_abs then - "ABS" - else - Nat_big_num.to_string tmp) - in - let ndx_pad = -(let pad = (Nat_num.nat_monus( 3) (String.length ndx)) in - if pad = 0 then - "" - else - concatS (replicate0 (Nat_big_num.of_int pad) " ")) - in - let nm = -(let idx1 = (Nat_big_num.of_string (Uint32.to_string ent.elf32_st_name)) in - if Nat_big_num.equal idx1(Nat_big_num.of_int 0) then - "" - else - (match String_table.get_string_at idx1 stbl with - | Fail err -> err - | Success s -> s - )) - in - let sym = "" in - let num = -(let temp = (Pervasives.string_of_int num) in - let pad = (Nat_num.nat_monus( 3) (String.length temp)) in - if pad = 0 then - temp - else - let spcs = (concatS (replicate0 (Nat_big_num.of_int pad) " ")) in - spcs ^ temp) - in - concatS [ - " " - ; (num ^ ":") - ; " " - ; vlu - ; " " - ; siz_pad; siz - ; " " - ; typ - ; " " - ; bnd_pad; bnd - ; " " - ; vis_pad; vis - ; " " - ; ndx_pad; ndx - ; " " - ; nm - ; sym - ]) - -(*val harness_string_of_elf32_syms' : endianness -> (natural -> string) -> (natural -> string) -> elf32_file -> elf32_section_header_table -> elf32_section_header_table -> string_table -> byte_sequence -> string*) -let harness_string_of_elf32_syms' endian os proc f1 filtered_sht sht shdr bs0:string= - (let rels = -(mapM (fun ent -> - let off = (Nat_big_num.of_string (Uint32.to_string ent.elf32_sh_offset)) in - let siz = (Nat_big_num.of_string (Uint32.to_string ent.elf32_sh_size)) in - let lnk = (Nat_big_num.of_string (Uint32.to_string ent.elf32_sh_link)) in - let typ = (Nat_big_num.of_string (Uint32.to_string ent.elf32_sh_type)) in - Byte_sequence.offset_and_cut off siz bs0 >>= (fun syms -> - Elf_symbol_table.read_elf32_symbol_table endian syms >>= (fun sect -> - Elf_file.get_elf32_string_table_by_index f1 lnk >>= (fun strtab -> - return (sect, ent, strtab, typ)))) - ) filtered_sht >>= (fun sects -> - mapM (fun (syms, ent, strtab, typ) -> - let nm = (Nat_big_num.of_string (Uint32.to_string ent.elf32_sh_name)) in - let len = (Pervasives.string_of_int (List.length syms)) in - String_table.get_string_at nm shdr >>= (fun nm -> - let hdr = ("Symbol table '" ^ (nm ^ ("' contains " ^ (len ^ " entries:\n")))) in - let ttl = " Num: Value Size Type Bind Vis Ndx Name\n" in - let body = (concatS (intercalate "\n" (Lem_list.mapi (fun n -> - harness_string_of_elf32_symbol_table_entry n os proc bs0 strtab) syms))) - in - return (hdr ^ (ttl ^ body)))) sects)) - in - (match rels with - | Fail err -> err - | Success s -> concatS (intercalate "\n\n" s) - )) - -(*val harness_string_of_elf32_syms : elf32_file -> (natural -> string) -> (natural -> string) -> byte_sequence -> string*) -let harness_string_of_elf32_syms f1 os proc bs0:string= - (let hdr = (f1.elf32_file_header) in - let sht = (f1.elf32_file_section_header_table) in - let endian = (get_elf32_header_endianness hdr) in - let sym_secs = (List.filter (fun x -> -(x.elf32_sh_type = Uint32.of_string (Nat_big_num.to_string sht_dynsym)) || -(x.elf32_sh_type = Uint32.of_string (Nat_big_num.to_string sht_symtab))) sht) - in - if List.length sym_secs = 0 then - "\nThere are no symbols in this file." - else - (match get_elf32_file_section_header_string_table f1 with - | Fail err -> err - | Success shdr -> - "\n" ^ - harness_string_of_elf32_syms' endian os proc f1 sym_secs sht shdr bs0 - )) - -(*val harness_string_of_elf64_symbol_table_entry : nat -> (natural -> string) -> (natural -> string) -> string_table -> elf64_symbol_table_entry -> string*) -let harness_string_of_elf64_symbol_table_entry num os proc stbl ent:string= - (let vlu = (unsafe_hex_string_of_natural( 16) (Ml_bindings.nat_big_num_of_uint64 ent.elf64_st_value)) in - let siz = (Nat_big_num.to_string (Ml_bindings.nat_big_num_of_uint64 ent.elf64_st_size)) in - let siz_pad = - (let pad = (Nat_num.nat_monus( 5) (String.length siz)) in - if pad = 0 then - "" - else - concatS (replicate0 (Nat_big_num.of_int pad) " ")) - in - let typ = (string_of_symbol_type (get_elf64_symbol_type ent) os proc) in - let bnd = (string_of_symbol_binding (get_elf64_symbol_binding ent) os proc) in - let bnd_pad = -(let pad = (Nat_num.nat_monus( 8) (String.length typ)) in - if pad = 0 then - "" - else - concatS (replicate0 (Nat_big_num.of_int pad) " ")) - in - let vis = (string_of_symbol_visibility (Nat_big_num.of_string (Uint32.to_string ent.elf64_st_other))) in - let vis_pad = -(let pad = (Nat_num.nat_monus( 6) (String.length bnd)) in - if pad = 0 then - "" - else - concatS (replicate0 (Nat_big_num.of_int pad) " ")) - in - let ndx = -(let tmp = (Nat_big_num.of_string (Uint32.to_string ent.elf64_st_shndx)) in - if Nat_big_num.equal tmp shn_undef then - "UND" - else if Nat_big_num.equal tmp shn_abs then - "ABS" - else - Nat_big_num.to_string tmp) - in - let ndx_pad = -(let pad = (Nat_num.nat_monus( 3) (String.length ndx)) in - if pad = 0 then - "" - else - concatS (replicate0 (Nat_big_num.of_int pad) " ")) - in - let nm = -(let idx1 = (Nat_big_num.of_string (Uint32.to_string ent.elf64_st_name)) in - if Nat_big_num.equal idx1(Nat_big_num.of_int 0) then - "" - else - (match String_table.get_string_at idx1 stbl with - | Fail err -> err - | Success s -> s - )) - in - let num = -(let temp = (Pervasives.string_of_int num) in - let pad = (Nat_num.nat_monus( 3) (String.length temp)) in - if pad = 0 then - temp - else - let spcs = (concatS (replicate0 (Nat_big_num.of_int pad) " ")) in - spcs ^ temp) - in - concatS [ - " " - ; (num ^ ":") - ; " " - ; vlu - ; " " - ; siz_pad; siz - ; " " - ; typ - ; bnd_pad; bnd - ; " " - ; vis_pad; vis - ; " " - ; ndx_pad; ndx - ; " " - ; nm - ]) - -(*val harness_string_of_elf64_syms' : endianness -> (natural -> string) -> (natural -> string) -> elf64_file -> elf64_section_header_table -> elf64_section_header_table -> string_table -> byte_sequence -> string*) -let harness_string_of_elf64_syms' endian os proc f1 filtered_sht sht shdr bs0:string= - (let rels = -(mapM (fun ent -> - let off = (Nat_big_num.of_string (Uint64.to_string ent.elf64_sh_offset)) in - let siz = (Ml_bindings.nat_big_num_of_uint64 ent.elf64_sh_size) in - let lnk = (Nat_big_num.of_string (Uint32.to_string ent.elf64_sh_link)) in - let typ = (Nat_big_num.of_string (Uint32.to_string ent.elf64_sh_type)) in - Byte_sequence.offset_and_cut off siz bs0 >>= (fun syms -> - Elf_symbol_table.read_elf64_symbol_table endian syms >>= (fun sect -> - Elf_file.get_elf64_string_table_by_index f1 lnk >>= (fun strtab -> - return (sect, ent, strtab, typ)))) - ) filtered_sht - >>= - mapM (fun (syms, ent, strtab, typ) -> - let nm = (Nat_big_num.of_string (Uint32.to_string ent.elf64_sh_name)) in - let len = (Pervasives.string_of_int (List.length syms)) in - String_table.get_string_at nm shdr >>= (fun nm -> - let hdr = ("Symbol table '" ^ (nm ^ ("' contains " ^ (len ^ " entries:\n")))) in - let ttl = " Num: Value Size Type Bind Vis Ndx Name\n" in - let body = (concatS (intercalate "\n" (Lem_list.mapi (fun n -> - harness_string_of_elf64_symbol_table_entry n os proc strtab) syms))) - in - return (hdr ^ (ttl ^ body))))) - in - (match rels with - | Fail err -> err - | Success s -> concatS (intercalate "\n\n" s) - )) - -(*val harness_string_of_elf64_syms : elf64_file -> (natural -> string) -> (natural -> string) -> byte_sequence -> string*) -let harness_string_of_elf64_syms f1 os proc bs0:string= - (let hdr = (f1.elf64_file_header) in - let sht = (f1.elf64_file_section_header_table) in - let endian = (get_elf64_header_endianness hdr) in - let sym_secs = (List.filter (fun x -> -(x.elf64_sh_type = Uint32.of_string (Nat_big_num.to_string sht_dynsym)) || -(x.elf64_sh_type = Uint32.of_string (Nat_big_num.to_string sht_symtab))) sht) - in - if List.length sym_secs = 0 then - "\nThere are no symbols in this file." - else - (match get_elf64_file_section_header_string_table f1 with - | Fail err -> err - | Success shdr -> - "\n" ^ - harness_string_of_elf64_syms' endian os proc f1 sym_secs sht shdr bs0 - )) - -(*val string_of_unix_time : natural -> string*) - -(*val string_of_dyn_value : forall 'addr 'size. dyn_value 'addr 'size -> - ('addr -> string) -> ('size -> string) -> string*) -let string_of_dyn_value dyn addr size2:string= - ((match dyn with - | Address a -> addr a - | Size s -> size2 s - | FName f -> f - | Path p -> p - | SOName f -> "Library soname: [" ^ (f ^ "]") - | RPath p -> "Library rpath: [" ^ (p ^ "]") - | RunPath p -> "Library runpath: [" ^ (p ^ "]") - | Flags f -> string_of_dt_flag f - | Flags1 f -> "Flags: " ^ gnu_string_of_dt_flag_1 f - | Ignored -> "" - | Checksum s -> "0x" ^ unsafe_hex_string_of_natural( 0) s - | Library l -> "Shared library: [" ^ (l ^ "]") - | Numeric n -> Nat_big_num.to_string n - | RelType r -> string_of_rel_type r - | Timestamp t -> Ml_bindings.string_of_unix_time t - | Null -> "0x0" - )) - -(*val string_of_elf32_dyn_value : elf32_dyn_value -> string*) -let string_of_elf32_dyn_value dyn:string= - (string_of_dyn_value - dyn - (fun a -> "0x" ^ unsafe_hex_string_of_natural( 0) (Nat_big_num.of_string (Uint32.to_string a))) - (fun s -> Uint32.to_string s ^ " (bytes)")) - -(*val string_of_elf64_dyn_value : elf64_dyn_value -> string*) -let string_of_elf64_dyn_value dyn:string= - (string_of_dyn_value - dyn - (fun a -> "0x" ^ unsafe_hex_string_of_natural( 0) (Ml_bindings.nat_big_num_of_uint64 a)) - (fun s -> Uint64.to_string s ^ " (bytes)")) - -(*val harness_string_of_elf32_dyn_entry : bool -> elf32_dyn -> (natural -> bool) -> (natural -> string) -> - (elf32_dyn -> string_table -> error elf32_dyn_value) -> - (elf32_dyn -> string_table -> error elf32_dyn_value) -> string_table -> string*) -let harness_string_of_elf32_dyn_entry shared_object dyn os_additional_tags typ os_dyn proc_dyn stbl:string= - (let tag = (unsafe_hex_string_of_natural( 8) (Nat_big_num.abs (Nat_big_num.of_int32 dyn.elf32_dyn_tag))) in - let typ = ("(" ^ (typ (Nat_big_num.abs (Nat_big_num.of_int32 dyn.elf32_dyn_tag)) ^ ")")) in - let vlu = -((match get_value_of_elf32_dyn shared_object dyn os_additional_tags os_dyn proc_dyn stbl with - | Fail f -> f - | Success v -> string_of_elf32_dyn_value v - )) - in - let vlu_pad = -(let pad = (Nat_num.nat_monus( 29) (String.length typ)) in - if pad = 0 then - "" - else - let reps = (replicate0 (Nat_big_num.of_int pad) " ") in - concatS reps) - in - concatS [ - " " - ; ("0x" ^ tag) - ; " " - ; typ - ; vlu_pad; vlu - ]) - -(*val harness_string_of_elf32_dynamic_section' : elf32_file -> elf32_program_header_table_entry -> - byte_sequence -> (natural -> bool) -> (natural -> error tag_correspondence) -> - (natural -> error tag_correspondence) -> (natural -> string) -> - (elf32_dyn -> string_table -> error elf32_dyn_value) -> - (elf32_dyn -> string_table -> error elf32_dyn_value) -> string*) -let harness_string_of_elf32_dynamic_section' f1 dyn bs0 os_additional_ranges os proc os_print os_dyn proc_dyn:string= - (let endian = (get_elf32_header_endianness f1.elf32_file_header) in - let sht = (f1.elf32_file_section_header_table) in - let off = (Nat_big_num.of_string (Uint32.to_string dyn.elf32_p_offset)) in - let siz = (Nat_big_num.of_string (Uint32.to_string dyn.elf32_p_filesz)) in - let shared_object = (is_elf32_shared_object_file f1.elf32_file_header) in - let res = -(Byte_sequence.offset_and_cut off siz bs0 >>= (fun rel -> - obtain_elf32_dynamic_section_contents f1 os_additional_ranges os proc bs0 >>= (fun dyns -> - get_string_table_of_elf32_dyn_section endian dyns sht bs0 >>= (fun stbl -> - return (Lem_list.map (fun x -> harness_string_of_elf32_dyn_entry shared_object x os_additional_ranges os_print os_dyn proc_dyn stbl) dyns))))) - in - (match res with - | Fail f -> f - | Success s -> - let off = (unsafe_hex_string_of_natural( 0) off) in - let entries = (Pervasives.string_of_int (List.length s)) in - concatS [ - "\n" - ; ("Dynamic section at offset 0x" ^ (off ^ (" contains " ^ (entries ^ " entries:\n")))) - ; " Tag Type Name/Value\n" - ; concatS (intercalate "\n" s) - ] - )) - -(*val harness_string_of_elf32_dynamic_section : elf32_file -> byte_sequence -> - (natural -> bool) -> (natural -> error tag_correspondence) -> - (natural -> error tag_correspondence) -> (natural -> string) -> - (elf32_dyn -> string_table -> error elf32_dyn_value) -> - (elf32_dyn -> string_table -> error elf32_dyn_value) -> string*) -let harness_string_of_elf32_dynamic_section f1 bs0 os_additional_ranges os proc os_print os_dyn proc_dyn:string= - (let pht = (f1.elf32_file_program_header_table) in - let dyn = -(List.filter (fun x -> - x.elf32_p_type = Uint32.of_string (Nat_big_num.to_string elf_pt_dynamic) - ) pht) - in - let print_msg = (is_elf32_shared_object_file f1.elf32_file_header || - is_elf32_executable_file f1.elf32_file_header) - in - (match dyn with - | [] -> - if print_msg then - "\nThere is no dynamic section in this file." - else - "" - | [x] -> harness_string_of_elf32_dynamic_section' f1 x bs0 os_additional_ranges os proc os_print os_dyn proc_dyn - | _ -> "Multiple dynamic sections detected." - )) - -(*val harness_string_of_elf64_dyn_entry : bool -> elf64_dyn -> (natural -> bool) -> (natural -> string) -> - (elf64_dyn -> string_table -> error elf64_dyn_value) -> - (elf64_dyn -> string_table -> error elf64_dyn_value) -> string_table -> string*) -let harness_string_of_elf64_dyn_entry shared_object dyn os_additional_ranges typ os_dyn proc_dyn stbl:string= - (let tag = (unsafe_hex_string_of_natural( 16) (Nat_big_num.abs (Nat_big_num.of_int64 dyn.elf64_dyn_tag))) in - let typ = ("(" ^ (typ (Nat_big_num.abs (Nat_big_num.of_int64 dyn.elf64_dyn_tag)) ^ ")")) in - let vlu = -((match get_value_of_elf64_dyn shared_object dyn os_additional_ranges os_dyn proc_dyn stbl with - | Fail f -> f - | Success v -> string_of_elf64_dyn_value v - )) - in - let vlu_pad = -(let pad = (Nat_num.nat_monus( 21) (String.length typ)) in - if pad = 0 then - "" - else - let reps = (replicate0 (Nat_big_num.of_int pad) " ") in - concatS reps) - in - concatS [ - " " - ; ("0x" ^ tag) - ; " " - ; typ - ; vlu_pad; vlu - ]) - -(*val harness_string_of_elf64_dynamic_section' : elf64_file -> elf64_program_header_table_entry -> - byte_sequence -> (natural -> bool) -> (natural -> error tag_correspondence) -> - (natural -> error tag_correspondence) -> (natural -> string) -> - (elf64_dyn -> string_table -> error elf64_dyn_value) -> - (elf64_dyn -> string_table -> error elf64_dyn_value) -> string*) -let harness_string_of_elf64_dynamic_section' f1 dyn bs0 os_additional_ranges os proc os_print os_dyn proc_dyn:string= - (let endian = (get_elf64_header_endianness f1.elf64_file_header) in - let sht = (f1.elf64_file_section_header_table) in - let off = (Nat_big_num.of_string (Uint64.to_string dyn.elf64_p_offset)) in - let siz = (Ml_bindings.nat_big_num_of_uint64 dyn.elf64_p_filesz) in - let shared_object = (is_elf64_shared_object_file f1.elf64_file_header) in - let res = -(Byte_sequence.offset_and_cut off siz bs0 >>= (fun rel -> - obtain_elf64_dynamic_section_contents f1 os_additional_ranges os proc bs0 >>= (fun dyns -> - get_string_table_of_elf64_dyn_section endian dyns sht bs0 >>= (fun stbl -> - return (Lem_list.map (fun x -> harness_string_of_elf64_dyn_entry shared_object x os_additional_ranges os_print os_dyn proc_dyn stbl) dyns))))) - in - (match res with - | Fail f -> f - | Success s -> - let off = (unsafe_hex_string_of_natural( 0) off) in - let entries = (Pervasives.string_of_int (List.length s)) in - concatS [ - "\n" - ; ("Dynamic section at offset 0x" ^ (off ^ (" contains " ^ (entries ^ " entries:\n")))) - ; " Tag Type Name/Value\n" - ; concatS (intercalate "\n" s) - ] - )) - -(*val harness_string_of_elf64_dynamic_section : elf64_file -> byte_sequence -> - (natural -> bool) -> (natural -> error tag_correspondence) -> - (natural -> error tag_correspondence) -> (natural -> string) -> - (elf64_dyn -> string_table -> error elf64_dyn_value) -> - (elf64_dyn -> string_table -> error elf64_dyn_value) -> string*) -let harness_string_of_elf64_dynamic_section f1 bs0 os_additional_ranges os proc os_print os_dyn proc_dyn:string= - (let pht = (f1.elf64_file_program_header_table) in - let print_msg = (is_elf64_shared_object_file f1.elf64_file_header || - is_elf64_executable_file f1.elf64_file_header) - in - let dyn = -(List.filter (fun x -> - x.elf64_p_type = Uint32.of_string (Nat_big_num.to_string elf_pt_dynamic) - ) pht) - in - (match dyn with - | [] -> - if print_msg then - "\nThere is no dynamic section in this file." - else - "" - | [x] -> harness_string_of_elf64_dynamic_section' f1 x bs0 os_additional_ranges os proc os_print os_dyn proc_dyn - | _ -> "Multiple dynamic sections detected." - )) - - diff --git a/lib/ocaml_rts/linksem/adaptors/sail_interface.ml b/lib/ocaml_rts/linksem/adaptors/sail_interface.ml deleted file mode 100644 index f3024467..00000000 --- a/lib/ocaml_rts/linksem/adaptors/sail_interface.ml +++ /dev/null @@ -1,250 +0,0 @@ -(*Generated by Lem from adaptors/sail_interface.lem.*) -open Lem_basic_classes -open Lem_function -open Lem_list -open Lem_maybe -open Lem_num -open Lem_string -open Lem_tuple - -open Lem_assert_extra - -open Byte_sequence -open Error -open Missing_pervasives -open Show - -open Elf_header -open Elf_file -open Elf_interpreted_section -open Elf_interpreted_segment -open String_table -open Elf_symbol_table -open Elf_program_header_table -open Elf_types_native_uint - -open Hex_printing - -type executable_process_image = - | ELF_Class_32 of elf32_executable_process_image - | ELF_Class_64 of elf64_executable_process_image - -(*val string_of_segment_provenance : segment_provenance -> string*) -let string_of_segment_provenance p:string= - ((match p with - | FromELF -> "Segment from ELF file" - | AutoGenerated -> "Segment auto generated" - )) - -(*val string_of_executable_process_image : executable_process_image -> string*) -let string_of_executable_process_image img2:string= - ((match img2 with - | ELF_Class_32 (segs, entry_point, machine_type) -> - let machine_type = (string_of_elf_machine_architecture machine_type) in - let entry_point = (unsafe_hex_string_of_natural( 16) entry_point) in - let segs = (Lem_list.map (fun (seg, prov) -> - let prov = (string_of_segment_provenance prov) in - let seg = (string_of_elf32_interpreted_segment seg) in - "Segment provenance: " ^ (prov ^ ("\n" ^ seg)) - ) segs) - in - unlines ( List.rev_append (List.rev [ - "32-bit ELF executable image" - ; ("Machine type: " ^ machine_type) - ; ("Entry point: " ^ entry_point) - ; "" - ]) segs) - | ELF_Class_64 (segs, entry_point, machine_type) -> - let machine_type = (string_of_elf_machine_architecture machine_type) in - let entry_point = (unsafe_hex_string_of_natural( 16) entry_point) in - let segs = (intercalate "\n" (Lem_list.map (fun (seg, prov) -> - let prov = (string_of_segment_provenance prov) in - let seg = (string_of_elf64_interpreted_segment seg) in - "Segment provenance: " ^ (prov ^ ("\n" ^ seg)) - ) segs)) - in - unlines ( List.rev_append (List.rev [ - "64-bit ELF executable image" - ; ("Machine type: " ^ machine_type) - ; ("Entry point: " ^ entry_point) - ; "" - ]) segs) - )) - -(*val populate : string -> error executable_process_image*) -let populate fname1:(executable_process_image)error= -( - (* Acquire the data from the file... *)Byte_sequence.acquire fname1 >>= (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 Lem_list.list_index ident( 4) with - | None -> fail "populate: ELF ident transcription error" - | Some c -> - (* Calculate whether we are dealing with a 32- or 64-bit file based on - * what we have read... - *) - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string c)) Elf_header.elf_class_32 then - Elf_file.read_elf32_file bs0 >>= (fun ef5 -> - if Elf_program_header_table.get_elf32_static_linked ef5.elf32_file_program_header_table then - Elf_file.get_elf32_executable_image ef5 >>= (fun img2 -> - return (ELF_Class_32 img2)) - else - fail "populate: not a statically linked executable") - else if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string c)) Elf_header.elf_class_64 then - Elf_file.read_elf64_file bs0 >>= (fun ef5 -> - if Elf_program_header_table.get_elf64_static_linked ef5.elf64_file_program_header_table then - Elf_file.get_elf64_executable_image ef5 >>= (fun img2 -> - return (ELF_Class_64 img2)) - else - fail "populate: not a statically linked executable") - else - fail "populate: ELF class unrecognised" - )))) - -(*val populate' : byte_sequence -> error executable_process_image*) -let populate' bs0:(executable_process_image)error= -( - (* 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 Lem_list.list_index ident( 4) with - | None -> fail "populate': ELF ident transcription error" - | Some c -> - (* Calculate whether we are dealing with a 32- or 64-bit file based on - * what we have read... - *) - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string c)) Elf_header.elf_class_32 then - Elf_file.read_elf32_file bs0 >>= (fun ef5 -> - if Elf_program_header_table.get_elf32_static_linked ef5.elf32_file_program_header_table then - Elf_file.get_elf32_executable_image ef5 >>= (fun img2 -> - return (ELF_Class_32 img2)) - else - fail "populate': not a statically linked executable") - else if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string c)) Elf_header.elf_class_64 then - Elf_file.read_elf64_file bs0 >>= (fun ef5 -> - if Elf_program_header_table.get_elf64_static_linked ef5.elf64_file_program_header_table then - Elf_file.get_elf64_executable_image ef5 >>= (fun img2 -> - return (ELF_Class_64 img2)) - else - fail "populate': not a statically linked executable") - else - fail "populate': ELF class unrecognised" - ))) - -(*val obtain_global_symbol_init_info : string -> error global_symbol_init_info*) -let obtain_global_symbol_init_info fname1:((string*(Nat_big_num.num*Nat_big_num.num*Nat_big_num.num*(byte_sequence)option*Nat_big_num.num))list)error= -( - (* Acquire the data from the file... *)Byte_sequence.acquire fname1 >>= (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 Lem_list.list_index ident( 4) with - | None -> fail "obtain_global_symbol_init_info: ELF ident transcription error" - | Some c -> - (* Calculate whether we are dealing with a 32- or 64-bit file based on - * what we have read... - *) - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string c)) Elf_header.elf_class_32 then - Elf_file.read_elf32_file bs0 >>= (fun f1 -> - if Elf_program_header_table.get_elf32_static_linked f1.elf32_file_program_header_table then - Elf_file.get_elf32_file_global_symbol_init f1 >>= (fun init1 -> - return init1) - else - fail "obtain_global_symbol_init_info: not a statically linked executable") - else if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string c)) Elf_header.elf_class_64 then - Elf_file.read_elf64_file bs0 >>= (fun f1 -> - if Elf_program_header_table.get_elf64_static_linked f1.elf64_file_program_header_table then - Elf_file.get_elf64_file_global_symbol_init f1 >>= (fun init1 -> - return init1) - else - fail "obtain_global_symbol_init_info: not a statically linked executable") - else - fail "obtain_global_symbol_init_info: ELF class unrecognised" - )))) - -(*val obtain_global_symbol_init_info' : byte_sequence -> error global_symbol_init_info*) -let obtain_global_symbol_init_info' bs0:((string*(Nat_big_num.num*Nat_big_num.num*Nat_big_num.num*(byte_sequence)option*Nat_big_num.num))list)error= -( - (* 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 Lem_list.list_index ident( 4) with - | None -> fail "obtain_global_symbol_init_info': ELF ident transcription error" - | Some c -> - (* Calculate whether we are dealing with a 32- or 64-bit file based on - * what we have read... - *) - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string c)) Elf_header.elf_class_32 then - Elf_file.read_elf32_file bs0 >>= (fun f1 -> - if Elf_program_header_table.get_elf32_static_linked f1.elf32_file_program_header_table then - Elf_file.get_elf32_file_global_symbol_init f1 >>= (fun init1 -> - return init1) - else - fail "obtain_global_symbol_init_info': not a statically linked executable") - else if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string c)) Elf_header.elf_class_64 then - Elf_file.read_elf64_file bs0 >>= (fun f1 -> - if Elf_program_header_table.get_elf64_static_linked f1.elf64_file_program_header_table then - Elf_file.get_elf64_file_global_symbol_init f1 >>= (fun init1 -> - return init1) - else - fail "obtain_global_symbol_init_info': not a statically linked executable") - else - fail "obtain_global_symbol_init_info': ELF class unrecognised" - ))) - -(*val populate_and_obtain_global_symbol_init_info : string -> error (elf_file * executable_process_image * global_symbol_init_info)*) -let populate_and_obtain_global_symbol_init_info fname1:(elf_file*executable_process_image*(string*(Nat_big_num.num*Nat_big_num.num*Nat_big_num.num*(byte_sequence)option*Nat_big_num.num))list)error= -( - (* Acquire the data from the file... *)Byte_sequence.acquire fname1 >>= (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 Lem_list.list_index ident( 4) with - | None -> fail "populate_and_obtain_global_symbol_init_info: ELF ident transcription error" - | Some c -> - (* Calculate whether we are dealing with a 32- or 64-bit file based on - * what we have read... - *) - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string c)) Elf_header.elf_class_32 then - Elf_file.read_elf32_file bs0 >>= (fun f1 -> - if Elf_program_header_table.get_elf32_static_linked f1.elf32_file_program_header_table then - Elf_file.get_elf32_file_global_symbol_init f1 >>= (fun init1 -> - Elf_file.get_elf32_executable_image f1 >>= (fun img2 -> - return ((ELF_File_32 f1), (ELF_Class_32 img2), init1))) - else - fail "populate_and_obtain_global_symbol_init_info: not a statically linked executable") - else if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string c)) Elf_header.elf_class_64 then - Elf_file.read_elf64_file bs0 >>= (fun f1 -> - if Elf_program_header_table.get_elf64_static_linked f1.elf64_file_program_header_table then - Elf_file.get_elf64_file_global_symbol_init f1 >>= (fun init1 -> - Elf_file.get_elf64_executable_image f1 >>= (fun img2 -> - return ((ELF_File_64 f1), (ELF_Class_64 img2), init1))) - else - fail "populate_and_obtain_global_symbol_init_info: not a statically linked executable") - else - fail "populate_and_obtain_global_symbol_init_info: ELF class unrecognised" - )))) - -(*val populate_and_obtain_global_symbol_init_info' : byte_sequence -> error (elf_file * executable_process_image * global_symbol_init_info)*) -let populate_and_obtain_global_symbol_init_info' bs0:(elf_file*executable_process_image*(string*(Nat_big_num.num*Nat_big_num.num*Nat_big_num.num*(byte_sequence)option*Nat_big_num.num))list)error= -( - (* 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 Lem_list.list_index ident( 4) with - | None -> fail "populate_and_obtain_global_symbol_init_info': ELF ident transcription error" - | Some c -> - (* Calculate whether we are dealing with a 32- or 64-bit file based on - * what we have read... - *) - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string c)) Elf_header.elf_class_32 then - Elf_file.read_elf32_file bs0 >>= (fun f1 -> - if Elf_program_header_table.get_elf32_static_linked f1.elf32_file_program_header_table then - Elf_file.get_elf32_file_global_symbol_init f1 >>= (fun init1 -> - Elf_file.get_elf32_executable_image f1 >>= (fun img2 -> - return ((ELF_File_32 f1), (ELF_Class_32 img2), init1))) - else - fail "populate_and_obtain_global_symbol_init_info': not a statically linked executable") - else if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string c)) Elf_header.elf_class_64 then - Elf_file.read_elf64_file bs0 >>= (fun f1 -> - if Elf_program_header_table.get_elf64_static_linked f1.elf64_file_program_header_table then - Elf_file.get_elf64_file_global_symbol_init f1 >>= (fun init1 -> - Elf_file.get_elf64_executable_image f1 >>= (fun img2 -> - return ((ELF_File_64 f1), (ELF_Class_64 img2), init1))) - else - fail "populate_and_obtain_global_symbol_init_info': not a statically linked executable") - else - fail "populate_and_obtain_global_symbol_init_info': ELF class unrecognised" - ))) diff --git a/lib/ocaml_rts/linksem/archive.ml b/lib/ocaml_rts/linksem/archive.ml deleted file mode 100644 index cd4480b4..00000000 --- a/lib/ocaml_rts/linksem/archive.ml +++ /dev/null @@ -1,150 +0,0 @@ -(*Generated by Lem from archive.lem.*) -open Lem_basic_classes -open Lem_bool -open Lem_list -open Lem_num -open Lem_maybe -open Lem_string -open Show -open Lem_assert_extra - -open Missing_pervasives -open Byte_sequence -open Error - -type archive_entry_header = - { name : string - ; timestamp : Nat_big_num.num - ; uid : int - ; gid : int - ; mode : int - ; size : int (* 1GB should be enough *) - } - -type archive_global_header = char - list - -(*val string_of_byte_sequence : byte_sequence -> string*) -let string_of_byte_sequence0 seq:string= - ((match seq with - | Sequence bs -> Xstring.implode (Lem_list.map (fun x-> x) bs) - )) - -(*val read_archive_entry_header : natural -> byte_sequence -> error (archive_entry_header * natural * byte_sequence)*) -let read_archive_entry_header seq_length seq:(archive_entry_header*Nat_big_num.num*byte_sequence)error= - (let magic_bytes = ([Char.chr (Nat_big_num.to_int (Nat_big_num.of_int 96)) (* 0x60 *); Char.chr (Nat_big_num.to_int (Nat_big_num.of_int 10)) (* 0x0a *)]) in - let header_length =(Nat_big_num.of_int 60) in - (* let _ = Missing_pervasives.errs ("Archive entry header? " ^ (show (take 16 bs)) ^ "? ") in *) - partition_with_length header_length seq_length seq >>= (fun (header, rest) -> - offset_and_cut(Nat_big_num.of_int 58)(Nat_big_num.of_int 2) header >>= (fun magic -> - offset_and_cut(Nat_big_num.of_int 0)(Nat_big_num.of_int 16) header >>= (fun name1 -> - offset_and_cut(Nat_big_num.of_int 16)(Nat_big_num.of_int 12) header >>= (fun timestamp_str -> - offset_and_cut(Nat_big_num.of_int 28)(Nat_big_num.of_int 6) header >>= (fun uid_str -> - offset_and_cut(Nat_big_num.of_int 34)(Nat_big_num.of_int 6) header >>= (fun gid_str -> - offset_and_cut(Nat_big_num.of_int 40)(Nat_big_num.of_int 8) header >>= (fun mode_str -> - offset_and_cut(Nat_big_num.of_int 48)(Nat_big_num.of_int 10) header >>= (fun size_str -> - let size2 = (natural_of_decimal_string (string_of_byte_sequence0 size_str)) in - (* let _ = Missing_pervasives.errln (": yes, size " ^ (show size)) in *) - return ({ name = (string_of_byte_sequence0 name1); timestamp = ((Nat_big_num.of_int 0 : Nat_big_num.num)) (* FIXME *); - uid =( 0) (* FIXME *) ; gid =( 0) (* FIXME *) ; mode =( 0) (* FIXME *); - size = (Nat_big_num.to_int size2) (* FIXME *) }, Nat_big_num.sub_nat seq_length header_length, rest)))))))))) - -(*val read_archive_global_header : byte_sequence -> error (archive_global_header * byte_sequence)*) -let read_archive_global_header seq:((char)list*byte_sequence)error= - ((match seq with - | Sequence bs -> - (* let _ = Missing_pervasives.errs ("Archive? " ^ (show (take 16 bs)) ^ "? ") - in*) - let chars = (Lem_list.map (fun x-> x) (take0(Nat_big_num.of_int 8) bs)) in - if Xstring.implode chars = "!<arch>\n" then - (* let _ = Missing_pervasives.errln ": yes" in *) - return (chars, Sequence(drop0(Nat_big_num.of_int 8) bs)) - else - (* let _ = Missing_pervasives.errln ": no" in *) - fail "read_archive_global_header: not an archive" - )) - -(*val accum_archive_contents : (list (string * byte_sequence)) -> maybe string -> natural -> byte_sequence -> error (list (string * byte_sequence))*) -let rec accum_archive_contents accum extended_filenames whole_seq_length whole_seq:((string*byte_sequence)list)error= -( - (* let _ = Missing_pervasives.errs "Can read a header? " in *)if not (Nat_big_num.equal (Byte_sequence.length0 whole_seq) whole_seq_length) then -(assert false) (* invariant: whole_seq_length always equal to length of whole_seq, so the length is only - computed one. This "fail" needed for Isabelle termination proofs... *) - else - (match (read_archive_entry_header whole_seq_length whole_seq) with - | Fail _ -> return accum - | Success (hdr, (seq_length : Nat_big_num.num), seq) -> - (match seq with - | Sequence next_bs -> - (* let _ = Missing_pervasives.errln ("yes; next_bs has length " ^ (show (List.length next_bs))) in *) - let amount_to_drop = -(if (hdr.size mod 2) = 0 then - (Nat_big_num.of_int hdr.size) - else Nat_big_num.add - (Nat_big_num.of_int hdr.size)(Nat_big_num.of_int 1)) - in - if Nat_big_num.equal amount_to_drop(Nat_big_num.of_int 0) then - fail "accum_archive_contents: amount to drop from byte sequence is 0" - else - (*let _ = Missing_pervasives.errln ("amount_to_drop is " ^ (show amount_to_drop)) in*) - let chunk = (Sequence(Lem_list.take hdr.size next_bs)) - in - (*let _ = Missing_pervasives.errs ("Processing archive header named " ^ hdr.name) - in*) - let (new_accum, (new_extended_filenames : string option)) = -(let name1 = (Xstring.explode hdr.name) in - if (listEqualBy (=) name1 ['/'; ' '; ' '; ' '; ' '; ' '; ' '; ' '; ' '; ' '; ' '; ' '; ' '; ' '; ' '; ' ']) then - (* SystemV symbol lookup table; we skip this *) (accum, extended_filenames) - else - (match name1 with - | x::xs -> - if x = '/' then - (match xs with - | y::ys -> - if y = '/' then - (accum, Some (string_of_byte_sequence0 chunk)) - else - let index = (natural_of_decimal_string (Xstring.implode xs)) in - (match extended_filenames with - | None -> failwith "corrupt archive: reference to non-existent extended filenames" - | Some s -> - let table_suffix = ((match Ml_bindings.string_suffix index s with Some x -> x | None -> "" )) in - let index = ((match Ml_bindings.string_index_of '/' table_suffix with Some x -> x | None -> (Nat_big_num.of_int (String.length table_suffix)) )) in - let ext_name = ((match Ml_bindings.string_prefix index table_suffix with Some x -> x | None -> "" )) in - (*let _ = Missing_pervasives.errln ("Got ext_name " ^ ext_name) in*) - (((ext_name, chunk) :: accum), extended_filenames) - ) - | [] -> - let index = (natural_of_decimal_string (Xstring.implode xs)) in - (match extended_filenames with - | None -> failwith "corrupt archive: reference to non-existent extended filenames" - | Some s -> - let table_suffix = ((match Ml_bindings.string_suffix index s with Some x -> x | None -> "" )) in - let index = ((match Ml_bindings.string_index_of '/' table_suffix with Some x -> x | None -> (Nat_big_num.of_int (String.length table_suffix)) )) in - let ext_name = ((match Ml_bindings.string_prefix index table_suffix with Some x -> x | None -> "" )) in - (*let _ = Missing_pervasives.errln ("Got ext_name " ^ ext_name) in*) - (((ext_name, chunk) :: accum), extended_filenames) - ) - ) - else - (((hdr.name, chunk) :: accum), extended_filenames) - | [] -> (((hdr.name, chunk) :: accum), extended_filenames) - )) - in - (match (Byte_sequence.dropbytes amount_to_drop seq) with - | Fail _ -> return accum - | Success new_seq -> - accum_archive_contents new_accum new_extended_filenames ( Nat_big_num.sub_nat seq_length amount_to_drop) new_seq - ) - ) - )) - -(*val read_archive : byte_sequence -> error (list (string * byte_sequence))*) -let read_archive bs:((string*byte_sequence)list)error= - (read_archive_global_header bs >>= (fun (hdr, seq) -> - let result = (accum_archive_contents [] None (Byte_sequence.length0 seq) seq) in - (* let _ = Missing_pervasives.errln "Finished reading archive" in *) - (match result with - Success r -> Success (List.rev r) - | Fail x -> Fail x - ))) diff --git a/lib/ocaml_rts/linksem/byte_sequence.ml b/lib/ocaml_rts/linksem/byte_sequence.ml deleted file mode 100644 index 27eb6d81..00000000 --- a/lib/ocaml_rts/linksem/byte_sequence.ml +++ /dev/null @@ -1,335 +0,0 @@ -(*Generated by Lem from byte_sequence.lem.*) -(** [byte_sequence.lem], a list of bytes used for ELF I/O and other basic tasks - * in the ELF model. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_list -open Lem_num -open Lem_string -open Lem_assert_extra - -open Error -open Missing_pervasives -open Show - -(** A [byte_sequence], [bs], denotes a consecutive list of bytes. Can be read - * from or written to a binary file. Most basic type in the ELF formalisation. - *) -type byte_sequence = - Sequence of ( char list) - -(** [byte_list_of_byte_sequence bs] obtains the underlying list of bytes of the - * byte sequence [bs]. - *) -(*val byte_list_of_byte_sequence : byte_sequence -> list byte*) -let byte_list_of_byte_sequence bs0:(char)list= - ((match bs0 with - | Sequence xs -> xs - )) - -(** [compare_byte_sequence bs1 bs2] is an ordering comparison function for byte - * sequences, suitable for constructing sets, maps and other ordered types - * with. - *) -(*val compare_byte_sequence : byte_sequence -> byte_sequence -> ordering*) -let compare_byte_sequence s1 s2:int= -(lexicographic_compare compare_byte (byte_list_of_byte_sequence s1) (byte_list_of_byte_sequence s2)) - -let instance_Basic_classes_Ord_Byte_sequence_byte_sequence_dict:(byte_sequence)ord_class= ({ - - compare_method = compare_byte_sequence; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(compare_byte_sequence f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> let result = (compare_byte_sequence f1 f2) in Lem.orderingEqual result (-1) || Lem.orderingEqual result 0)); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(compare_byte_sequence f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> let result = (compare_byte_sequence f1 f2) in Lem.orderingEqual result 1 || Lem.orderingEqual result 0))}) - -(** [acquire_byte_list fname] exhaustively reads in a list of bytes from a file - * pointed to by filename [fname]. Fails if the file does not exist, or if the - * transcription otherwise fails. Implemented as a primitive in OCaml. - *) -(*val acquire_byte_list : string -> error (list byte)*) - -(** [acquire fname] exhaustively reads in a byte_sequence from a file pointed to - * by filename [fname]. Fails if the file does not exist, or if the transcription - * otherwise fails. - *) -(*val acquire : string -> error byte_sequence*) -let acquire fname1:(byte_sequence)error= - (Byte_sequence_wrapper.acquire_char_list fname1 >>= (fun bs -> - return (Sequence bs))) - -(** [serialise_byte_list fname bs] writes a list of bytes, [bs], to a binary file - * pointed to by filename [fname]. Fails if the transcription fails. Implemented - * as a primitive in OCaml. - *) -(*val serialise_byte_list : string -> list byte -> error unit*) - -(** [serialise fname bs0] writes a byte sequence, [bs0], to a binary file pointed - * to by filename [fname]. Fails if the transcription fails. - *) -(*val serialise : string -> byte_sequence -> error unit*) -let serialise fname1 ss:(unit)error= - ((match ss with - | Sequence ts -> Byte_sequence_wrapper.serialise_char_list fname1 ts - )) - -(** [empty], the empty byte sequence. - *) -(*val empty : byte_sequence*) -let empty:byte_sequence= (Sequence []) - -(** [read_char bs0] reads a single byte from byte sequence [bs0] and returns the - * remainder of the byte sequence. Fails if [bs0] is empty. - * TODO: rename to read_byte, probably. - *) -(*val read_char : byte_sequence -> error (byte * byte_sequence)*) -let read_char (Sequence ts):(char*byte_sequence)error= - ((match ts with - | [] -> fail "read_char: sequence is empty" - | x::xs -> return (x, Sequence xs) - )) - -(** [repeat cnt b] creates a list of length [cnt] containing only [b]. - * TODO: move into missing_pervasives.lem. - *) -(*val repeat' : natural -> byte -> list byte -> list byte*) -let rec repeat' count c acc:(char)list= - ( - if(Nat_big_num.equal count (Nat_big_num.of_int 0)) then acc else - (repeat' ( Nat_big_num.sub_nat count (Nat_big_num.of_int 1)) c (c :: acc))) - -(*val repeat : natural -> byte -> list byte*) -let repeat count c:(char)list= (repeat' count c []) - -(** [create cnt b] creates a byte sequence of length [cnt] containing only [b]. - *) -(*val create : natural -> byte -> byte_sequence*) -let create count c:byte_sequence= - (Sequence (repeat count c)) - -(** [zeros cnt] creates a byte sequence of length [cnt] containing only 0, the - * null byte. - *) -(*val zeros : natural -> byte_sequence*) -let zeros m:byte_sequence= - (create m '\000') - -(** [length bs0] returns the length of [bs0]. - *) -(*val length : byte_sequence -> natural*) -let length0 (Sequence ts):Nat_big_num.num= - (Nat_big_num.of_int (List.length ts)) - - -(** [concat bs] concatenates a list of byte sequences, [bs], into a single byte - * sequence, maintaining byte order across the sequences. - *) -(*val concat : list byte_sequence -> byte_sequence*) -let rec concat0 ts:byte_sequence= - ((match ts with - | [] -> Sequence [] - | ((Sequence x)::xs) -> - (match concat0 xs with - | Sequence tail -> Sequence ( List.rev_append (List.rev x) tail) - ) - )) - -(** [zero_pad_to_length len bs0] pads (on the right) consecutive zeros until the - * resulting byte sequence is [len] long. Returns [bs0] if [bs0] is already of - * greater length than [len]. - *) -(*val zero_pad_to_length : natural -> byte_sequence -> byte_sequence*) -let zero_pad_to_length len bs:byte_sequence= - (let curlen = (length0 bs) in - if Nat_big_num.greater_equal curlen len then - bs - else - concat0 [bs ; (zeros ( Nat_big_num.sub_nat len curlen))]) - -(** [from_byte_lists bs] concatenates a list of bytes [bs] and creates a byte - * sequence from their contents. Maintains byte order in [bs]. - *) -(*val from_byte_lists : list (list byte) -> byte_sequence*) -let from_byte_lists ts:byte_sequence= - (Sequence (List.concat ts)) - -(** [string_of_char_list cs] converts a list of characters into a string. - * Implemented as a primitive in OCaml. - *) -(*val string_of_char_list : list char -> string*) - -(** [char_list_of_byte_list bs] converts byte list [bs] into a list of characters. - * Implemented as a primitive in OCaml and Isabelle. - * TODO: is this actually being used in the Isabelle backend? All string functions - * should be factored out by target-specific definitions. - *) -(*val char_list_of_byte_list : list byte -> list char*) - -(** [string_of_byte_sequence bs0] converts byte sequence [bs0] into a string - * representation. - *) -(*val string_of_byte_sequence : byte_sequence -> string*) -let string_of_byte_sequence (Sequence ts):string= - (let cs = ( ts) in - Xstring.implode cs) - -(** [equal bs0 bs1] checks whether two byte sequences, [bs0] and [bs1], are equal. - *) -(*val equal : byte_sequence -> byte_sequence -> bool*) -let rec equal left right:bool= - ((match (left, right) with - | (Sequence [], Sequence []) -> true - | (Sequence (x::xs), Sequence (y::ys)) -> -(x = y) && equal (Sequence xs) (Sequence ys) - | (_, _) -> false - )) - -(** [dropbytes cnt bs0] drops [cnt] bytes from byte sequence [bs0]. Fails if - * [cnt] is greater than the length of [bs0]. - *) -(*val dropbytes : natural -> byte_sequence -> error byte_sequence*) -let rec dropbytes count (Sequence ts):(byte_sequence)error= - (if Nat_big_num.equal count Nat_big_num.zero then - return (Sequence ts) - else - (match ts with - | [] -> fail "dropbytes: cannot drop more bytes than are contained in sequence" - | x::xs -> dropbytes ( Nat_big_num.sub_nat count(Nat_big_num.of_int 1)) (Sequence xs) - )) - -(*val takebytes_r_with_length: nat -> natural -> byte_sequence -> error byte_sequence*) -let rec takebytes_r_with_length count ts_length (Sequence ts):(byte_sequence)error= - (if Nat_big_num.greater_equal ts_length (Nat_big_num.of_int count) then - return (Sequence (list_take_with_accum count [] ts)) - else - fail "takebytes: cannot take more bytes than are contained in sequence") - -(*val takebytes : natural -> byte_sequence -> error byte_sequence*) -let takebytes count (Sequence ts):(byte_sequence)error= - (let result = (takebytes_r_with_length (Nat_big_num.to_int count) (Missing_pervasives.length ts) (Sequence ts)) in - result) - -(*val takebytes_with_length : natural -> natural -> byte_sequence -> error byte_sequence*) -let takebytes_with_length count ts_length (Sequence ts):(byte_sequence)error= -( - (* let _ = Missing_pervasives.errs ("Trying to take " ^ (show count) ^ " bytes from sequence of " ^ (show (List.length ts)) ^ "\n") in *)let result = (takebytes_r_with_length (Nat_big_num.to_int count) ts_length (Sequence ts)) in - (*let _ = Missing_pervasives.errs ("Succeeded\n") in *) - result) - -(** [read_2_bytes_le bs0] reads two bytes from [bs0], returning them in - * little-endian order, and returns the remainder of [bs0]. Fails if [bs0] has - * length less than 2. - *) -(*val read_2_bytes_le : byte_sequence -> error ((byte * byte) * byte_sequence)*) -let read_2_bytes_le bs0:((char*char)*byte_sequence)error= - (read_char bs0 >>= (fun (b0, bs1) -> - read_char bs1 >>= (fun (b1, bs2) -> - return ((b1, b0), bs2)))) - -(** [read_2_bytes_be bs0] reads two bytes from [bs0], returning them in - * big-endian order, and returns the remainder of [bs0]. Fails if [bs0] has - * length less than 2. - *) -(*val read_2_bytes_be : byte_sequence -> error ((byte * byte) * byte_sequence)*) -let read_2_bytes_be bs0:((char*char)*byte_sequence)error= - (read_char bs0 >>= (fun (b0, bs1) -> - read_char bs1 >>= (fun (b1, bs2) -> - return ((b0, b1), bs2)))) - -(** [read_4_bytes_le bs0] reads four bytes from [bs0], returning them in - * little-endian order, and returns the remainder of [bs0]. Fails if [bs0] has - * length less than 4. - *) -(*val read_4_bytes_le : byte_sequence -> error ((byte * byte * byte * byte) * byte_sequence)*) -let read_4_bytes_le bs0:((char*char*char*char)*byte_sequence)error= - (read_char bs0 >>= (fun (b0, bs1) -> - read_char bs1 >>= (fun (b1, bs2) -> - read_char bs2 >>= (fun (b2, bs3) -> - read_char bs3 >>= (fun (b3, bs4) -> - return ((b3, b2, b1, b0), bs4)))))) - -(** [read_4_bytes_be bs0] reads four bytes from [bs0], returning them in - * big-endian order, and returns the remainder of [bs0]. Fails if [bs0] has - * length less than 4. - *) -(*val read_4_bytes_be : byte_sequence -> error ((byte * byte * byte * byte) * byte_sequence)*) -let read_4_bytes_be bs0:((char*char*char*char)*byte_sequence)error= - (read_char bs0 >>= (fun (b0, bs1) -> - read_char bs1 >>= (fun (b1, bs2) -> - read_char bs2 >>= (fun (b2, bs3) -> - read_char bs3 >>= (fun (b3, bs4) -> - return ((b0, b1, b2, b3), bs4)))))) - -(** [read_8_bytes_le bs0] reads eight bytes from [bs0], returning them in - * little-endian order, and returns the remainder of [bs0]. Fails if [bs0] has - * length less than 8. - *) -(*val read_8_bytes_le : byte_sequence -> error ((byte * byte * byte * byte * byte * byte * byte * byte) * byte_sequence)*) -let read_8_bytes_le bs0:((char*char*char*char*char*char*char*char)*byte_sequence)error= - (read_char bs0 >>= (fun (b0, bs1) -> - read_char bs1 >>= (fun (b1, bs2) -> - read_char bs2 >>= (fun (b2, bs3) -> - read_char bs3 >>= (fun (b3, bs4) -> - read_char bs4 >>= (fun (b4, bs5) -> - read_char bs5 >>= (fun (b5, bs6) -> - read_char bs6 >>= (fun (b6, bs7) -> - read_char bs7 >>= (fun (b7, bs8) -> - return ((b7, b6, b5, b4, b3, b2, b1, b0), bs8)))))))))) - -(** [read_8_bytes_be bs0] reads eight bytes from [bs0], returning them in - * big-endian order, and returns the remainder of [bs0]. Fails if [bs0] has - * length less than 8. - *) -(*val read_8_bytes_be : byte_sequence -> error ((byte * byte * byte * byte * byte * byte * byte * byte) * byte_sequence)*) -let read_8_bytes_be bs0:((char*char*char*char*char*char*char*char)*byte_sequence)error= - (read_char bs0 >>= (fun (b0, bs1) -> - read_char bs1 >>= (fun (b1, bs2) -> - read_char bs2 >>= (fun (b2, bs3) -> - read_char bs3 >>= (fun (b3, bs4) -> - read_char bs4 >>= (fun (b4, bs5) -> - read_char bs5 >>= (fun (b5, bs6) -> - read_char bs6 >>= (fun (b6, bs7) -> - read_char bs7 >>= (fun (b7, bs8) -> - return ((b0, b1, b2, b3, b4, b5, b6, b7), bs8)))))))))) - -(** [partition pnt bs0] splits [bs0] into two parts at index [pnt]. Fails if - * [pnt] is greater than the length of [bs0]. - *) -(*val partition : natural -> byte_sequence -> error (byte_sequence * byte_sequence)*) -let partition0 idx1 bs0:(byte_sequence*byte_sequence)error= - (takebytes idx1 bs0 >>= (fun l -> - dropbytes idx1 bs0 >>= (fun r -> - return (l, r)))) - -(*val partition_with_length : natural -> natural -> byte_sequence -> error (byte_sequence * byte_sequence)*) -let partition_with_length idx1 bs0_length bs0:(byte_sequence*byte_sequence)error= - (takebytes_with_length idx1 bs0_length bs0 >>= (fun l -> - dropbytes idx1 bs0 >>= (fun r -> - return (l, r)))) - -(** [offset_and_cut off cut bs0] first cuts [off] bytes off [bs0], then cuts - * the resulting byte sequence to length [cut]. Fails if [off] is greater than - * the length of [bs0] and if [cut] is greater than the length of the intermediate - * byte sequence. - *) -(*val offset_and_cut : natural -> natural -> byte_sequence -> error byte_sequence*) -let offset_and_cut off cut bs0:(byte_sequence)error= - (dropbytes off bs0 >>= (fun bs1 -> - takebytes cut bs1 >>= (fun res -> - return res))) - -let instance_Show_Show_Byte_sequence_byte_sequence_dict:(byte_sequence)show_class= ({ - - show_method = string_of_byte_sequence}) - -let instance_Basic_classes_Eq_Byte_sequence_byte_sequence_dict:(byte_sequence)eq_class= ({ - - isEqual_method = equal; - - isInequal_method = (fun l r->not (equal l r))}) diff --git a/lib/ocaml_rts/linksem/byte_sequence_wrapper.ml b/lib/ocaml_rts/linksem/byte_sequence_wrapper.ml deleted file mode 100644 index 69efcc8d..00000000 --- a/lib/ocaml_rts/linksem/byte_sequence_wrapper.ml +++ /dev/null @@ -1,33 +0,0 @@ -open Big_int - -open Error - -let acquire_char_list (fname : string) = - let char_list = ref [] in - try - let ic = open_in_bin fname in - while true do - let c = input_char ic in - let _ = char_list := c :: !char_list in - () - done; - let _ = close_in ic in - Fail "acquire_char_list: the impossible happened" - with End_of_file -> - Success (List.rev !char_list) -;; - -let serialise_char_list (fname : string) bytes = - let rec go oc bytes = - match bytes with - | [] -> () - | x::xs -> output_char oc x; go oc xs - in - try - let oc = open_out_bin fname in - let _ = go oc bytes in - let _ = close_out oc in - Success () - with _ -> - Fail "serialise_char_list: unable to open file for writing" -;;
\ No newline at end of file diff --git a/lib/ocaml_rts/linksem/command_line.ml b/lib/ocaml_rts/linksem/command_line.ml deleted file mode 100644 index 62d4b87e..00000000 --- a/lib/ocaml_rts/linksem/command_line.ml +++ /dev/null @@ -1,671 +0,0 @@ -(*Generated by Lem from command_line.lem.*) -open Lem_basic_classes -open Lem_function -open Lem_string -open Lem_string_extra -open Lem_tuple -open Lem_bool -open Lem_list -open Lem_list_extra -(*import Set*) -(*import Set_extra*) -open Lem_sorting -open Lem_num -open Lem_maybe -open Lem_assert_extra - -open Byte_sequence -open Default_printing -open Error -open Missing_pervasives -open Show - -(* Here we try to model the command line of GNU ld.bfd. - * - * Some options are global modifiers affecting the link output. - * Others have effect only for some subset of input files. - * Typically some mutually-exclusive possibilities exist - * whereby each argument selects one such possibility for all subsequent input files, - * until a different argument selects another possibility for ensuring inputs. - *) - -type input_file_spec = Filename of string (* /path/to/file.{o,a,so,...} -- might be script! *) - | Libname of string (* -llib *) - -(*val string_of_input_file_spec : input_file_spec -> string*) -let string_of_input_file_spec spec:string= - ((match spec with - Filename(s) -> "file `" ^ (s ^ "'") - | Libname(s) -> "library `" ^ (s ^ "'") - )) - -let instance_Show_Show_Command_line_input_file_spec_dict:(input_file_spec)show_class= ({ - - show_method = string_of_input_file_spec}) - -type input_file_options = { input_fmt : string - ; input_libpath : string list - ; input_link_sharedlibs : bool (* -Bstatic *) - ; input_check_sections : bool - ; input_copy_dt_needed : bool - ; input_whole_archive : bool - ; input_as_needed : bool - } - -(*val null_input_file_options : input_file_options*) -let null_input_file_options:input_file_options= - ({ input_fmt = "" - ; input_libpath = ([]) - ; input_link_sharedlibs = false - ; input_check_sections = false - ; input_copy_dt_needed = false - ; input_whole_archive = false - ; input_as_needed = false - }) - -type output_kind = Executable - | SharedLibrary - -type link_option = OutputFilename of string - | OutputKind of output_kind - | ForceCommonDefined of bool (* -d, -dc, -dp *) - | Soname of string (* -soname *) - | EntryAddress of Nat_big_num.num - | TextSegmentStart of Nat_big_num.num - | RodataSegmentStart of Nat_big_num.num - | LdataSegmentStart of Nat_big_num.num - | BindFunctionsEarly (* -Bsymbolic-functions *) - | BindNonFunctionsEarly (* the remainder of -Bsymbolic *) - (* more here! *) - -(*val tagEqual : link_option -> link_option -> bool*) -let tagEqual opt1 opt2:bool= ((match (opt1, opt2) with - (* FIXME: Lem BUG here! says "duplicate binding" *) - (OutputFilename(_), OutputFilename(_)) -> true - | (OutputKind(_), OutputKind(_)) -> true - (* | (ForceCommonDefined, ForceCommonDefined) -> true *) - | (Soname(_), Soname(_)) -> true - (* | (EntryAddress, EntryAddress) -> true *) - | (TextSegmentStart(_), TextSegmentStart(_)) -> true - | (RodataSegmentStart(_), RodataSegmentStart(_)) -> true - | (LdataSegmentStart(_), LdataSegmentStart(_)) -> true - (* | (BindFunctionsEarly, BindFunctionsEarly) -> true *) - (* | (BindNonFunctionsEarly, BindNonFunctionsEarly) -> true *) - | _ -> false -)) - -(* To allow filtering out a previous setting for a given option, we define - * an equality relation that is true if options are of the same constructor. - * Seems like a bit of a HACK. *) -let instance_Basic_classes_Eq_Command_line_link_option_dict:(link_option)eq_class= ({ - - isEqual_method = (fun opt1 -> - (fun opt2 -> - (match (opt1, opt2) with - | (OutputFilename(_), OutputFilename(_)) -> true - | (ForceCommonDefined(_), ForceCommonDefined(_)) -> true - | (Soname(_), Soname(_)) -> true - | (EntryAddress(_), EntryAddress(_)) -> true - | _ -> false - ) - )); - - isInequal_method = (fun opt1 -> (fun opt2 -> not ( ((fun opt1 -> - (fun opt2 -> - (match (opt1, opt2) with - | (OutputFilename(_), OutputFilename(_)) -> true - | (ForceCommonDefined(_), ForceCommonDefined(_)) -> true - | (Soname(_), Soname(_)) -> true - | (EntryAddress(_), EntryAddress(_)) -> true - | _ -> false - ) - ))opt1 opt2))))}) - -type input_file_and_options = input_file_spec * input_file_options -type input_unit = File of input_file_and_options - | Group of (input_file_and_options) list (* NOT recursive *) - | BuiltinControlScript (* for uniformity when processing script defs *) - -(*val string_of_input_unit : input_unit -> string*) -let string_of_input_unit u:string= - ((match u with - File(spec, opts) -> - "single " ^ (string_of_input_file_spec spec) - | Group(spec_opt_list) -> - "group: [" ^ ((string_of_list - instance_Show_Show_Command_line_input_file_spec_dict (Lem_list.map (fun (spec, opts) -> spec) spec_opt_list)) ^ "]") - | BuiltinControlScript -> "(built-in control script)" - )) - -let instance_Show_Show_Command_line_input_unit_dict:(input_unit)show_class= ({ - - show_method = string_of_input_unit}) - -(* Reading the command-line: - * we encode the meaning of a linker command token - * using a reader function interpreting a list of argument definitions. - * Lookahead is necessary: sometimes the interpretation of an option - * depends on the next argument (e.g. whether it's a file, directory or another option). - * The list of argument definitions is from lists of strings to constructor function invocations. - * We use lists of strings since many options have synonyms. - * The strings are interpreted as regular expressions and any matched groups are collected together - * as a second argument list; this is because some arguments are of the form --blah=NUM or similar. *) - -(* As we read the command line, we keep a current state which is the collection - * of seen input files, seen whole-link options, and input file options that will - * apply to any input files we add subsequently. *) -type command_state = { input_units : input_unit list - ; link_options : link_option Pset.set - ; current_input_options : input_file_options - ; current_group : ( input_file_and_options list)option - } - -(* This is the "default state" when we start reading input options *) -(*val initial_state : list command_state*) (* the stack *) -let initial_state0:(command_state)list= ([{ input_units = ([]) - ; link_options =(Pset.from_list compare [OutputFilename("a.out"); OutputKind(Executable)]) - ; current_input_options = ({ input_fmt = "elf64-x86-64" (* FIXME *) - ; input_libpath = (["/usr/lib"]) (* FIXME: this probably isn't the right place to supply the default search path *) - ; input_link_sharedlibs = true - ; input_check_sections = true - ; input_copy_dt_needed = false - ; input_whole_archive = false - ; input_as_needed = true (* FIXME *) - }) - ; current_group = None - }]) - -type interpreted_command_line = input_unit list * link_option Pset.set - -(*val add_input_file : list command_state -> string -> list command_state*) -let add_input_file (state1 :: more) s:(command_state)list= - (let chars = (Xstring.explode s) - in - let spec = ((match chars with - '-' :: 'l' :: more -> Libname(Xstring.implode more) - | '-' :: more -> failwith ("not a valid option or input file: " ^ s) - | _ -> Filename(s) - )) - in - if (Lem.option_equal (listEqualBy (Lem.pair_equal (=) (=))) state1.current_group None) - then - { input_units = (List.rev_append (List.rev state1.input_units) [File(spec, state1.current_input_options)]) - ; link_options = (state1.link_options) - ; current_input_options = (state1.current_input_options) - ; current_group = (state1.current_group) - } :: more - else - { input_units = (state1.input_units) - ; link_options = (state1.link_options) - ; current_input_options = (state1.current_input_options) - ; current_group = (let toAppend = ([(spec, state1.current_input_options)]) in - (match state1.current_group with Some l -> Some( List.rev_append (List.rev l) toAppend) | None -> Some(toAppend) - )) - } :: more) - -(*val start_group : list command_state -> list command_state*) -let start_group (state1 :: more):(command_state)list= ({ - input_units = (state1.input_units) - ; link_options = (state1.link_options) - ; current_input_options = (state1.current_input_options) - ; current_group = ((match state1.current_group with - None -> Some [] - | _ -> failwith "cannot nest groups" - )) - } :: more) - -(*val end_group : list command_state -> list command_state*) -let end_group (state1 :: more):(command_state)list= ({ - input_units = (List.rev_append (List.rev state1.input_units) ((match state1.current_group with - Some l -> [Group(l)] - | None -> failwith "end group without start group" - ))) - ; link_options = (state1.link_options) - ; current_input_options = (state1.current_input_options) - ; current_group = None - } :: more) - -type option_token = string -type option_argspecs = string list * string list -type option_argvals = string list * string list - -(*val set_or_replace_option : link_option -> list command_state -> list command_state*) -let set_or_replace_option opt state_list:(command_state)list= - ((match state_list with - [] -> failwith "error: no state" - | state1 :: more -> - { input_units = (state1.input_units) - ; link_options = (Pset.add opt (Pset.filter (fun existing -> ((fun opt1 -> (fun opt2 -> not ( ((fun opt1 -> - (fun opt2 -> - (match (opt1, opt2) with - | (OutputFilename(_), OutputFilename(_)) -> true - | (ForceCommonDefined(_), ForceCommonDefined(_)) -> true - | (Soname(_), Soname(_)) -> true - | (EntryAddress(_), EntryAddress(_)) -> true - | _ -> false - ) - ))opt1 opt2)))) existing opt)) state1.link_options)) - ; current_input_options = (state1.current_input_options) - ; current_group = (state1.current_group) - } :: more - )) - -(*val find_option_matching_tag : link_option -> set link_option -> maybe link_option*) -let rec find_option_matching_tag tag options:(link_option)option= - (Lem_list.list_find_opt (tagEqual tag) (Pset.elements options)) - -(*val extract_hex_addend : char -> maybe natural*) -let extract_hex_addend x:(Nat_big_num.num)option= - (if x = '0' then - Some(Nat_big_num.of_int 0) - else if x = '1' then - Some(Nat_big_num.of_int 1) - else if x = '2' then - Some(Nat_big_num.of_int 2) - else if x = '3' then - Some(Nat_big_num.of_int 3) - else if x = '4' then - Some(Nat_big_num.of_int 4) - else if x = '5' then - Some(Nat_big_num.of_int 5) - else if x = '6' then - Some(Nat_big_num.of_int 6) - else if x = '7' then - Some(Nat_big_num.of_int 7) - else if x = '8' then - Some(Nat_big_num.of_int 8) - else if x = '9' then - Some(Nat_big_num.of_int 9) - else if x = 'a' then - Some(Nat_big_num.of_int 10) - else if x = 'b' then - Some(Nat_big_num.of_int 11) - else if x = 'c' then - Some(Nat_big_num.of_int 12) - else if x = 'd' then - Some(Nat_big_num.of_int 13) - else if x = 'e' then - Some(Nat_big_num.of_int 14) - else if x = 'f' then - Some(Nat_big_num.of_int 15) - else - None) - -(*val accumulate_hex_chars : natural -> list char -> natural*) -let rec accumulate_hex_chars acc chars:Nat_big_num.num= - ((match chars with - | [] -> acc - | x::xs -> - (match extract_hex_addend x with - | None -> acc - | Some addend -> - accumulate_hex_chars ( Nat_big_num.add (Nat_big_num.mul acc(Nat_big_num.of_int 16)) addend) xs - ) - )) - -(*val extract_dec_addend : char -> maybe natural*) -let extract_dec_addend x:(Nat_big_num.num)option= - (if x = '0' then - Some(Nat_big_num.of_int 0) - else if x = '1' then - Some(Nat_big_num.of_int 1) - else if x = '2' then - Some(Nat_big_num.of_int 2) - else if x = '3' then - Some(Nat_big_num.of_int 3) - else if x = '4' then - Some(Nat_big_num.of_int 4) - else if x = '5' then - Some(Nat_big_num.of_int 5) - else if x = '6' then - Some(Nat_big_num.of_int 6) - else if x = '7' then - Some(Nat_big_num.of_int 7) - else if x = '8' then - Some(Nat_big_num.of_int 8) - else if x = '9' then - Some(Nat_big_num.of_int 9) - else - None) - -(*val accumulate_dec_chars : natural -> list char -> natural*) -let rec accumulate_dec_chars acc chars:Nat_big_num.num= - ((match chars with - | [] -> acc - | x::xs -> - (match extract_dec_addend x with - | None -> acc - | Some addend -> - accumulate_hex_chars ( Nat_big_num.add (Nat_big_num.mul acc(Nat_big_num.of_int 16)) addend) xs - ) - )) - -(*val parse_address : string -> natural*) -let parse_address s:Nat_big_num.num= ((match Xstring.explode s with - '0' :: 'x' :: more -> accumulate_hex_chars(Nat_big_num.of_int 0) more - | chars -> accumulate_dec_chars(Nat_big_num.of_int 0) chars -)) - -type option_def = ( option_token list) * option_argspecs * (option_argvals -> command_state list -> command_state list) * string - -(* the table is a list of: ... options and their arg names ... and the option's meaning as a function... and a help string *) -(*val command_line_table : list option_def*) -let command_line_table:((string)list*((string)list*(string)list)*((string)list*(string)list ->(command_state)list ->(command_state)list)*string)list= ([ - (* per-input options *) - (["-b"; "--format"], (["TARGET"], []), (fun args -> (fun state1 -> state1)), "Specify target for following input files"); - (["-L"; "--library-path"], (["DIRECTORY"], []), (fun args -> (fun state1 -> state1)), "Add DIRECTORY to library search path"); - (["--as-needed"], ([], []), (fun _ -> (fun state1 -> state1)), "Only set DT_NEEDED for following dynamic libs if used"); - (["--no-as-needed"], ([], []), (fun _ -> (fun state1 -> state1)), "Always set DT_NEEDED for dynamic libraries mentioned on the command line"); - (["-Bdynamic"; "-dy"; "-call_shared"], ([], []), (fun _ -> (fun state1 -> state1)), "Link against shared libraries"); - (["-Bstatic"; "-dn"; "-non_shared"; "-static"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not link against shared libraries"); - (["--check-sections"], ([], []), (fun _ -> (fun state1 -> state1)), "Check section addresses for overlaps (default) **srk** not sure it's per-input!"); - (["--no-check-sections"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not check section addresses for overlaps **srk** not sure it's per-input!"); - (["--copy-dt-needed-entries"], ([], []), (fun _ -> (fun state1 -> state1)), "Copy DT_NEEDED links mentioned inside DSOs that follow"); - (["--no-copy-dt-needed-entries"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not copy DT_NEEDED links mentioned inside DSOs that follow"); - (["--no-whole-archive"], ([], []), (fun _ -> (fun state1 -> state1)), "Turn off --whole-archive"); - (["-rpath-link"], (["PATH"], []), (fun _ -> (fun state1 -> state1)), "Set link time shared library search path **srk** not sure it's per-input!"); - (["--whole-archive"], ([], []), (fun _ -> (fun state1 -> state1)), "Include all objects from following archives"); - (* linker plugin control *) - (["-plugin"], (["PLUGIN"], []), (fun _ -> (fun state1 -> state1)), "Load named plugin"); - (["-plugin-opt"], (["ARG"], []), (fun _ -> (fun state1 -> state1)), "Send arg to last-loaded plugin"); - (* output / whole-job options (some may be repeated with different args, but most not): *) - (["-A"; "--architecture"], (["ARCH"], []), (fun _ -> (fun state1 -> state1)), "Set architecture"); - (["-EB"], ([], []), (fun _ -> (fun state1 -> state1)), "Link big-endian objects"); - (["-EL"], ([], []), (fun _ -> (fun state1 -> state1)), "Link little-endian objects"); - (["-R"; "--just-symbols"], (["DIR"], []), (fun _ -> (fun state1 -> state1)), "**srk** (if directory, same as --rpath)"); - (["-d"; "-dc"; "-dp"], ([], []), (fun _ -> (fun state1 -> state1)), "Force common symbols to be defined"); - (["-e"; "--entry"], (["ADDRESS"], []), (fun _ -> (fun state1 -> state1)), "Set start address"); - (["-E"; "--export-dynamic"], ([], []), (fun _ -> (fun state1 -> state1)), "Export all dynamic symbols"); - (["--no-export-dynamic"], ([], []), (fun _ -> (fun state1 -> state1)), "Undo the effect of --export-dynamic"); - (["-f"; "--auxiliary"], (["SHLIB"], []), (fun _ -> (fun state1 -> state1)), "Auxiliary filter for shared object symbol table"); - (["-F"; "--filter"], (["SHLIB"], []), (fun _ -> (fun state1 -> state1)), "Filter for shared object symbol table"); - (["-G"; "--gpsize"], (["SIZE"], []), (fun _ -> (fun state1 -> state1)), "Small data size (if no size, same as --shared) **srk NOTE this quirk!**"); - (["-h"; "-soname"], (["FILENAME"], []), (fun _ -> (fun state1 -> state1)), "Set internal name of shared library"); - (["-I"; "--dynamic-linker"], (["PROGRAM"], []), (fun _ -> (fun state1 -> state1)), "Set PROGRAM as the dynamic linker to use"); - (["--sysroot="], ([], ["DIRECTORY"]), (fun _ -> (fun state1 -> state1)), "Override the default sysroot location"); - (["-m"], (["EMULATION"], []), (fun _ -> (fun state1 -> state1)), "Set emulation"); - (["-n"; "--nmagic"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not page align data"); - (["-N"; "--omagic"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not page align data, do not make text readonly"); - (["--no-omagic"], ([], []), (fun _ -> (fun state1 -> state1)), "Page align data, make text readonly"); - (["-o"; "--output"], (["FILE"], []), (fun argvals -> set_or_replace_option (OutputFilename(List.hd (fst argvals)))), "Set output file name"); - (["-O"], ([], []), (fun _ -> (fun state1 -> state1)), "Optimise output file"); - (["-q"; "--emit-relocs"], ([], []), (fun _ -> (fun state1 -> state1)), "Generate relocations in final output"); - (["-r"; "-i"; "--relocatable"], ([], []), (fun _ -> (fun state1 -> state1)), "Generate relocatable output"); - (["-s"; "--strip-all"], ([], []), (fun _ -> (fun state1 -> state1)), "Strip all symbols"); - (["-S"; "--strip-debug"], ([], []), (fun _ -> (fun state1 -> state1)), "Strip debugging symbols"); - (["--strip-discarded"], ([], []), (fun _ -> (fun state1 -> state1)), "Strip symbols in discarded sections"); - (["--no-strip-discarded"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not strip symbols in discarded sections"); - (["--default-script"; "-dT"], (["FILE"], []), (fun _ -> (fun state1 -> state1)), "Read default linker script"); - (["--unique="], ([], ["SECTION"]), (fun _ -> (fun state1 -> state1)), "Don't merge input [SECTION | orphan] sections"); - (["-Ur"], ([], []), (fun _ -> (fun state1 -> state1)), "Build global constructor/destructor tables ( **srk**: like -r, but... )"); - (["-x"; "--discard-all"], ([], []), (fun _ -> (fun state1 -> state1)), "Discard all local symbols"); - (["-X"; "--discard-locals"], ([], []), (fun _ -> (fun state1 -> state1)), "Discard temporary local symbols (default)"); - (["--discard-none"], ([], []), (fun _ -> (fun state1 -> state1)), "Don't discard any local symbols"); - (["-Bsymbolic"], ([], []), (fun argvals -> (fun state1 -> set_or_replace_option BindFunctionsEarly (set_or_replace_option BindNonFunctionsEarly state1))), "Bind global references locally"); - (["-Bsymbolic-functions"], ([], []), (fun argvals -> set_or_replace_option (BindFunctionsEarly)), "Bind global function references locally"); - (["--force-exe-suffix"], ([], []), (fun _ -> (fun state1 -> state1)), "Force generation of file with .exe suffix"); - (["--gc-sections"], ([], []), (fun _ -> (fun state1 -> state1)), "**srk: uncertain: can repeat?** Remove unused sections (on some targets)"); - (["--no-gc-sections"], ([], []), (fun _ -> (fun state1 -> state1)), "**srk: uncertain: can repeat?** Don't remove unused sections (default)"); - (["--hash-size="], ([], ["NUMBER"]), (fun _ -> (fun state1 -> state1)), "Set default hash table size close to <NUMBER>"); - (["--no-define-common"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not define Common storage"); - (["--no-undefined"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not allow unresolved references in object files"); - (["--allow-shlib-undefined"], ([], []), (fun _ -> (fun state1 -> state1)), "Allow unresolved references in shared libraries"); - (["--no-allow-shlib-undefined"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not allow unresolved references in shared libs"); - (["--default-symver"], ([], []), (fun _ -> (fun state1 -> state1)), "Create default symbol version"); - (["--default-imported-symver"], ([], []), (fun _ -> (fun state1 -> state1)), "Create default symbol version for imported symbols"); - (["-nostdlib"], ([], []), (fun _ -> (fun state1 -> state1)), "Only use library directories specified on the command line"); - (["--oformat"], (["TARGET"], []), (fun _ -> (fun state1 -> state1)), "Specify target of output file"); - (["--relax"], ([], []), (fun _ -> (fun state1 -> state1)), "Reduce code size by using target specific optimisations"); - (["--no-relax"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not use relaxation techniques to reduce code size"); - (["--retain-symbols-file"], (["FILE"], []), (fun _ -> (fun state1 -> state1)), "Keep only symbols listed in FILE"); - (["-rpath"], (["PATH"], []), (fun _ -> (fun state1 -> state1)), "Set runtime shared library search path"); - (["-shared"; "-Bshareable"], ([], []), (fun argvals -> set_or_replace_option (OutputKind(SharedLibrary))), "Create a shared library"); - (["-pie"; "--pic-executable"], ([], []), (fun _ -> (fun state1 -> state1)), "Create a position independent executable"); - (["--sort-common="],(* (ascending|descending) *)([], ["order"]), (fun _ -> (fun state1 -> state1)), "Sort common symbols by alignment [in specified order]"); - (["--sort-section="],(* (name|alignment) *) ([], ["key"]), (fun _ -> (fun state1 -> state1)), "Sort sections by name or maximum alignment"); - (["--spare-dynamic-tags"], (["COUNT"], []), (fun _ -> (fun state1 -> state1)), "How many tags to reserve in .dynamic section"); - (["--split-by-file="], ([], ["SIZE"]), (fun _ -> (fun state1 -> state1)), "Split output sections every SIZE octets"); - (["--split-by-reloc="], ([], ["COUNT"]), (fun _ -> (fun state1 -> state1)), "Split output sections every COUNT relocs"); - (["--traditional-format"], ([], []), (fun _ -> (fun state1 -> state1)), "Use same format as native linker"); - (["--unresolved-symbols="], ([], ["method"]), (fun _ -> (fun state1 -> state1)), "How to handle unresolved symbols. <method> is: ignore-all, report-all, ignore-in-object-files, ignore-in-shared-libs"); - (["--dynamic-list-data"], ([], []), (fun _ -> (fun state1 -> state1)), "Add data symbols to dynamic list"); - (["--dynamic-list-cpp-new"], ([], []), (fun _ -> (fun state1 -> state1)), "Use C++ operator new/delete dynamic list"); - (["--dynamic-list-cpp-typeinfo "], ([], []), (fun _ -> (fun state1 -> state1)), "Use C++ typeinfo dynamic list"); - (["--dynamic-list"], (["FILE"], []), (fun _ -> (fun state1 -> state1)), "Read dynamic list"); - (["--wrap"], (["SYMBOL"], []), (fun _ -> (fun state1 -> state1)), "Use wrapper functions for SYMBOL"); - (* the following are specific to ELF emulations *) - (["--audit=(.*)"], ([], ["AUDITLIB"]), (fun _ -> (fun state1 -> state1)), "Specify a library to use for auditing"); - (["-Bgroup"], ([], []), (fun _ -> (fun state1 -> state1)), "Selects group name lookup rules for DSO"); - (["--build-id="], ([], ["STYLE"]), (fun _ -> (fun state1 -> state1)), "Generate build ID note"); - (["-P"], (["AUDITLIB"], []), (fun _ -> (fun state1 -> state1)), "Specify a library to use for auditing dependencies"); - (["--depaudit="], ([], ["AUDITLIB"]), (fun _ -> (fun state1 -> state1)), "Specify a library to use for auditing dependencies"); - (["--disable-new-dtags"], ([], []), (fun _ -> (fun state1 -> state1)), "Disable new dynamic tags"); - (["--enable-new-dtags"], ([], []), (fun _ -> (fun state1 -> state1)), "Enable new dynamic tags"); - (["--eh-frame-hdr"], ([], []), (fun _ -> (fun state1 -> state1)), "Create .eh_frame_hdr section"); - (["--exclude-libs="], ([], ["LIBS"]), (fun _ -> (fun state1 -> state1)), "Make all symbols in LIBS hidden"); - (["--hash-style="], ([], ["STYLE"]), (fun _ -> (fun state1 -> state1)), "Set hash style to sysv, gnu or both"); - (* NOTE: for these to work, we hack our word-splitter to merge -z options into a single word with a single space in *) - (["-z combreloc"], ([], []), (fun _ -> (fun state1 -> state1)), "Merge dynamic relocs into one section and sort"); - (["-z common-page-size="], ([], ["SIZE"]), (fun _ -> (fun state1 -> state1)), "Set common page size to SIZE"); - (["-z defs"], ([], []), (fun _ -> (fun state1 -> state1)), "Report unresolved symbols in object files."); - (["-z execstack"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark executable as requiring executable stack"); - (["-z global"], ([], []), (fun _ -> (fun state1 -> state1)), "Make symbols in DSO available for subsequently loaded objects"); - (["-z initfirst"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark DSO to be initialized first at runtime"); - (["-z interpose"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark object to interpose all DSOs but executable"); - (["-z lazy"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark object lazy runtime binding (default)"); - (["-z loadfltr"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark object requiring immediate process"); - (["-z max-page-size="], ([], ["SIZE"]), (fun _ -> (fun state1 -> state1)), "Set maximum page size to SIZE"); - (["-z nocombreloc"], ([], []), (fun _ -> (fun state1 -> state1)), "Don't merge dynamic relocs into one section"); - (["-z nocopyreloc"], ([], []), (fun _ -> (fun state1 -> state1)), "Don't create copy relocs"); - (["-z nodefaultlib"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark object not to use default search paths"); - (["-z nodelete"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark DSO non-deletable at runtime"); - (["-z nodlopen"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark DSO not available to dlopen"); - (["-z nodump"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark DSO not available to dldump"); - (["-z noexecstack"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark executable as not requiring executable stack"); - (["-z norelro"], ([], []), (fun _ -> (fun state1 -> state1)), "Don't create RELRO program header"); - (["-z now"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark object non-lazy runtime binding"); - (["-z origin"], ([], []), (fun _ -> (fun state1 -> state1)), "Mark object requiring immediate $ORIGIN processing at runtime"); - (["-z relro"], ([], []), (fun _ -> (fun state1 -> state1)), "Create RELRO program header"); - (["-z stacksize="], ([], ["SIZE"]), (fun _ -> (fun state1 -> state1)), "Set size of stack segment"); - (["-z bndplt"], ([], []), (fun _ -> (fun state1 -> state1)), "Always generate BND prefix in PLT entries"); - (["--ld-generated-unwind-info"], ([], []), (fun _ -> (fun state1 -> state1)), "Generate exception handling info for PLT."); - (["--no-ld-generated-unwind-info"], ([], []), (fun _ -> (fun state1 -> state1)), "Don't do so."); - (* quasi-input options (can be repeated): *) - (["-c"; "--mri-script"], (["FILE"], []), (fun _ -> (fun state1 -> state1)), "Read MRI format linker script"); - (["-l"; "--library"], (["LIBNAME"], []), (fun _ -> (fun state1 -> state1)), "Search for library LIBNAME"); - (* (["-R" ,"--just-symbols"], (["FILE"], []), fun _ -> (fun state -> state), "Just link symbols"), *) (* Handled above! *) - (["-T"; "--script"], (["FILE"], []), (fun _ -> (fun state1 -> state1)), "Read linker script"); - (["-u"; "--undefined"], (["SYMBOL"], []), (fun _ -> (fun state1 -> state1)), "Start with undefined reference to SYMBOL"); - (["-("; "--start-group"], ([], []), (fun _ -> (fun state1 -> start_group state1)), "Start a group"); - (["-)"; "--end-group"], ([], []), (fun _ -> (fun state1 -> end_group state1)), "End a group"); - (["--defsym"], (["SYMBOL=EXPRESSION"], []), (fun _ -> (fun state1 -> state1)), "Define a symbol"); - (["-fini"], (["SYMBOL"], []), (fun _ -> (fun state1 -> state1)), "Call SYMBOL at unload-time"); - (["-init"], (["SYMBOL"], []), (fun _ -> (fun state1 -> state1)), "Call SYMBOL at load-time"); - (["--section-start"], (["SECTION=ADDRESS"], []), (fun _ -> (fun state1 -> state1)), "Set address of named section"); - (["-Tbss"], (["ADDRESS"], []), (fun _ -> (fun state1 -> state1)), "Set address of .bss section"); - (["-Tdata"], (["ADDRESS"], []), (fun _ -> (fun state1 -> state1)), "Set address of .data section"); - (["-Ttext"], (["ADDRESS"], []), (fun _ -> (fun state1 -> state1)), "Set address of .text section"); - (["-Ttext-segment"], (["ADDRESS"], []), (fun argvals -> set_or_replace_option (TextSegmentStart(parse_address (List.hd (fst argvals))))), "Set address of text segment"); - (["-Trodata-segment"], (["ADDRESS"], []), (fun argvals -> set_or_replace_option (RodataSegmentStart(parse_address (List.hd (fst argvals))))), "Set address of rodata segment"); - (["-Tldata-segment"], (["ADDRESS"], []), (fun argvals -> set_or_replace_option (LdataSegmentStart(parse_address (List.hd (fst argvals))))), "Set address of ldata segment"); - (["--version-script"], (["FILE"], []), (fun _ -> (fun state1 -> state1)), "Read version information script"); - (["--version-exports-section"], (["SYMBOL"], []), (fun _ -> (fun state1 -> state1)), "Take export symbols list from .exports, using SYMBOL as the version."); - (* linker internal debugging/diagnostics and performance tuning *) - (["-M"; "--print-map"], ([], []), (fun _ -> (fun state1 -> state1)), "Print map file on standard output"); - (["-t"; "--trace"], ([], []), (fun _ -> (fun state1 -> state1)), "Trace file opens"); - (["-v"; "--version"], ([], []), (fun _ -> (fun state1 -> state1)), "Print version information"); - (["-V"], ([], []), (fun _ -> (fun state1 -> state1)), "Print version and emulation information"); - (["-y"; "--trace-symbol"], (["SYMBOL"], []), (fun _ -> (fun state1 -> state1)), "Trace mentions of SYMBOL"); - (["--cref"], ([], []), (fun _ -> (fun state1 -> state1)), "Output cross reference table"); - (["--demangle="], ([], ["STYLE"]), (fun _ -> (fun state1 -> state1)), "Demangle symbol names [using STYLE]"); - (["--print-gc-sections"], ([], []), (fun _ -> (fun state1 -> state1)), "List removed unused sections on stderr"); - (["--no-print-gc-sections"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not list removed unused sections"); - (["-Map"], (["FILE"], []), (fun _ -> (fun state1 -> state1)), "Write a map file"); - (["-Map="], ([], ["FILE"]), (fun _ -> (fun state1 -> state1)), "Write a map file"); - (["--help"], ([], []), (fun _ -> (fun state1 -> state1)), "Print option help"); - (["--no-keep-memory"], ([], []), (fun _ -> (fun state1 -> state1)), "Use less memory and more disk I/O"); - (["--no-demangle"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not demangle symbol names"); - (["--print-output-format"], ([], []), (fun _ -> (fun state1 -> state1)), "Print default output format"); - (["--print-sysroot"], ([], []), (fun _ -> (fun state1 -> state1)), "Print current sysroot"); - (["--reduce-memory-overheads"], ([], []), (fun _ -> (fun state1 -> state1)), "Reduce memory overheads, possibly taking much longer"); - (["--stats"], ([], []), (fun _ -> (fun state1 -> state1)), "Print memory usage statistics"); - (["--target-help"], ([], []), (fun _ -> (fun state1 -> state1)), "Display target specific options"); - (["--verbose="], ([], ["NUMBER"]), (fun _ -> (fun state1 -> state1)), "Output lots of information during link"); - (* unknown *) - (["--embedded-relocs"], ([], []), (fun _ -> (fun state1 -> state1)), "Generate embedded relocs"); - (["--task-link"], (["SYMBOL"], []), (fun _ -> (fun state1 -> state1)), "Do task level linking"); - (* compatibility *) - (["-a"], (["KEYWORD"], []), (fun _ -> (fun state1 -> state1)), "Shared library control for HP/UX compatibility"); - (["-Y"], (["PATH"], []), (fun _ -> (fun state1 -> state1)), "Default search path for Solaris compatibility"); - (* permissiveness controls (tightening/loosening) *) - (["--accept-unknown-input-arch"], ([], []), (fun _ -> (fun state1 -> state1)), "Accept input files whose architecture cannot be determined"); - (["--no-accept-unknown-input-arch"], ([], []), (fun _ -> (fun state1 -> state1)), "Reject input files whose architecture is unknown"); - (["--fatal-warnings"], ([], []), (fun _ -> (fun state1 -> state1)), "Treat warnings as errors"); - (["--no-fatal-warnings"], ([], []), (fun _ -> (fun state1 -> state1)), "Do not treat warnings as errors (default)"); - (["--allow-multiple-definition"], ([], []), (fun _ -> (fun state1 -> state1)), "Allow multiple definitions"); - (["--no-undefined-version"], ([], []), (fun _ -> (fun state1 -> state1)), "Disallow undefined version"); - (["--noinhibit-exec"], ([], []), (fun _ -> (fun state1 -> state1)), "Create an output file even if errors occur"); - (["--error-unresolved-symbols"], ([], []), (fun _ -> (fun state1 -> state1)), "Report unresolved symbols as errors"); - (["--ignore-unresolved-symbol"], (["SYMBOL"], []), (fun _ -> (fun state1 -> state1)), "Unresolved SYMBOL will not cause an error or warning"); - (* permissiveness, specific to ELF emulation *) - (["-z muldefs"], ([], []), (fun _ -> (fun state1 -> state1)), "Allow multiple definitions"); - (* warnings (enabling/disabling) *) - (["--no-warn-mismatch"], ([], []), (fun _ -> (fun state1 -> state1)), "Don't warn about mismatched input files"); - (["--no-warn-search-mismatch"], ([], []), (fun _ -> (fun state1 -> state1)), "Don't warn on finding an incompatible library"); - (["--warn-common"], ([], []), (fun _ -> (fun state1 -> state1)), "Warn about duplicate common symbols"); - (["--warn-constructors"], ([], []), (fun _ -> (fun state1 -> state1)), "Warn if global constructors/destructors are seen"); - (["--warn-multiple-gp"], ([], []), (fun _ -> (fun state1 -> state1)), "Warn if the multiple GP values are used"); - (["--warn-once"], ([], []), (fun _ -> (fun state1 -> state1)), "Warn only once per undefined symbol"); - (["--warn-section-align"], ([], []), (fun _ -> (fun state1 -> state1)), "Warn if start of section changes due to alignment"); - (["--warn-shared-textrel"], ([], []), (fun _ -> (fun state1 -> state1)), "Warn if shared object has DT_TEXTREL"); - (["--warn-alternate-em"], ([], []), (fun _ -> (fun state1 -> state1)), "Warn if an object has alternate ELF machine code"); - (["--warn-unresolved-symbols"], ([], []), (fun _ -> (fun state1 -> state1)), "Report unresolved symbols as warnings"); - (* meta-options *) - (["--push-state"], ([], []), (fun _ -> (fun state1 -> state1)), "Push state of flags governing input file handling"); - (["--pop-state"], ([], []), (fun _ -> (fun state1 -> state1)), "Pop state of flags governing input file handling") -(*(["@FILE"], [], fun _ -> (fun state -> state), "Read options from FILE") *) (* processed during word-splitting phase *); -]) - -(*val delete_trailing_equals: string -> maybe string*) -let delete_trailing_equals str:(string)option= - (let cs = (Xstring.explode str) - in - if (listEqualBy (=) ['='] (drop0 ( Nat_big_num.sub_nat(length cs)(Nat_big_num.of_int 1)) cs)) - then Some (Xstring.implode ((take0 ( Nat_big_num.sub_nat(length cs)(Nat_big_num.of_int 1)) cs))) - else (* let _ = Missing_pervasives.errln ("No trailing equals: " ^ str) - in *) - None) - -(*val string_following_equals_at : nat -> string -> maybe string*) -let string_following_equals_at pos str:(string)option= - (let (first, second) = (Lem_list.split_at pos (Xstring.explode str)) - in (match second with - '=' :: rest -> Some (Xstring.implode rest) - | _ -> (* let _ = Missing_pervasives.errln ("No trailing equals at " ^ (show pos) ^ ": " ^ str) - in *) - None - )) - -(*val equal_modulo_trailing_equals : string -> string -> bool*) -let equal_modulo_trailing_equals argstr argdef:bool= -( - (* we allow argdef to have a trailing equals; if it does, - * we allow the argstring to have the equals (or not) and trailing stuff, - * which will become an arg *)let result = ((match (delete_trailing_equals argdef) with - Some matched -> - let following_equals = (string_following_equals_at (String.length matched) argstr) - in - (match following_equals with - Some following -> (* okay; does the pre-equals part match? *) - matched = Xstring.implode (Lem_list.take ( Nat_num.nat_monus(String.length argdef)( 1)) (Xstring.explode argstr)) - | _ -> (* the argstr is allowed not to have a trailing equals *) argstr = matched - ) - | None -> (* no trailing equals *) argdef = argstr - )) - in - (* let _ = Missing_pervasives.errln ("Do '" ^ argstr ^ "' and '" ^ argdef ^ "' match modulo trailing equals? " ^ (show result)) - in *) result) - - -(*val matching_arg_and_alias : string -> list option_def -> maybe (string * option_def)*) -let rec matching_arg_and_alias arg options:(string*((string)list*((string)list*(string)list)*(option_argvals ->(command_state)list ->(command_state)list)*string))option= ((match options with - [] -> None - | (aliases, argspec, meaning, doc) :: more_opts -> - (match list_find_opt (fun alias -> equal_modulo_trailing_equals arg alias) aliases with - Some found_alias -> Some (found_alias, (aliases, argspec, meaning, doc)) - | None -> matching_arg_and_alias arg more_opts - ) - )) - -(* We don't try to convert from strings to other things here; - * everything we record is either a bool, meaning option -A was "present", for some A, - * or a string somearg, meaning option -A somearg was present, for some A. *) - -(* The above suffices to understand each concrete argument. - * Now we define an "interpreted command line" that includes - * some useful structure. *) - -(*val read_one_arg : list command_state -> list string -> (list command_state * list string)*) -let read_one_arg state_stack args:(command_state)list*(string)list= -( - (* Get the first string and look it up in our table. *)(match args with - [] -> (state_stack, []) - | some_arg :: more -> (match (matching_arg_and_alias some_arg command_line_table) with - (* We need to handle argdefs that have trailing equals. This means - * an extra arg might follow the equals. We need some helper functions. *) - Some (alias, (aliases, (argspec_extras, argspec_regex), meaning, doc)) -> - (* Return a new state, by applying the argument's meaning. - * We have to supply the option's argument strings to the meaning function. *) - let argstrings = (Lem_list.take (List.length argspec_extras) more) - in - let regex_matches = ((match delete_trailing_equals some_arg with - Some prefix -> - (match (string_following_equals_at ( Nat_num.nat_monus(String.length alias)( 1)) some_arg) with - Some following_equals -> [following_equals] - | None -> failwith "impossible: '=' not where it was a moment ago" - ) - | None -> [] - )) - in - let new_state_stack = (meaning (argstrings, regex_matches) state_stack) - in - (new_state_stack, drop0 (length argspec_extras) more) - | None -> - (* If we didn't match any args, we ought to be an input file. *) - (add_input_file state_stack some_arg, more) - ) - )) - -(* To fold over the command-line arguments we need a fold that passes - * suffixes of the list, not individual elements, and gives us back - * the continuation that we need to fold over: a pair of folded-value, new-list. *) -(*val foldl_suffix : forall 'a 'b. ('a -> list 'b -> ('a * list 'b)) -> 'a -> list 'b -> 'a*) (* originally foldl *) -let rec foldl_suffix f a l:'a= ((match l with - | [] -> a - | x :: xs -> - let (new_a, new_list) = (f a l) - in foldl_suffix f new_a new_list -)) - -(* the word-splitting in argv needs a little fixing up. *) -(*val cook_argv : list string -> list string -> list string*) -let rec cook_argv acc args:(string)list= - ((match args with - [] -> acc - | "-z" :: more -> (match more with - [] -> failwith "-z must be followed by another argument" - | something :: yetmore -> cook_argv ( List.rev_append (List.rev acc) [("-z " ^ something)]) yetmore - ) - | something :: more -> cook_argv ( List.rev_append (List.rev acc) [something]) more - )) - -(*val command_line : unit -> interpreted_command_line*) -let command_line:unit ->(input_unit)list*(link_option)Pset.set= (fun _ -> ( - let cooked_argv = (cook_argv [] (List.tl Ml_bindings.argv_list)) - in - (* Now we use our fold-alike. *) - (match foldl_suffix read_one_arg initial_state0 cooked_argv with - state1 :: rest_of_stack -> (state1.input_units, state1.link_options) - | _ -> failwith "no command state left" - ) -)) diff --git a/lib/ocaml_rts/linksem/default_printing.ml b/lib/ocaml_rts/linksem/default_printing.ml deleted file mode 100644 index 4bce7684..00000000 --- a/lib/ocaml_rts/linksem/default_printing.ml +++ /dev/null @@ -1,28 +0,0 @@ -(*Generated by Lem from default_printing.lem.*) -(** [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 Lem_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:'a ->string= - ((fun y->"*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:'a ->string= - ((fun y->"*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:'a ->string= - ((fun y->"*Default user specific print*")) diff --git a/lib/ocaml_rts/linksem/dwarf.ml b/lib/ocaml_rts/linksem/dwarf.ml deleted file mode 100644 index 9e5a31aa..00000000 --- a/lib/ocaml_rts/linksem/dwarf.ml +++ /dev/null @@ -1,4619 +0,0 @@ -(*Generated by Lem from dwarf.lem.*) -open Lem_basic_classes -open Lem_bool -open Lem_function -open Lem_maybe -open Lem_num -open Lem_string - -open Lem_list (* TODO: check why this is not imported in ELF *) - -open Byte_sequence -open Error -open Hex_printing -open Missing_pervasives -open Show - -open Default_printing - -open Endianness -open String_table - -open Elf_dynamic -open Elf_file -open Elf_header -open Elf_program_header_table -open Elf_relocation -open Elf_section_header_table -open Elf_symbol_table -open Elf_types_native_uint - - -(** ***************** experimental DWARF reading *********** *) - -(* - -This defines a representation of some of the DWARF debug information, -with parsing functions to extract it from the byte sequences of the -relevant ELF sections, and pretty-printing function to dump it in a -human-readable form, similar to that of readelf. The main functions -for this are: - - val extract_dwarf : elf64_file -> maybe dwarf - val pp_dwarf : dwarf -> string - -It also defines evaluation of DWARF expressions and analysis functions -to convert the variable location information to a form suitable for -looking up variable names from machine addresses that arise during -execution, including the call frame address calculation. The main -types and functions for this are: - - type analysed_location_data - val analyse_locations : dwarf -> analysed_location_data - - type evaluated_frame_info - val evaluate_frame_info : dwarf -> evaluated_frame_info - - type dwarf_static - val extract_dwarf_static : elf64_file -> maybe dwarf_static - -The last collects all the above - information that can be computed statically. - -Then to do lookup from addresses to source-code names, we have: - - type analysed_location_data_at_pc - val analysed_locations_at_pc : evaluation_context -> dwarf_static -> natural -> analysed_location_data_at_pc - val names_of_address : dwarf -> analysed_location_data_at_pc -> natural -> list string - -The definitions are deliberately simple-minded, to be quick to write, -easy to see the correspondence to the DWARF text specification, and -potentially support generation of theorem-prover definitions in -future. They are in a pure functional style, making the information -dependencies explicit. They are not written for performance, though -they may be efficient enough for small examples as-is. They are -written in Lem, and compiled from that to executable OCaml. - -The development follows the DWARF 4 pdf specification at http://www.dwarfstd.org/ -though tweaked in places where our examples use earlier versions. It doesn't -systematically cover all the DWARF versions. -It doesn't cover the GNU extensions -(at https://fedorahosted.org/elfutils/wiki/DwarfExtensions). -The representation, parsing, and pretty printing are mostly complete for the -data in these DWARF ELF sections: - -.debug_abbrev -.debug_info -.debug_types -.debug_loc -.debug_str -.debug_ranges -.debug_frame (without augmentations) -.debug_line - -The following DWARF ELF sections are not covered: - -.debug_aranges -.debug_macinfo -.debug_pubnames -.debug_pubtypes - -The evaluation of DWARF expressions covers only some of the operations -- probably enough for common cases. - -The analysis of DWARF location data should be enough to look up names -from the addresses of variables and formal parameters. It does not -currently handle the DWARF type data, so will not be useful for accesses -strictly within the extent of a variable or parameter. - -The 'dwarf' type gives a lightly parsed representation of some of the -dwarf information, with the byte sequences of the above .debug_* -sections parsed into a structured representation. That makes the list -and tree structures explicit, and converts the various numeric types -into just natural, integer, and byte sequences. The lem natural and -integer could be replaced by unsigned and signed 64-bit types; that'd -probably be better for execution but not for theorem-prover use. - -*) - -(* some spec ambiguities (more in comments in-line below): *) -(* can a location list be referenced from multiple compilation units, with different base addresses? *) - - -(** debug *) - -(* workaround debug.lem linking *) -(*val print_endline : string -> unit*) - -let my_debug s:unit= () (*print_endline s*) -let my_debug2 s:unit= () (*print_endline s*) -let my_debug3 s:unit= () (*print_endline s*) -let my_debug4 s:unit= () (*print_endline s*) -let my_debug5 s:unit= (print_endline s) - - -(** ************************************************************ *) -(** ** dwarf representation types **************************** *) -(** ************************************************************ *) - - -type dwarf_attribute_classes = - | DWA_7_5_3 - | DWA_address - | DWA_block - | DWA_constant - | DWA_dash - | DWA_exprloc - | DWA_flag - | DWA_lineptr - | DWA_loclistptr - | DWA_macptr - | DWA_rangelistptr - | DWA_reference - | DWA_string - -(* operations and expression evalution *) - -type operation_argument_type = - | OAT_addr - | OAT_dwarf_format_t - | OAT_uint8 - | OAT_uint16 - | OAT_uint32 - | OAT_uint64 - | OAT_sint8 - | OAT_sint16 - | OAT_sint32 - | OAT_sint64 - | OAT_ULEB128 - | OAT_SLEB128 - | OAT_block - -type operation_argument_value = - | OAV_natural of Nat_big_num.num - | OAV_integer of Nat_big_num.num - | OAV_block of Nat_big_num.num * char list - -type operation_stack = Nat_big_num.num list - -type arithmetic_context = - { - ac_bitwidth: Nat_big_num.num; - ac_half: Nat_big_num.num; (* 2 ^ (ac_bitwidth -1) *) - ac_all: Nat_big_num.num; (* 2 ^ ac_bitwidth *) - ac_max: Nat_big_num.num; (* (2 ^ ac_bitwidth) -1 *) (* also the representation of -1 *) -} - -type operation_semantics = - | OpSem_lit - | OpSem_deref - | OpSem_stack of (arithmetic_context -> operation_stack -> operation_argument_value list -> operation_stack option) - | OpSem_not_supported - | OpSem_binary of (arithmetic_context -> Nat_big_num.num -> Nat_big_num.num -> Nat_big_num.num option) - | OpSem_unary of (arithmetic_context -> Nat_big_num.num -> Nat_big_num.num option) - | OpSem_opcode_lit of Nat_big_num.num - | OpSem_reg - | OpSem_breg - | OpSem_bregx - | OpSem_fbreg - | OpSem_deref_size - | OpSem_nop - | OpSem_piece - | OpSem_bit_piece - | OpSem_implicit_value - | OpSem_stack_value - | OpSem_call_frame_cfa - -type operation = - { - op_code: Nat_big_num.num; - op_string: string; - op_argument_values: operation_argument_value list; - op_semantics: operation_semantics; - } - - -(* the result of a location expression evaluation is a single_location (or failure) *) - -type simple_location = - | SL_memory_address of Nat_big_num.num - | SL_register of Nat_big_num.num - | SL_implicit of char list (* used for implicit and stack values *) - | SL_empty - -type composite_location_piece = - | CLP_piece of Nat_big_num.num * simple_location - | CLP_bit_piece of Nat_big_num.num * Nat_big_num.num * simple_location - -type single_location = - | SL_simple of simple_location - | SL_composite of composite_location_piece list - -(* location expression evaluation is a stack machine operating over the following state *) - -type state = - { - s_stack: operation_stack; - s_value: simple_location; - s_location_pieces: composite_location_piece list; - } - -(* location expression evaluation can involve register and memory reads, via the following interface *) - -type 'a register_read_result = - | RRR_result of Nat_big_num.num - | RRR_not_currently_available - | RRR_bad_register_number - -type 'a memory_read_result = - | MRR_result of Nat_big_num.num - | MRR_not_currently_available - | MRR_bad_address - -type evaluation_context = - { - read_register: Nat_big_num.num -> Nat_big_num.num register_read_result; - read_memory: Nat_big_num.num -> Nat_big_num.num -> Nat_big_num.num memory_read_result; - } - - -(* dwarf sections *) - -type dwarf_format = - | Dwarf32 - | Dwarf64 - -(* .debug_abbrev section *) - -type abbreviation_declaration = - { - ad_abbreviation_code: Nat_big_num.num; - ad_tag: Nat_big_num.num; - ad_has_children: bool; - ad_attribute_specifications: (Nat_big_num.num * Nat_big_num.num) list; - } - -type abbreviations_table = abbreviation_declaration list - -(* .debug_info section *) - -type attribute_value = - | AV_addr of Nat_big_num.num - | AV_block of Nat_big_num.num * char list - | AV_constantN of Nat_big_num.num * char list - | AV_constant_SLEB128 of Nat_big_num.num - | AV_constant_ULEB128 of Nat_big_num.num - | AV_exprloc of Nat_big_num.num * char list - | AV_flag of bool - | AV_ref of Nat_big_num.num - | AV_ref_addr of Nat_big_num.num (* dwarf_format dependent *) - | AV_ref_sig8 of Nat_big_num.num - | AV_sec_offset of Nat_big_num.num - | AV_string of char list (* not including terminating null *) - | AV_strp of Nat_big_num.num (* dwarf_format dependent *) - -type die = - { - die_offset: Nat_big_num.num; - die_abbreviation_code: Nat_big_num.num; - die_abbreviation_declaration: abbreviation_declaration; - die_attribute_values: (Nat_big_num.num (*pos*) * attribute_value) list; - die_children: die list; - } - -type compilation_unit_header = - { - cuh_offset: Nat_big_num.num; - cuh_dwarf_format: dwarf_format; - cuh_unit_length: Nat_big_num.num; - cuh_version: Nat_big_num.num; - cuh_debug_abbrev_offset: Nat_big_num.num; - cuh_address_size: Nat_big_num.num; - } - -type compilation_unit = - { - cu_header: compilation_unit_header; - cu_abbreviations_table: abbreviations_table; - cu_die: die; - } - -type compilation_units = compilation_unit list - -(* .debug_type section *) - -type type_unit_header = - { - tuh_cuh: compilation_unit_header; - tuh_type_signature: Nat_big_num.num; - tuh_type_offset: Nat_big_num.num; - } - -type type_unit = - { - tu_header: type_unit_header; - tu_abbreviations_table: abbreviations_table; - tu_die: die; - } - -type type_units = type_unit list - -(* .debug_loc section *) - -type single_location_description = char list - -type location_list_entry = - { - lle_beginning_address_offset: Nat_big_num.num; - lle_ending_address_offset: Nat_big_num.num; - lle_single_location_description: single_location_description; - } - -type base_address_selection_entry = - { - base_address: Nat_big_num.num; - } - -type location_list_item = - | LLI_lle of location_list_entry - | LLI_base of base_address_selection_entry - -type location_list = Nat_big_num.num (*offset*) * location_list_item list - -type location_list_list = location_list list - -(* .debug_ranges section *) - -type range_list_entry = - { - rle_beginning_address_offset: Nat_big_num.num; - rle_ending_address_offset: Nat_big_num.num; - } - -type range_list_item = - | RLI_rle of range_list_entry - | RLI_base of base_address_selection_entry - -type range_list = Nat_big_num.num (*offset*) * range_list_item list - -type range_list_list = range_list list - -(* .debug_frame section: call frame instructions *) - -type cfa_address = Nat_big_num.num -type cfa_block = char list -type cfa_delta = Nat_big_num.num -type cfa_offset = Nat_big_num.num -type cfa_register = Nat_big_num.num -type cfa_sfoffset = Nat_big_num.num - -type call_frame_argument_type = - | CFAT_address - | CFAT_delta1 - | CFAT_delta2 - | CFAT_delta4 - | CFAT_delta_ULEB128 - | CFAT_offset (*ULEB128*) - | CFAT_sfoffset (*SLEB128*) - | CFAT_register (*ULEB128*) - | CFAT_block - -type call_frame_argument_value = - | CFAV_address of cfa_address - | CFAV_block of cfa_block - | CFAV_delta of cfa_delta - | CFAV_offset of cfa_offset - | CFAV_register of cfa_register - | CFAV_sfoffset of cfa_sfoffset - -type call_frame_instruction = - | DW_CFA_advance_loc of cfa_delta - | DW_CFA_offset of cfa_register * cfa_offset - | DW_CFA_restore of cfa_register - | DW_CFA_nop - | DW_CFA_set_loc of cfa_address - | DW_CFA_advance_loc1 of cfa_delta - | DW_CFA_advance_loc2 of cfa_delta - | DW_CFA_advance_loc4 of cfa_delta - | DW_CFA_offset_extended of cfa_register * cfa_offset - | DW_CFA_restore_extended of cfa_register - | DW_CFA_undefined of cfa_register - | DW_CFA_same_value of cfa_register - | DW_CFA_register of cfa_register * cfa_register - | DW_CFA_remember_state - | DW_CFA_restore_state - | DW_CFA_def_cfa of cfa_register * cfa_offset - | DW_CFA_def_cfa_register of cfa_register - | DW_CFA_def_cfa_offset of cfa_offset - | DW_CFA_def_cfa_expression of cfa_block - | DW_CFA_expression of cfa_register * cfa_block - | DW_CFA_offset_extended_sf of cfa_register * cfa_sfoffset - | DW_CFA_def_cfa_sf of cfa_register * cfa_sfoffset - | DW_CFA_def_cfa_offset_sf of cfa_sfoffset - | DW_CFA_val_offset of cfa_register * cfa_offset - | DW_CFA_val_offset_sf of cfa_register * cfa_sfoffset - | DW_CFA_val_expression of cfa_register * cfa_block - | DW_CFA_unknown of char - -(* .debug_frame section: top-level *) - -type cie = - { - cie_offset: Nat_big_num.num; - cie_length: Nat_big_num.num; - cie_id: Nat_big_num.num; - cie_version: Nat_big_num.num; - cie_augmentation: char list; (* not including terminating null *) - cie_address_size: Nat_big_num.num option; - cie_segment_size: Nat_big_num.num option; - cie_code_alignment_factor: Nat_big_num.num; - cie_data_alignment_factor: Nat_big_num.num; - cie_return_address_register: cfa_register; - cie_initial_instructions_bytes: char list; - cie_initial_instructions: call_frame_instruction list; - } - -type fde = - { - fde_offset: Nat_big_num.num; - fde_length: Nat_big_num.num; - fde_cie_pointer: Nat_big_num.num; - fde_initial_location_segment_selector: Nat_big_num.num option; - fde_initial_location_address: Nat_big_num.num; - fde_address_range: Nat_big_num.num; - fde_instructions_bytes: char list; - fde_instructions: call_frame_instruction list; - } - -type frame_info_element = - | FIE_cie of cie - | FIE_fde of fde - -type frame_info = frame_info_element list - - -(* evaluated cfa data *) - -type cfa_rule = - | CR_undefined - | CR_register of cfa_register * Nat_big_num.num - | CR_expression of single_location_description - -type register_rule = - | RR_undefined (*A register that has this rule has no recoverable value in the previous frame. - (By convention, it is not preserved by a callee.)*) - | RR_same_value (*This register has not been modified from the previous frame. (By convention, - it is preserved by the callee, but the callee has not modified it.)*) - | RR_offset of Nat_big_num.num (* The previous value of this register is saved at the address CFA+N where CFA - is the current CFA value and N is a signed offset.*) - | RR_val_offset of Nat_big_num.num (* The previous value of this register is the value CFA+N where CFA is the - current CFA value and N is a signed offset.*) - | RR_register of Nat_big_num.num (* The previous value of this register is stored in another register numbered R.*) - | RR_expression of single_location_description (* The previous value of this register is located at the address produced by - executing the DWARF expression E.*) - | RR_val_expression of single_location_description (* The previous value of this register is the value produced by executing the -DWARF expression E.*) - | RR_architectural (*The rule is defined externally to this specification by the augmenter*) - -type register_rule_map = (cfa_register * register_rule) list - -type cfa_table_row = - { - ctr_loc: Nat_big_num.num; - ctr_cfa: cfa_rule; - ctr_regs: register_rule_map; - } - -type cfa_state = - { - cs_current_row: cfa_table_row; - cs_previous_rows: cfa_table_row list; - cs_initial_instructions_row: cfa_table_row; - cs_row_stack: cfa_table_row list; - } - - -type evaluated_frame_info = (fde * cfa_table_row list) - list - - -(* line number *) - -type line_number_argument_type = - | LNAT_address - | LNAT_ULEB128 - | LNAT_SLEB128 - | LNAT_uint16 - | LNAT_string - -type line_number_argument_value = - | LNAV_address of Nat_big_num.num - | LNAV_ULEB128 of Nat_big_num.num - | LNAV_SLEB128 of Nat_big_num.num - | LNAV_uint16 of Nat_big_num.num - | LNAV_string of char list (* not including terminating null *) - -type line_number_operation = - (* standard *) - | DW_LNS_copy - | DW_LNS_advance_pc of Nat_big_num.num - | DW_LNS_advance_line of Nat_big_num.num - | DW_LNS_set_file of Nat_big_num.num - | DW_LNS_set_column of Nat_big_num.num - | DW_LNS_negate_stmt - | DW_LNS_set_basic_block - | DW_LNS_const_add_pc - | DW_LNS_fixed_advance_pc of Nat_big_num.num - | DW_LNS_set_prologue_end - | DW_LNS_set_epilogue_begin - | DW_LNS_set_isa of Nat_big_num.num - (* extended *) - | DW_LNE_end_sequence - | DW_LNE_set_address of Nat_big_num.num - | DW_LNE_define_file of ( char list) * Nat_big_num.num * Nat_big_num.num * Nat_big_num.num - | DW_LNE_set_discriminator of Nat_big_num.num - (* special *) - | DW_LN_special of Nat_big_num.num (* the adjusted opcode *) - -type line_number_file_entry = - { - lnfe_path: char list; - lnfe_directory_index: Nat_big_num.num; - lnfe_last_modification: Nat_big_num.num; - lnfe_length: Nat_big_num.num; - } - -type line_number_header = - { - lnh_offset: Nat_big_num.num; - lnh_dwarf_format: dwarf_format; - lnh_unit_length: Nat_big_num.num; - lnh_version: Nat_big_num.num; - lnh_header_length: Nat_big_num.num; - lnh_minimum_instruction_length: Nat_big_num.num; - lnh_maximum_operations_per_instruction: Nat_big_num.num; - lnh_default_is_stmt: bool; - lnh_line_base: Nat_big_num.num; - lnh_line_range: Nat_big_num.num; - lnh_opcode_base: Nat_big_num.num; - lnh_standard_opcode_lengths: Nat_big_num.num list; - lnh_include_directories: ( char list) list; - lnh_file_names: line_number_file_entry list; - } - -type line_number_program = - { - lnp_header: line_number_header; - lnp_operations: line_number_operation list; - } - -(* line number evaluation *) - -type line_number_registers = - { - lnr_address: Nat_big_num.num; - lnr_op_index: Nat_big_num.num; - lnr_file: Nat_big_num.num; - lnr_line: Nat_big_num.num; - lnr_column: Nat_big_num.num; - lnr_is_stmt: bool; - lnr_basic_block: bool; - lnr_end_sequence: bool; - lnr_prologue_end: bool; - lnr_epilogue_begin: bool; - lnr_isa: Nat_big_num.num; - lnr_discriminator: Nat_big_num.num; - } - - - - -(* top-level collection of dwarf data *) - -type dwarf = - { - d_endianness: Endianness.endianness; (* from the ELF *) - d_str: char list; - d_compilation_units: compilation_units; - d_type_units: type_units; - d_loc: location_list_list; - d_ranges: range_list_list; - d_frame_info: frame_info; - d_line_info: line_number_program list; - } - -(* analysed location data *) - -type analysed_location_data = ((compilation_unit * ( die list) * die) * ( (Nat_big_num.num * Nat_big_num.num * single_location_description)list)option) list - -type analysed_location_data_at_pc = ((compilation_unit * ( die list) * die) * (Nat_big_num.num * Nat_big_num.num * single_location_description * single_location error)) list - -(* evaluated line data *) - -type evaluated_line_info = (line_number_header * line_number_registers list) list - -type dwarf_static = - { - ds_dwarf: dwarf; - ds_analysed_location_data: analysed_location_data; - ds_evaluated_frame_info: evaluated_frame_info; - ds_evaluated_line_info: evaluated_line_info; - } - -type dwarf_dynamic_at_pc = analysed_location_data_at_pc - -(** context for parsing and pp functions *) - -type p_context = - { - endianness: Endianness.endianness; - } - - - -(** ************************************************************ *) -(** ** missing pervasives ************************************ *) -(** ************************************************************ *) - -(** hex parsing *) - -(* this should be in lem, either built-in or in pervasives *) - -(*val natural_of_char : char -> natural*) -let natural_of_char c:Nat_big_num.num= - (let naturalOrd c'= (Nat_big_num.of_int (Char.code c')) in - let n = (naturalOrd c) in - if Nat_big_num.greater_equal n (naturalOrd '0') && Nat_big_num.less_equal n (naturalOrd '9') then Nat_big_num.sub_nat n (naturalOrd '0') - else if Nat_big_num.greater_equal n (naturalOrd 'A') && Nat_big_num.less_equal n (naturalOrd 'F') then Nat_big_num.add (Nat_big_num.sub_nat n (naturalOrd 'A'))(Nat_big_num.of_int 10) - else if Nat_big_num.greater_equal n (naturalOrd 'a') && Nat_big_num.less_equal n (naturalOrd 'f') then Nat_big_num.add (Nat_big_num.sub_nat n (naturalOrd 'a'))(Nat_big_num.of_int 10) - else failwith ("natural_of_char argument #'" ^ (Xstring.implode [c] ^ "' not in 0-9,A-F,a-f"))) - -(*val natural_of_hex' : list char -> natural*) -let rec natural_of_hex' cs:Nat_big_num.num= - ((match cs with - | c :: cs' -> Nat_big_num.add (natural_of_char c) (Nat_big_num.mul(Nat_big_num.of_int 16) (natural_of_hex' cs')) - | [] ->Nat_big_num.of_int 0 - )) - -(*val natural_of_hex : string -> natural*) -let natural_of_hex s:Nat_big_num.num= - (let cs = (Xstring.explode s) in - (match cs with - | '0'::'x'::cs' -> - (match cs' with - | c :: _ -> natural_of_hex' (List.rev cs') - | [] -> failwith ("natural_of_hex argument \"" ^ (s ^ "\" has no digits")) - ) - | _ -> failwith ("natural_of_hex argument \"" ^ (s ^ "\" does not begin 0x")) - )) - - -(* natural version of List.index *) -(*val index_natural : forall 'a. list 'a -> natural -> maybe 'a*) -let rec index_natural l n:'a option= ((match l with - | [] -> None - | x :: xs -> if Nat_big_num.equal n(Nat_big_num.of_int 0) then Some x else index_natural xs (Nat_big_num.sub_nat n(Nat_big_num.of_int 1)) -)) - -let partialNaturalFromInteger (i:Nat_big_num.num) : Nat_big_num.num= - (if Nat_big_num.less i(Nat_big_num.of_int 0) then failwith "partialNaturalFromInteger" else Nat_big_num.abs i) - -(*val natural_nat_shift_left : natural -> nat -> natural*) - -(*val natural_nat_shift_right : natural -> nat -> natural*) - - - -(** ************************************************************ *) -(** ** dwarf encodings *************************************** *) -(** ************************************************************ *) - -(* these encoding tables are pasted from the DWARF 4 specification *) - -(* tag encoding *) -let tag_encodings:(string*Nat_big_num.num)list= ([ - ("DW_TAG_array_type" , natural_of_hex "0x01" ); - ("DW_TAG_class_type" , natural_of_hex "0x02" ); - ("DW_TAG_entry_point" , natural_of_hex "0x03" ); - ("DW_TAG_enumeration_type" , natural_of_hex "0x04" ); - ("DW_TAG_formal_parameter" , natural_of_hex "0x05" ); - ("DW_TAG_imported_declaration" , natural_of_hex "0x08" ); - ("DW_TAG_label" , natural_of_hex "0x0a" ); - ("DW_TAG_lexical_block" , natural_of_hex "0x0b" ); - ("DW_TAG_member" , natural_of_hex "0x0d" ); - ("DW_TAG_pointer_type" , natural_of_hex "0x0f" ); - ("DW_TAG_reference_type" , natural_of_hex "0x10" ); - ("DW_TAG_compile_unit" , natural_of_hex "0x11" ); - ("DW_TAG_string_type" , natural_of_hex "0x12" ); - ("DW_TAG_structure_type" , natural_of_hex "0x13" ); - ("DW_TAG_subroutine_type" , natural_of_hex "0x15" ); - ("DW_TAG_typedef" , natural_of_hex "0x16" ); - ("DW_TAG_union_type" , natural_of_hex "0x17" ); - ("DW_TAG_unspecified_parameters" , natural_of_hex "0x18" ); - ("DW_TAG_variant" , natural_of_hex "0x19" ); - ("DW_TAG_common_block" , natural_of_hex "0x1a" ); - ("DW_TAG_common_inclusion" , natural_of_hex "0x1b" ); - ("DW_TAG_inheritance" , natural_of_hex "0x1c" ); - ("DW_TAG_inlined_subroutine" , natural_of_hex "0x1d" ); - ("DW_TAG_module" , natural_of_hex "0x1e" ); - ("DW_TAG_ptr_to_member_type" , natural_of_hex "0x1f" ); - ("DW_TAG_set_type" , natural_of_hex "0x20" ); - ("DW_TAG_subrange_type" , natural_of_hex "0x21" ); - ("DW_TAG_with_stmt" , natural_of_hex "0x22" ); - ("DW_TAG_access_declaration" , natural_of_hex "0x23" ); - ("DW_TAG_base_type" , natural_of_hex "0x24" ); - ("DW_TAG_catch_block" , natural_of_hex "0x25" ); - ("DW_TAG_const_type" , natural_of_hex "0x26" ); - ("DW_TAG_constant" , natural_of_hex "0x27" ); - ("DW_TAG_enumerator" , natural_of_hex "0x28" ); - ("DW_TAG_file_type" , natural_of_hex "0x29" ); - ("DW_TAG_friend" , natural_of_hex "0x2a" ); - ("DW_TAG_namelist" , natural_of_hex "0x2b" ); - ("DW_TAG_namelist_item" , natural_of_hex "0x2c" ); - ("DW_TAG_packed_type" , natural_of_hex "0x2d" ); - ("DW_TAG_subprogram" , natural_of_hex "0x2e" ); - ("DW_TAG_template_type_parameter" , natural_of_hex "0x2f" ); - ("DW_TAG_template_value_parameter" , natural_of_hex "0x30" ); - ("DW_TAG_thrown_type" , natural_of_hex "0x31" ); - ("DW_TAG_try_block" , natural_of_hex "0x32" ); - ("DW_TAG_variant_part" , natural_of_hex "0x33" ); - ("DW_TAG_variable" , natural_of_hex "0x34" ); - ("DW_TAG_volatile_type" , natural_of_hex "0x35" ); - ("DW_TAG_dwarf_procedure" , natural_of_hex "0x36" ); - ("DW_TAG_restrict_type" , natural_of_hex "0x37" ); - ("DW_TAG_interface_type" , natural_of_hex "0x38" ); - ("DW_TAG_namespace" , natural_of_hex "0x39" ); - ("DW_TAG_imported_module" , natural_of_hex "0x3a" ); - ("DW_TAG_unspecified_type" , natural_of_hex "0x3b" ); - ("DW_TAG_partial_unit" , natural_of_hex "0x3c" ); - ("DW_TAG_imported_unit" , natural_of_hex "0x3d" ); - ("DW_TAG_condition" , natural_of_hex "0x3f" ); - ("DW_TAG_shared_type" , natural_of_hex "0x40" ); - ("DW_TAG_type_unit" , natural_of_hex "0x41" ); - ("DW_TAG_rvalue_reference_type" , natural_of_hex "0x42" ); - ("DW_TAG_template_alias" , natural_of_hex "0x43" ); - ("DW_TAG_lo_user" , natural_of_hex "0x4080"); - ("DW_TAG_hi_user" , natural_of_hex "0xffff") -]) - - -(* child determination encoding *) - -let vDW_CHILDREN_no:Nat_big_num.num= (natural_of_hex "0x00") -let vDW_CHILDREN_yes:Nat_big_num.num= (natural_of_hex "0x01") - - -(* attribute encoding *) - -let attribute_encodings:(string*Nat_big_num.num*(dwarf_attribute_classes)list)list= ([ - ("DW_AT_sibling" , natural_of_hex "0x01", [DWA_reference]) ; - ("DW_AT_location" , natural_of_hex "0x02", [DWA_exprloc; DWA_loclistptr]) ; - ("DW_AT_name" , natural_of_hex "0x03", [DWA_string]) ; - ("DW_AT_ordering" , natural_of_hex "0x09", [DWA_constant]) ; - ("DW_AT_byte_size" , natural_of_hex "0x0b", [DWA_constant; DWA_exprloc; DWA_reference]) ; - ("DW_AT_bit_offset" , natural_of_hex "0x0c", [DWA_constant; DWA_exprloc; DWA_reference]) ; - ("DW_AT_bit_size" , natural_of_hex "0x0d", [DWA_constant; DWA_exprloc; DWA_reference]) ; - ("DW_AT_stmt_list" , natural_of_hex "0x10", [DWA_lineptr]) ; - ("DW_AT_low_pc" , natural_of_hex "0x11", [DWA_address]) ; - ("DW_AT_high_pc" , natural_of_hex "0x12", [DWA_address; DWA_constant]) ; - ("DW_AT_language" , natural_of_hex "0x13", [DWA_constant]) ; - ("DW_AT_discr" , natural_of_hex "0x15", [DWA_reference]) ; - ("DW_AT_discr_value" , natural_of_hex "0x16", [DWA_constant]) ; - ("DW_AT_visibility" , natural_of_hex "0x17", [DWA_constant]) ; - ("DW_AT_import" , natural_of_hex "0x18", [DWA_reference]) ; - ("DW_AT_string_length" , natural_of_hex "0x19", [DWA_exprloc; DWA_loclistptr]) ; - ("DW_AT_common_reference" , natural_of_hex "0x1a", [DWA_reference]) ; - ("DW_AT_comp_dir" , natural_of_hex "0x1b", [DWA_string]) ; - ("DW_AT_const_value" , natural_of_hex "0x1c", [DWA_block; DWA_constant; DWA_string]) ; - ("DW_AT_containing_type" , natural_of_hex "0x1d", [DWA_reference]) ; - ("DW_AT_default_value" , natural_of_hex "0x1e", [DWA_reference]) ; - ("DW_AT_inline" , natural_of_hex "0x20", [DWA_constant]) ; - ("DW_AT_is_optional" , natural_of_hex "0x21", [DWA_flag]) ; - ("DW_AT_lower_bound" , natural_of_hex "0x22", [DWA_constant; DWA_exprloc; DWA_reference]) ; - ("DW_AT_producer" , natural_of_hex "0x25", [DWA_string]) ; - ("DW_AT_prototyped" , natural_of_hex "0x27", [DWA_flag]) ; - ("DW_AT_return_addr" , natural_of_hex "0x2a", [DWA_exprloc; DWA_loclistptr]) ; - ("DW_AT_start_scope" , natural_of_hex "0x2c", [DWA_constant; DWA_rangelistptr]) ; - ("DW_AT_bit_stride" , natural_of_hex "0x2e", [DWA_constant; DWA_exprloc; DWA_reference]) ; - ("DW_AT_upper_bound" , natural_of_hex "0x2f", [DWA_constant; DWA_exprloc; DWA_reference]) ; - ("DW_AT_abstract_origin" , natural_of_hex "0x31", [DWA_reference]) ; - ("DW_AT_accessibility" , natural_of_hex "0x32", [DWA_constant]) ; - ("DW_AT_address_class" , natural_of_hex "0x33", [DWA_constant]) ; - ("DW_AT_artificial" , natural_of_hex "0x34", [DWA_flag]) ; - ("DW_AT_base_types" , natural_of_hex "0x35", [DWA_reference]) ; - ("DW_AT_calling_convention" , natural_of_hex "0x36", [DWA_constant]) ; - ("DW_AT_count" , natural_of_hex "0x37", [DWA_constant; DWA_exprloc; DWA_reference]) ; - ("DW_AT_data_member_location" , natural_of_hex "0x38", [DWA_constant; DWA_exprloc; DWA_loclistptr]) ; - ("DW_AT_decl_column" , natural_of_hex "0x39", [DWA_constant]) ; - ("DW_AT_decl_file" , natural_of_hex "0x3a", [DWA_constant]) ; - ("DW_AT_decl_line" , natural_of_hex "0x3b", [DWA_constant]) ; - ("DW_AT_declaration" , natural_of_hex "0x3c", [DWA_flag]) ; - ("DW_AT_discr_list" , natural_of_hex "0x3d", [DWA_block]) ; - ("DW_AT_encoding" , natural_of_hex "0x3e", [DWA_constant]) ; - ("DW_AT_external" , natural_of_hex "0x3f", [DWA_flag]) ; - ("DW_AT_frame_base" , natural_of_hex "0x40", [DWA_exprloc; DWA_loclistptr]) ; - ("DW_AT_friend" , natural_of_hex "0x41", [DWA_reference]) ; - ("DW_AT_identifier_case" , natural_of_hex "0x42", [DWA_constant]) ; - ("DW_AT_macro_info" , natural_of_hex "0x43", [DWA_macptr]) ; - ("DW_AT_namelist_item" , natural_of_hex "0x44", [DWA_reference]) ; - ("DW_AT_priority" , natural_of_hex "0x45", [DWA_reference]) ; - ("DW_AT_segment" , natural_of_hex "0x46", [DWA_exprloc; DWA_loclistptr]) ; - ("DW_AT_specification" , natural_of_hex "0x47", [DWA_reference]) ; - ("DW_AT_static_link" , natural_of_hex "0x48", [DWA_exprloc; DWA_loclistptr]) ; - ("DW_AT_type" , natural_of_hex "0x49", [DWA_reference]) ; - ("DW_AT_use_location" , natural_of_hex "0x4a", [DWA_exprloc; DWA_loclistptr]) ; - ("DW_AT_variable_parameter" , natural_of_hex "0x4b", [DWA_flag]) ; - ("DW_AT_virtuality" , natural_of_hex "0x4c", [DWA_constant]) ; - ("DW_AT_vtable_elem_location" , natural_of_hex "0x4d", [DWA_exprloc; DWA_loclistptr]) ; - ("DW_AT_allocated" , natural_of_hex "0x4e", [DWA_constant; DWA_exprloc; DWA_reference]) ; - ("DW_AT_associated" , natural_of_hex "0x4f", [DWA_constant; DWA_exprloc; DWA_reference]) ; - ("DW_AT_data_location" , natural_of_hex "0x50", [DWA_exprloc]) ; - ("DW_AT_byte_stride" , natural_of_hex "0x51", [DWA_constant; DWA_exprloc; DWA_reference]) ; - ("DW_AT_entry_pc" , natural_of_hex "0x52", [DWA_address]) ; - ("DW_AT_use_UTF8" , natural_of_hex "0x53", [DWA_flag]) ; - ("DW_AT_extension" , natural_of_hex "0x54", [DWA_reference]) ; - ("DW_AT_ranges" , natural_of_hex "0x55", [DWA_rangelistptr]) ; - ("DW_AT_trampoline" , natural_of_hex "0x56", [DWA_address; DWA_flag; DWA_reference; DWA_string]); - ("DW_AT_call_column" , natural_of_hex "0x57", [DWA_constant]) ; - ("DW_AT_call_file" , natural_of_hex "0x58", [DWA_constant]) ; - ("DW_AT_call_line" , natural_of_hex "0x59", [DWA_constant]) ; - ("DW_AT_description" , natural_of_hex "0x5a", [DWA_string]) ; - ("DW_AT_binary_scale" , natural_of_hex "0x5b", [DWA_constant]) ; - ("DW_AT_decimal_scale" , natural_of_hex "0x5c", [DWA_constant]) ; - ("DW_AT_small" , natural_of_hex "0x5d", [DWA_reference]) ; - ("DW_AT_decimal_sign" , natural_of_hex "0x5e", [DWA_constant]) ; - ("DW_AT_digit_count" , natural_of_hex "0x5f", [DWA_constant]) ; - ("DW_AT_picture_string" , natural_of_hex "0x60", [DWA_string]) ; - ("DW_AT_mutable" , natural_of_hex "0x61", [DWA_flag]) ; - ("DW_AT_threads_scaled" , natural_of_hex "0x62", [DWA_flag]) ; - ("DW_AT_explicit" , natural_of_hex "0x63", [DWA_flag]) ; - ("DW_AT_object_pointer" , natural_of_hex "0x64", [DWA_reference]) ; - ("DW_AT_endianity" , natural_of_hex "0x65", [DWA_constant]) ; - ("DW_AT_elemental" , natural_of_hex "0x66", [DWA_flag]) ; - ("DW_AT_pure" , natural_of_hex "0x67", [DWA_flag]) ; - ("DW_AT_recursive" , natural_of_hex "0x68", [DWA_flag]) ; - ("DW_AT_signature" , natural_of_hex "0x69", [DWA_reference]) ; - ("DW_AT_main_subprogram" , natural_of_hex "0x6a", [DWA_flag]) ; - ("DW_AT_data_bit_offset" , natural_of_hex "0x6b", [DWA_constant]) ; - ("DW_AT_const_expr" , natural_of_hex "0x6c", [DWA_flag]) ; - ("DW_AT_enum_class" , natural_of_hex "0x6d", [DWA_flag]) ; - ("DW_AT_linkage_name" , natural_of_hex "0x6e", [DWA_string]) ; - ("DW_AT_lo_user" , natural_of_hex "0x2000", [DWA_dash]) ; - ("DW_AT_hi_user" , natural_of_hex "0x3fff", [DWA_dash]) -]) - - -(* attribute form encoding *) - -let attribute_form_encodings:(string*Nat_big_num.num*(dwarf_attribute_classes)list)list= ([ - ("DW_FORM_addr" , natural_of_hex "0x01", [DWA_address]) ; - ("DW_FORM_block2" , natural_of_hex "0x03", [DWA_block]) ; - ("DW_FORM_block4" , natural_of_hex "0x04", [DWA_block]) ; - ("DW_FORM_data2" , natural_of_hex "0x05", [DWA_constant]) ; - ("DW_FORM_data4" , natural_of_hex "0x06", [DWA_constant]) ; - ("DW_FORM_data8" , natural_of_hex "0x07", [DWA_constant]) ; - ("DW_FORM_string" , natural_of_hex "0x08", [DWA_string]) ; - ("DW_FORM_block" , natural_of_hex "0x09", [DWA_block]) ; - ("DW_FORM_block1" , natural_of_hex "0x0a", [DWA_block]) ; - ("DW_FORM_data1" , natural_of_hex "0x0b", [DWA_constant]) ; - ("DW_FORM_flag" , natural_of_hex "0x0c", [DWA_flag]) ; - ("DW_FORM_sdata" , natural_of_hex "0x0d", [DWA_constant]) ; - ("DW_FORM_strp" , natural_of_hex "0x0e", [DWA_string]) ; - ("DW_FORM_udata" , natural_of_hex "0x0f", [DWA_constant]) ; - ("DW_FORM_ref_addr" , natural_of_hex "0x10", [DWA_reference]); - ("DW_FORM_ref1" , natural_of_hex "0x11", [DWA_reference]); - ("DW_FORM_ref2" , natural_of_hex "0x12", [DWA_reference]); - ("DW_FORM_ref4" , natural_of_hex "0x13", [DWA_reference]); - ("DW_FORM_ref8" , natural_of_hex "0x14", [DWA_reference]); - ("DW_FORM_ref_udata" , natural_of_hex "0x15", [DWA_reference]); - ("DW_FORM_indirect" , natural_of_hex "0x16", [DWA_7_5_3]) ; - ("DW_FORM_sec_offset" , natural_of_hex "0x17", [DWA_lineptr; DWA_loclistptr; DWA_macptr; DWA_rangelistptr]) ; - ("DW_FORM_exprloc" , natural_of_hex "0x18", [DWA_exprloc]) ; - ("DW_FORM_flag_present", natural_of_hex "0x19", [DWA_flag]) ; - ("DW_FORM_ref_sig8" , natural_of_hex "0x20", [DWA_reference]) -]) - - -(* operation encoding *) - -let operation_encodings:(string*Nat_big_num.num*(operation_argument_type)list*operation_semantics)list= ([ -("DW_OP_addr", natural_of_hex "0x03", [OAT_addr] , OpSem_lit); (*1*) (*constant address (size target specific)*) -("DW_OP_deref", natural_of_hex "0x06", [] , OpSem_deref); (*0*) -("DW_OP_const1u", natural_of_hex "0x08", [OAT_uint8] , OpSem_lit); (*1*) (* 1-byte constant *) -("DW_OP_const1s", natural_of_hex "0x09", [OAT_sint8] , OpSem_lit); (*1*) (* 1-byte constant *) -("DW_OP_const2u", natural_of_hex "0x0a", [OAT_uint16] , OpSem_lit); (*1*) (* 2-byte constant *) -("DW_OP_const2s", natural_of_hex "0x0b", [OAT_sint16] , OpSem_lit); (*1*) (* 2-byte constant *) -("DW_OP_const4u", natural_of_hex "0x0c", [OAT_uint32] , OpSem_lit); (*1*) (* 4-byte constant *) -("DW_OP_const4s", natural_of_hex "0x0d", [OAT_sint32] , OpSem_lit); (*1*) (* 4-byte constant *) -("DW_OP_const8u", natural_of_hex "0x0e", [OAT_uint64] , OpSem_lit); (*1*) (* 8-byte constant *) -("DW_OP_const8s", natural_of_hex "0x0f", [OAT_sint64] , OpSem_lit); (*1*) (* 8-byte constant *) -("DW_OP_constu", natural_of_hex "0x10", [OAT_ULEB128] , OpSem_lit); (*1*) (* ULEB128 constant *) -("DW_OP_consts", natural_of_hex "0x11", [OAT_SLEB128] , OpSem_lit); (*1*) (* SLEB128 constant *) -("DW_OP_dup", natural_of_hex "0x12", [] , OpSem_stack (fun ac vs args -> (match vs with v::vs -> Some (v::(v::vs)) | _ -> None ))); (*0*) -("DW_OP_drop", natural_of_hex "0x13", [] , OpSem_stack (fun ac vs args -> (match vs with v::vs -> Some vs | _ -> None ))); (*0*) -("DW_OP_over", natural_of_hex "0x14", [] , OpSem_stack (fun ac vs args -> (match vs with v::v'::vs -> Some (v'::(v::(v'::vs))) | _ -> None ))); (*0*) -("DW_OP_pick", natural_of_hex "0x15", [OAT_uint8] , OpSem_stack (fun ac vs args -> (match args with [OAV_natural n] -> (match index_natural vs n with Some v -> Some (v::vs) | None -> None ) | _ -> None ))); (*1*) (* 1-byte stack index *) -("DW_OP_swap", natural_of_hex "0x16", [] , OpSem_stack (fun ac vs args -> (match vs with v::v'::vs -> Some (v'::(v::vs)) | _ -> None ))); (*0*) -("DW_OP_rot", natural_of_hex "0x17", [] , OpSem_stack (fun ac vs args -> (match vs with v::v'::v''::vs -> Some (v'::(v''::(v::vs))) | _ -> None ))); (*0*) -("DW_OP_xderef", natural_of_hex "0x18", [] , OpSem_not_supported); (*0*) -("DW_OP_abs", natural_of_hex "0x19", [] , OpSem_unary (fun ac v -> if Nat_big_num.less v ac.ac_half then Some v else if Nat_big_num.equal v ac.ac_max then None else Some (Nat_big_num.sub_nat ac.ac_all v))); (*0*) -("DW_OP_and", natural_of_hex "0x1a", [] , OpSem_binary (fun ac v1 v2 -> Some (Nat_big_num.bitwise_and v1 v2))); (*0*) -("DW_OP_div", natural_of_hex "0x1b", [] , OpSem_not_supported) (*TODO*); (*0*) -("DW_OP_minus", natural_of_hex "0x1c", [] , OpSem_binary (fun ac v1 v2 -> Some (partialNaturalFromInteger ( Nat_big_num.modulus( Nat_big_num.sub( v1) ( v2)) ( ac.ac_all))))); (*0*) -("DW_OP_mod", natural_of_hex "0x1d", [] , OpSem_binary (fun ac v1 v2 -> Some ( Nat_big_num.modulus v1 v2))); (*0*) -("DW_OP_mul", natural_of_hex "0x1e", [] , OpSem_binary (fun ac v1 v2 -> Some (partialNaturalFromInteger ( Nat_big_num.modulus( Nat_big_num.mul( v1) ( v2)) ( ac.ac_all))))); (*0*) -("DW_OP_neg", natural_of_hex "0x1f", [] , OpSem_unary (fun ac v -> if Nat_big_num.less v ac.ac_half then Some ( Nat_big_num.sub_nat ac.ac_max v) else if Nat_big_num.equal v ac.ac_half then None else Some ( Nat_big_num.sub_nat ac.ac_all v))); (*0*) -("DW_OP_not", natural_of_hex "0x20", [] , OpSem_unary (fun ac v -> Some (Nat_big_num.bitwise_xor v ac.ac_max))); (*0*) -("DW_OP_or", natural_of_hex "0x21", [] , OpSem_binary (fun ac v1 v2 -> Some (Nat_big_num.bitwise_or v1 v2))); (*0*) -("DW_OP_plus", natural_of_hex "0x22", [] , OpSem_binary (fun ac v1 v2 -> Some ( Nat_big_num.modulus( Nat_big_num.add v1 v2) ac.ac_all))); (*0*) -("DW_OP_plus_uconst", natural_of_hex "0x23", [OAT_ULEB128] , OpSem_stack (fun ac vs args -> (match args with [OAV_natural n] -> (match vs with v::vs' -> let v' = (Nat_big_num.modulus (Nat_big_num.add v n) ac.ac_all) in Some (v'::vs) | [] -> None ) | _ -> None ))); (*1*) (* ULEB128 addend *) -("DW_OP_shl", natural_of_hex "0x24", [] , OpSem_binary (fun ac v1 v2 -> if Nat_big_num.greater_equal v2 ac.ac_bitwidth then Some(Nat_big_num.of_int 0) else Some (Nat_big_num.shift_left v1 (Nat_big_num.to_int v2)))); (*0*) -("DW_OP_shr", natural_of_hex "0x25", [] , OpSem_binary (fun ac v1 v2 -> if Nat_big_num.greater_equal v2 ac.ac_bitwidth then Some(Nat_big_num.of_int 0) else Some (Nat_big_num.shift_right v1 (Nat_big_num.to_int v2)))); (*0*) -("DW_OP_shra", natural_of_hex "0x26", [] , OpSem_binary (fun ac v1 v2 -> if Nat_big_num.less v1 ac.ac_half then (if Nat_big_num.greater_equal v2 ac.ac_bitwidth then Some(Nat_big_num.of_int 0) else Some (Nat_big_num.shift_right v1 (Nat_big_num.to_int v2))) else (if Nat_big_num.greater_equal v2 ac.ac_bitwidth then Some ac.ac_max else Some ( Nat_big_num.sub_nat ac.ac_max (Nat_big_num.shift_right ( Nat_big_num.sub_nat ac.ac_max v1) (Nat_big_num.to_int v2)))))); (*0*) -("DW_OP_xor", natural_of_hex "0x27", [] , OpSem_binary (fun ac v1 v2 -> Some (Nat_big_num.bitwise_xor v1 v2))); (*0*) -("DW_OP_skip", natural_of_hex "0x2f", [OAT_sint16] , OpSem_not_supported); (*1*) (* signed 2-byte constant *) -("DW_OP_bra", natural_of_hex "0x28", [OAT_sint16] , OpSem_not_supported); (*1*) (* signed 2-byte constant *) -("DW_OP_eq", natural_of_hex "0x29", [] , OpSem_not_supported); (*0*) -("DW_OP_ge", natural_of_hex "0x2a", [] , OpSem_not_supported); (*0*) -("DW_OP_gt", natural_of_hex "0x2b", [] , OpSem_not_supported); (*0*) -("DW_OP_le", natural_of_hex "0x2c", [] , OpSem_not_supported); (*0*) -("DW_OP_lt", natural_of_hex "0x2d", [] , OpSem_not_supported); (*0*) -("DW_OP_ne", natural_of_hex "0x2e", [] , OpSem_not_supported); (*0*) -("DW_OP_lit0", natural_of_hex "0x30", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) (* literals 0..31 =(DW_OP_lit0 + literal) *) -("DW_OP_lit1", natural_of_hex "0x31", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit2", natural_of_hex "0x32", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit3", natural_of_hex "0x33", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit4", natural_of_hex "0x34", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit5", natural_of_hex "0x35", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit6", natural_of_hex "0x36", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit7", natural_of_hex "0x37", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit8", natural_of_hex "0x38", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit9", natural_of_hex "0x39", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit10", natural_of_hex "0x3a", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit11", natural_of_hex "0x3b", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit12", natural_of_hex "0x3c", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit13", natural_of_hex "0x3d", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit14", natural_of_hex "0x3e", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit15", natural_of_hex "0x3f", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit16", natural_of_hex "0x40", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit17", natural_of_hex "0x41", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit18", natural_of_hex "0x42", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit19", natural_of_hex "0x43", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit20", natural_of_hex "0x44", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit21", natural_of_hex "0x45", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit22", natural_of_hex "0x46", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit23", natural_of_hex "0x47", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit24", natural_of_hex "0x48", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit25", natural_of_hex "0x49", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit26", natural_of_hex "0x4a", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit27", natural_of_hex "0x4b", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit28", natural_of_hex "0x4c", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit29", natural_of_hex "0x4d", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit30", natural_of_hex "0x4e", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_lit31", natural_of_hex "0x4f", [] , OpSem_opcode_lit (natural_of_hex "0x30")); (*0*) -("DW_OP_reg0", natural_of_hex "0x50", [] , OpSem_reg); (*1*) (* reg 0..31 = (DW_OP_reg0 + regnum) *) -("DW_OP_reg1", natural_of_hex "0x51", [] , OpSem_reg); (*1*) -("DW_OP_reg2", natural_of_hex "0x52", [] , OpSem_reg); (*1*) -("DW_OP_reg3", natural_of_hex "0x53", [] , OpSem_reg); (*1*) -("DW_OP_reg4", natural_of_hex "0x54", [] , OpSem_reg); (*1*) -("DW_OP_reg5", natural_of_hex "0x55", [] , OpSem_reg); (*1*) -("DW_OP_reg6", natural_of_hex "0x56", [] , OpSem_reg); (*1*) -("DW_OP_reg7", natural_of_hex "0x57", [] , OpSem_reg); (*1*) -("DW_OP_reg8", natural_of_hex "0x58", [] , OpSem_reg); (*1*) -("DW_OP_reg9", natural_of_hex "0x59", [] , OpSem_reg); (*1*) -("DW_OP_reg10", natural_of_hex "0x5a", [] , OpSem_reg); (*1*) -("DW_OP_reg11", natural_of_hex "0x5b", [] , OpSem_reg); (*1*) -("DW_OP_reg12", natural_of_hex "0x5c", [] , OpSem_reg); (*1*) -("DW_OP_reg13", natural_of_hex "0x5d", [] , OpSem_reg); (*1*) -("DW_OP_reg14", natural_of_hex "0x5e", [] , OpSem_reg); (*1*) -("DW_OP_reg15", natural_of_hex "0x5f", [] , OpSem_reg); (*1*) -("DW_OP_reg16", natural_of_hex "0x60", [] , OpSem_reg); (*1*) -("DW_OP_reg17", natural_of_hex "0x61", [] , OpSem_reg); (*1*) -("DW_OP_reg18", natural_of_hex "0x62", [] , OpSem_reg); (*1*) -("DW_OP_reg19", natural_of_hex "0x63", [] , OpSem_reg); (*1*) -("DW_OP_reg20", natural_of_hex "0x64", [] , OpSem_reg); (*1*) -("DW_OP_reg21", natural_of_hex "0x65", [] , OpSem_reg); (*1*) -("DW_OP_reg22", natural_of_hex "0x66", [] , OpSem_reg); (*1*) -("DW_OP_reg23", natural_of_hex "0x67", [] , OpSem_reg); (*1*) -("DW_OP_reg24", natural_of_hex "0x68", [] , OpSem_reg); (*1*) -("DW_OP_reg25", natural_of_hex "0x69", [] , OpSem_reg); (*1*) -("DW_OP_reg26", natural_of_hex "0x6a", [] , OpSem_reg); (*1*) -("DW_OP_reg27", natural_of_hex "0x6b", [] , OpSem_reg); (*1*) -("DW_OP_reg28", natural_of_hex "0x6c", [] , OpSem_reg); (*1*) -("DW_OP_reg29", natural_of_hex "0x6d", [] , OpSem_reg); (*1*) -("DW_OP_reg30", natural_of_hex "0x6e", [] , OpSem_reg); (*1*) -("DW_OP_reg31", natural_of_hex "0x6f", [] , OpSem_reg); (*1*) -("DW_OP_breg0", natural_of_hex "0x70", [OAT_SLEB128] , OpSem_breg); (*1*) (* base register 0..31 = (DW_OP_breg0 + regnum) *) -("DW_OP_breg1", natural_of_hex "0x71", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg2", natural_of_hex "0x72", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg3", natural_of_hex "0x73", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg4", natural_of_hex "0x74", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg5", natural_of_hex "0x75", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg6", natural_of_hex "0x76", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg7", natural_of_hex "0x77", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg8", natural_of_hex "0x78", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg9", natural_of_hex "0x79", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg10", natural_of_hex "0x7a", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg11", natural_of_hex "0x7b", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg12", natural_of_hex "0x7c", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg13", natural_of_hex "0x7d", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg14", natural_of_hex "0x7e", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg15", natural_of_hex "0x7f", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg16", natural_of_hex "0x80", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg17", natural_of_hex "0x81", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg18", natural_of_hex "0x82", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg19", natural_of_hex "0x83", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg20", natural_of_hex "0x84", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg21", natural_of_hex "0x85", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg22", natural_of_hex "0x86", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg23", natural_of_hex "0x87", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg24", natural_of_hex "0x88", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg25", natural_of_hex "0x89", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg26", natural_of_hex "0x8a", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg27", natural_of_hex "0x8b", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg28", natural_of_hex "0x8c", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg29", natural_of_hex "0x8d", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg30", natural_of_hex "0x8e", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_breg31", natural_of_hex "0x8f", [OAT_SLEB128] , OpSem_breg); (*1*) -("DW_OP_regx", natural_of_hex "0x90", [OAT_ULEB128] , OpSem_lit); (*1*) (* ULEB128 register *) -("DW_OP_fbreg", natural_of_hex "0x91", [OAT_SLEB128] , OpSem_fbreg); (*1*) (* SLEB128 offset *) -("DW_OP_bregx", natural_of_hex "0x92", [OAT_ULEB128; OAT_SLEB128] , OpSem_bregx); (*2*) (* ULEB128 register followed by SLEB128 offset *) -("DW_OP_piece", natural_of_hex "0x93", [OAT_ULEB128] , OpSem_piece); (*1*) (* ULEB128 size of piece addressed *) -("DW_OP_deref_size", natural_of_hex "0x94", [OAT_uint8] , OpSem_deref_size); (*1*) (* 1-byte size of data retrieved *) -("DW_OP_xderef_size", natural_of_hex "0x95", [OAT_uint8] , OpSem_not_supported); (*1*) (* 1-byte size of data retrieved *) -("DW_OP_nop", natural_of_hex "0x96", [] , OpSem_nop); (*0*) -("DW_OP_push_object_address", natural_of_hex "0x97", [] , OpSem_not_supported); (*0*) -("DW_OP_call2", natural_of_hex "0x98", [OAT_uint16] , OpSem_not_supported); (*1*) (* 2-byte offset of DIE *) -("DW_OP_call4", natural_of_hex "0x99", [OAT_uint32] , OpSem_not_supported); (*1*) (* 4-byte offset of DIE *) -("DW_OP_call_ref", natural_of_hex "0x9a", [OAT_dwarf_format_t] , OpSem_not_supported); (*1*) (* 4- or 8-byte offset of DIE *) -("DW_OP_form_tls_address", natural_of_hex "0x9b", [] , OpSem_not_supported); (*0*) -("DW_OP_call_frame_cfa", natural_of_hex "0x9c", [] , OpSem_call_frame_cfa); (*0*) -("DW_OP_bit_piece", natural_of_hex "0x9d", [OAT_ULEB128; OAT_ULEB128] , OpSem_bit_piece); (*2*) (* ULEB128 size followed by ULEB128 offset *) -("DW_OP_implicit_value", natural_of_hex "0x9e", [OAT_block] , OpSem_implicit_value); (*2*) (* ULEB128 size followed by block of that size *) -("DW_OP_stack_value", natural_of_hex "0x9f", [] , OpSem_stack_value); (*0*) -(* these aren't real operations -("DW_OP_lo_user", natural_of_hex "0xe0", [] , ); -("DW_OP_hi_user", natural_of_hex "0xff", [] , ); -*) - -(* GCC also produces these for our example: -https://fedorahosted.org/elfutils/wiki/DwarfExtensions -http://dwarfstd.org/ShowIssue.php?issue=100909.1 *) -("DW_GNU_OP_entry_value", natural_of_hex "0xf3", [OAT_block], OpSem_not_supported); (*2*) (* ULEB128 size followed by DWARF expression block of that size*) -("DW_OP_GNU_implicit_pointer", natural_of_hex "0xf2", [OAT_dwarf_format_t;OAT_SLEB128], OpSem_not_supported) - -]) - - -let vDW_OP_reg0:Nat_big_num.num= (natural_of_hex "0x50") -let vDW_OP_breg0:Nat_big_num.num= (natural_of_hex "0x70") - - -(* call frame instruction encoding *) - -let call_frame_instruction_encoding : (string * Nat_big_num.num * Nat_big_num.num * call_frame_argument_type list * (( call_frame_argument_value list) -> call_frame_instruction option)) list= ([ -(* high-order 2 bits low-order 6 bits uniformly parsed arguments *) - -(* instructions using low-order 6 bits for first argument *) -(* -("DW_CFA_advance_loc", 1, 0,(*delta *) []); -("DW_CFA_offset", 2, 0,(*register*) [CFAT_offset]); -("DW_CFA_restore", 3, 0,(*register*) []); -*) -(* instructions using low-order 6 bits as part of opcode *) -("DW_CFA_nop",Nat_big_num.of_int 0, natural_of_hex "0x00", [], -( (* *)fun avs -> (match avs with [] -> Some (DW_CFA_nop) | _ -> None ))); -("DW_CFA_set_loc",Nat_big_num.of_int 0, natural_of_hex "0x01", [CFAT_address], -( (* address *)fun avs -> (match avs with [CFAV_address a] -> Some (DW_CFA_set_loc a) | _ -> None ))); -("DW_CFA_advance_loc1",Nat_big_num.of_int 0, natural_of_hex "0x02", [CFAT_delta1], -( (* 1-byte delta *)fun avs -> (match avs with [CFAV_delta d] -> Some (DW_CFA_advance_loc1 d) | _ -> None ))); -("DW_CFA_advance_loc2",Nat_big_num.of_int 0, natural_of_hex "0x03", [CFAT_delta2], -( (* 2-byte delta *)fun avs -> (match avs with [CFAV_delta d] -> Some (DW_CFA_advance_loc2 d) | _ -> None ))); -("DW_CFA_advance_loc4",Nat_big_num.of_int 0, natural_of_hex "0x04", [CFAT_delta4], -( (* 4-byte delta *)fun avs -> (match avs with [CFAV_delta d] -> Some (DW_CFA_advance_loc4 d) | _ -> None ))); -("DW_CFA_offset_extended",Nat_big_num.of_int 0, natural_of_hex "0x05", [CFAT_register; CFAT_offset], -( (* ULEB128 register ULEB128 offset *)fun avs -> (match avs with [CFAV_register r; CFAV_offset n] -> Some (DW_CFA_offset_extended( r, n)) | _ -> None ))); -("DW_CFA_restore_extended",Nat_big_num.of_int 0, natural_of_hex "0x06", [CFAT_register], -( (* ULEB128 register *)fun avs -> (match avs with [CFAV_register r] -> Some (DW_CFA_restore_extended r) | _ -> None ))); -("DW_CFA_undefined",Nat_big_num.of_int 0, natural_of_hex "0x07", [CFAT_register], -( (* ULEB128 register *)fun avs -> (match avs with [CFAV_register r] -> Some (DW_CFA_undefined r) | _ -> None ))); -("DW_CFA_same_value",Nat_big_num.of_int 0, natural_of_hex "0x08", [CFAT_register], -( (* ULEB128 register *)fun avs -> (match avs with [CFAV_register r] -> Some (DW_CFA_same_value r) | _ -> None ))); -("DW_CFA_register",Nat_big_num.of_int 0, natural_of_hex "0x09", [CFAT_register; CFAT_register], -( (* ULEB128 register ULEB128 register *)fun avs -> (match avs with [CFAV_register r1; CFAV_register r2] -> Some (DW_CFA_register( r1, r2)) | _ -> None ))); -("DW_CFA_remember_state",Nat_big_num.of_int 0, natural_of_hex "0x0a", [], -( (* *)fun avs -> (match avs with [] -> Some (DW_CFA_remember_state) | _ -> None ))); -("DW_CFA_restore_state",Nat_big_num.of_int 0, natural_of_hex "0x0b", [], -( (* *)fun avs -> (match avs with [] -> Some (DW_CFA_restore_state) | _ -> None ))); -("DW_CFA_def_cfa",Nat_big_num.of_int 0, natural_of_hex "0x0c", [CFAT_register; CFAT_offset], -( (* ULEB128 register ULEB128 offset *)fun avs -> (match avs with [CFAV_register r; CFAV_offset n] -> Some (DW_CFA_def_cfa( r, n)) | _ -> None ))); -("DW_CFA_def_cfa_register",Nat_big_num.of_int 0, natural_of_hex "0x0d", [CFAT_register], -( (* ULEB128 register *)fun avs -> (match avs with [CFAV_register r] -> Some (DW_CFA_def_cfa_register r) | _ -> None ))); -("DW_CFA_def_cfa_offset",Nat_big_num.of_int 0, natural_of_hex "0x0e", [CFAT_offset], -( (* ULEB128 offset *)fun avs -> (match avs with [CFAV_offset n] -> Some (DW_CFA_def_cfa_offset n) | _ -> None ))); -("DW_CFA_def_cfa_expression",Nat_big_num.of_int 0, natural_of_hex "0x0f", [CFAT_block], -( (* BLOCK *)fun avs -> (match avs with [CFAV_block b] -> Some (DW_CFA_def_cfa_expression b) | _ -> None ))); -("DW_CFA_expression",Nat_big_num.of_int 0, natural_of_hex "0x10", [CFAT_register; CFAT_block], -( (* ULEB128 register BLOCK *)fun avs -> (match avs with [CFAV_register r; CFAV_block b] -> Some (DW_CFA_expression( r, b)) | _ -> None ))); -("DW_CFA_offset_extended_sf",Nat_big_num.of_int 0, natural_of_hex "0x11", [CFAT_register; CFAT_sfoffset], -( (* ULEB128 register SLEB128 offset *)fun avs -> (match avs with [CFAV_register r; CFAV_sfoffset i] -> Some (DW_CFA_offset_extended_sf( r, i)) | _ -> None ))); -("DW_CFA_def_cfa_sf",Nat_big_num.of_int 0, natural_of_hex "0x12", [CFAT_register; CFAT_sfoffset], -( (* ULEB128 register SLEB128 offset *)fun avs -> (match avs with [CFAV_register r; CFAV_sfoffset i] -> Some (DW_CFA_def_cfa_sf( r, i)) | _ -> None ))); -("DW_CFA_def_cfa_offset_sf",Nat_big_num.of_int 0, natural_of_hex "0x13", [CFAT_sfoffset], -( (* SLEB128 offset *)fun avs -> (match avs with [CFAV_sfoffset i] -> Some (DW_CFA_def_cfa_offset_sf i) | _ -> None ))); -("DW_CFA_val_offset",Nat_big_num.of_int 0, natural_of_hex "0x14", [CFAT_register; CFAT_offset], -( (* ULEB128 ULEB128 *)fun avs -> (match avs with [CFAV_register r; CFAV_offset n] -> Some (DW_CFA_val_offset( r, n)) | _ -> None ))); -("DW_CFA_val_offset_sf",Nat_big_num.of_int 0, natural_of_hex "0x15", [CFAT_register; CFAT_sfoffset], -( (* ULEB128 SLEB128 *)fun avs -> (match avs with [CFAV_register r; CFAV_sfoffset i] -> Some (DW_CFA_val_offset_sf( r, i)) | _ -> None ))); -("DW_CFA_val_expression",Nat_big_num.of_int 0, natural_of_hex "0x16", [CFAT_register; CFAT_block], -( (* ULEB128 BLOCK *)fun avs -> (match avs with [CFAV_register r; CFAV_block b] -> Some (DW_CFA_val_expression( r, b)) | _ -> None ))) -]) - -(* -("DW_CFA_lo_user", 0, natural_of_hex "0x1c", []); (* *) -("DW_CFA_hi_user", 0, natural_of_hex "0x3f", []); (* *) -*) - - -(* line number encodings *) - -let line_number_standard_encodings:(string*Nat_big_num.num*(line_number_argument_type)list*((line_number_argument_value)list ->(line_number_operation)option))list= ([ - ("DW_LNS_copy" , natural_of_hex "0x01", [ ], - (fun lnvs -> (match lnvs with [] -> Some DW_LNS_copy | _ -> None ))); - ("DW_LNS_advance_pc" , natural_of_hex "0x02", [LNAT_ULEB128 ], - (fun lnvs -> (match lnvs with [LNAV_ULEB128 n] -> Some (DW_LNS_advance_pc n) | _ -> None ))); - ("DW_LNS_advance_line" , natural_of_hex "0x03", [LNAT_SLEB128 ], - (fun lnvs -> (match lnvs with [LNAV_SLEB128 i] -> Some (DW_LNS_advance_line i) | _ -> None ))); - ("DW_LNS_set_file" , natural_of_hex "0x04", [LNAT_ULEB128 ], - (fun lnvs -> (match lnvs with [LNAV_ULEB128 n] -> Some (DW_LNS_set_file n) | _ -> None ))); - ("DW_LNS_set_column" , natural_of_hex "0x05", [LNAT_ULEB128 ], - (fun lnvs -> (match lnvs with [LNAV_ULEB128 n] -> Some (DW_LNS_set_column n) | _ -> None ))); - ("DW_LNS_negate_stmt" , natural_of_hex "0x06", [ ], - (fun lnvs -> (match lnvs with [] -> Some (DW_LNS_negate_stmt) | _ -> None ))); - ("DW_LNS_set_basic_block" , natural_of_hex "0x07", [ ], - (fun lnvs -> (match lnvs with [] -> Some (DW_LNS_set_basic_block) | _ -> None ))); - ("DW_LNS_const_add_pc" , natural_of_hex "0x08", [ ], - (fun lnvs -> (match lnvs with [] -> Some (DW_LNS_const_add_pc) | _ -> None ))); - ("DW_LNS_fixed_advance_pc" , natural_of_hex "0x09", [LNAT_uint16 ], - (fun lnvs -> (match lnvs with [LNAV_uint16 n] -> Some (DW_LNS_fixed_advance_pc n) | _ -> None ))); - ("DW_LNS_set_prologue_end" , natural_of_hex "0x0a", [ ], -(fun lnvs -> (match lnvs with [] -> Some (DW_LNS_set_prologue_end) | _ -> None ))); - ("DW_LNS_set_epilogue_begin" , natural_of_hex "0x0b", [ ], -(fun lnvs -> (match lnvs with [] -> Some (DW_LNS_set_epilogue_begin) | _ -> None ))); - ("DW_LNS_set_isa" , natural_of_hex "0x0c", [LNAT_ULEB128 ], - (fun lnvs -> (match lnvs with [LNAV_ULEB128 n] -> Some (DW_LNS_set_isa n) | _ -> None ))) -]) - -let line_number_extended_encodings:(string*Nat_big_num.num*(line_number_argument_type)list*((line_number_argument_value)list ->(line_number_operation)option))list= ([ - ("DW_LNE_end_sequence" , natural_of_hex "0x01", [], - (fun lnvs -> (match lnvs with [] -> Some (DW_LNE_end_sequence) | _ -> None ))); - ("DW_LNE_set_address" , natural_of_hex "0x02", [LNAT_address], - (fun lnvs -> (match lnvs with [LNAV_address n] -> Some (DW_LNE_set_address n) | _ -> None ))); - ("DW_LNE_define_file" , natural_of_hex "0x03", [LNAT_string; LNAT_ULEB128; LNAT_ULEB128; LNAT_ULEB128], - (fun lnvs -> (match lnvs with [LNAV_string s; LNAV_ULEB128 n1; LNAV_ULEB128 n2; LNAV_ULEB128 n3] -> Some (DW_LNE_define_file( s, n1, n2, n3)) | _ -> None ))); - ("DW_LNE_set_discriminator" , natural_of_hex "0x04", [LNAT_ULEB128], - (fun lnvs -> (match lnvs with [LNAV_ULEB128 n] -> Some (DW_LNE_set_discriminator n) | _ -> None ))) (* new in Dwarf 4*) -]) - - -(* -(DW_LNE_lo_user , natural_of_hex "0x80", "DW_LNE_lo_user"); -(DW_LNE_hi_user , natural_of_hex "0xff", "DW_LNE_hi_user"); -*) - - - -(* booleans encoded as a single byte containing the value 0 for âfalse,â and a non-zero value for âtrue.â *) - - -(** ************************************************************ *) -(** ** more missing pervasives and bits *********************** *) -(** ************************************************************ *) - - -(* quick hacky workaround: this is in String.lem, in src_lem_library, but the linker doesn't find it *) -(*val myconcat : string -> list string -> string*) -let rec myconcat sep ss:string= - ((match ss with - | [] -> "" - | s :: ss' -> - (match ss' with - | [] -> s - | _ -> s ^ (sep ^ myconcat sep ss') - ) - )) - -(*val myhead : forall 'a. list 'a -> 'a*) -let myhead l:'a= ((match l with | x::xs -> x | [] -> failwith "myhead of empty list" )) - - -(*val myfindNonPure : forall 'a. ('a -> bool) -> list 'a -> 'a*) -let myfindNonPure p0 l:'a= ((match (Lem_list.list_find_opt p0 l) with - | Some e -> e - | None -> failwith "myfindNonPure" -)) - -(*val myfindmaybe : forall 'a 'b. ('a -> maybe 'b) -> list 'a -> maybe 'b*) -let rec myfindmaybe f xs:'b option= - ((match xs with - | [] -> None - | x::xs' -> (match f x with Some y -> Some y | None -> myfindmaybe f xs' ) - )) - -(*val myfind : forall 'a. ('a -> bool) -> list 'a -> maybe 'a*) -let rec myfind f xs:'a option= - ((match xs with - | [] -> None - | x::xs' -> (match f x with true -> Some x | false -> myfind f xs' ) - )) - -(*val myfiltermaybe : forall 'a 'b. ('a -> maybe 'b) -> list 'a -> list 'b*) -let rec myfiltermaybe f xs:'b list= - ((match xs with - | [] -> [] - | x::xs' -> (match f x with Some y -> y::myfiltermaybe f xs'| None -> myfiltermaybe f xs' ) - )) - - - -(*val bytes_of_natural: endianness -> natural (*size*) -> natural (*value*) -> list byte*) -let bytes_of_natural en size2 n:(char)list= - (if Nat_big_num.equal size2(Nat_big_num.of_int 8) then - bytes_of_elf64_xword en (Uint64.of_string (Nat_big_num.to_string n)) - else if Nat_big_num.equal size2(Nat_big_num.of_int 4) then - bytes_of_elf32_word en (Uint32.of_string (Nat_big_num.to_string n)) - else - failwith "bytes_of_natural given size that is not 4 or 8") - -(* TODO: generalise *) -(*val natural_of_bytes: endianness -> list byte -> natural*) -let natural_of_bytes en bs:Nat_big_num.num= - ((match bs with - | b0::b1::b2::b3::b4::b5::b6::b7::[] -> - let v = (if en=Little then - Nat_big_num.add (Nat_big_num.add (Nat_big_num.add (Nat_big_num.add - (natural_of_byte b0)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b1)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b2)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b3))) (Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))( Nat_big_num.add (Nat_big_num.add (Nat_big_num.add(natural_of_byte b4)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b5)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b6)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b7)))) - else - Nat_big_num.add (Nat_big_num.add (Nat_big_num.add (Nat_big_num.add -(natural_of_byte b7)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b6)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b5)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b4))) (Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))( Nat_big_num.add (Nat_big_num.add (Nat_big_num.add(natural_of_byte b3)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b2)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b1)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b0))))) - in - v - | b0::b1::b2::b3::[] -> - let v = (if en=Little then Nat_big_num.add (Nat_big_num.add (Nat_big_num.add - (natural_of_byte b0)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b1)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b2)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b3)) - else Nat_big_num.add (Nat_big_num.add (Nat_big_num.add -(natural_of_byte b3)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b2)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b1)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b0))) - - in - v - | b0::b1::[] -> - let v = (if en=Little then Nat_big_num.add - (natural_of_byte b0)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b1)) - else Nat_big_num.add -(natural_of_byte b1)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b0))) - - in - v - | b0::[] -> - natural_of_byte b0 - | _ -> failwith "natural_of_bytes given not-8/4/2/1 bytes" - )) - - -(*val bigunionListMap : forall 'a 'b. SetType 'b => ('a -> set 'b) -> list 'a -> set 'b*) -let rec bigunionListMap dict_Basic_classes_SetType_b f xs:'b Pset.set= - ((match xs with - | [] ->(Pset.from_list - dict_Basic_classes_SetType_b.setElemCompare_method []) - | x::xs' -> Pset.(union) (f x) (bigunionListMap - dict_Basic_classes_SetType_b f xs') - )) - -let rec mytake' (n:Nat_big_num.num) acc xs:('a list*'a list)option= - ( - if(Nat_big_num.equal n (Nat_big_num.of_int 0)) then - (Some (List.rev acc, xs)) else - ((match xs with - [] -> None - | x::xs' -> mytake' (Nat_big_num.sub_nat n (Nat_big_num.of_int 1)) - (x :: acc) xs' - ))) - -(*val mytake : forall 'a. natural -> (list 'a) -> maybe (list 'a * list 'a)*) -let mytake n xs:('a list*'a list)option= (mytake' n [] xs) - -(*val mynth : forall 'a. natural -> (list 'a) -> maybe 'a*) -let rec mynth (n:Nat_big_num.num) xs:'a option= - ( (*Assert_extra.failwith "mynth"*) - if(Nat_big_num.equal n (Nat_big_num.of_int 0)) then - ((match xs with x::xs' -> Some x | [] -> None )) else - ((match xs with - x::xs' -> mynth (Nat_big_num.sub_nat n (Nat_big_num.of_int 1)) xs' - ))) - - -(** basic pretty printing *) - -let pphex n:string= ("0x" ^ unsafe_hex_string_of_natural( 0) n) - -let ppbytes dict_Show_Show_a xs:string= (string_of_list - instance_Show_Show_string_dict (Lem_list.map (fun x -> - dict_Show_Show_a.show_method x) xs)) - -let rec ppbytes2 dict_Show_Show_a n xs:string= ((match xs with | [] -> "" | x::xs' -> "<"^(pphex n^("> "^( - dict_Show_Show_a.show_method x^("\n"^ppbytes2 dict_Show_Show_a (Nat_big_num.add n(Nat_big_num.of_int 1)) xs')))) )) - -(* workaround: from String *) -(*val mytoString : list char -> string*) - -let string_of_bytes bs:string= (Xstring.implode (Lem_list.map (fun x-> x) bs)) - - -let just_one s xs:'a= - ((match xs with - | [] -> failwith ("no " ^ s) - | x1::x2::_ -> failwith ("more than one " ^ s) - | [x] -> x - )) - - - - -let max_address (as': Nat_big_num.num) : Nat_big_num.num= - ( - if(Nat_big_num.equal as' (Nat_big_num.of_int 4)) then - (natural_of_hex "0xffffffff") else - ( - if(Nat_big_num.equal as' (Nat_big_num.of_int 8)) then - (natural_of_hex "0xffffffffffffffff") else - (failwith "max_address size not 4 or 8"))) - - -(** lookup of encodings *) - -(*val lookup_Ab_b : forall 'a 'b. Eq 'a => 'a -> list ('a * 'b) -> maybe 'b*) -let rec lookup_Ab_b dict_Basic_classes_Eq_a x0 xys:'b option= - ((match xys with - | [] -> None - | (x,y)::xys' -> if - dict_Basic_classes_Eq_a.isEqual_method x x0 then Some y else lookup_Ab_b - dict_Basic_classes_Eq_a x0 xys' - )) - -(*val lookup_aB_a : forall 'a 'b. Eq 'b => 'b -> list ('a * 'b) -> maybe 'a*) -let rec lookup_aB_a dict_Basic_classes_Eq_b y0 xys:'a option= - ((match xys with - | [] -> None - | (x,y)::xys' -> if - dict_Basic_classes_Eq_b.isEqual_method y y0 then Some x else lookup_aB_a - dict_Basic_classes_Eq_b y0 xys' - )) - - -(*val lookup_aBc_a : forall 'a 'b 'c. Eq 'b => 'b -> list ('a * 'b * 'c) -> maybe 'a*) -let rec lookup_aBc_a dict_Basic_classes_Eq_b y0 xyzs:'a option= - ((match xyzs with - | [] -> None - | (x,y,_)::xyzs' -> if - dict_Basic_classes_Eq_b.isEqual_method y y0 then Some x else lookup_aBc_a - dict_Basic_classes_Eq_b y0 xyzs' - )) - -(*val lookup_aBc_ac : forall 'a 'b 'c. Eq 'b => 'b -> list ('a * 'b * 'c) -> maybe ('a*'c)*) -let rec lookup_aBc_ac dict_Basic_classes_Eq_b y0 xyzs:('a*'c)option= - ((match xyzs with - | [] -> None - | (x,y,z)::xyzs' -> if - dict_Basic_classes_Eq_b.isEqual_method y y0 then Some (x,z) else lookup_aBc_ac - dict_Basic_classes_Eq_b y0 xyzs' - )) - -(*val lookup_Abc_b : forall 'a 'b 'c. Eq 'a => 'a -> list ('a * 'b * 'c) -> maybe 'b*) -let rec lookup_Abc_b dict_Basic_classes_Eq_a x0 xyzs:'b option= - ((match xyzs with - | [] -> None - | (x,y,_)::xyzs' -> if - dict_Basic_classes_Eq_a.isEqual_method x x0 then Some y else lookup_Abc_b - dict_Basic_classes_Eq_a x0 xyzs' - )) - - - -(*val lookup_aBcd_a : forall 'a 'b 'c 'd. Eq 'b => 'b -> list ('a * 'b * 'c * 'd) -> maybe 'a*) -let rec lookup_aBcd_a dict_Basic_classes_Eq_b y0 xyzws:'a option= - ((match xyzws with - | [] -> None - | (x,y,_,_)::xyzws' -> if - dict_Basic_classes_Eq_b.isEqual_method y y0 then Some x else lookup_aBcd_a - dict_Basic_classes_Eq_b y0 xyzws' - )) - -(*val lookup_aBcd_acd : forall 'a 'b 'c 'd. Eq 'b => 'b -> list ('a * 'b * 'c * 'd) -> maybe ('a * 'c * 'd)*) -let rec lookup_aBcd_acd dict_Basic_classes_Eq_b y0 xyzws:('a*'c*'d)option= - ((match xyzws with - | [] -> None - | (x,y,z,w)::xyzws' -> if - dict_Basic_classes_Eq_b.isEqual_method y y0 then Some (x,z,w) else lookup_aBcd_acd - dict_Basic_classes_Eq_b y0 xyzws' - )) - -(*val lookup_abCde_de : forall 'a 'b 'c 'd 'e. Eq 'c => 'c -> list ('a * 'b * 'c * 'd * 'e) -> maybe ('d * 'e)*) -let rec lookup_abCde_de dict_Basic_classes_Eq_c z0 xyzwus:('d*'e)option= - ((match xyzwus with - | [] -> None - | (x,y,z,w,u)::xyzwus' -> if - dict_Basic_classes_Eq_c.isEqual_method z z0 then Some (w,u) else lookup_abCde_de - dict_Basic_classes_Eq_c z0 xyzwus' - )) - - -let pp_maybe ppf n:string= ((match ppf n with Some s -> s | None -> "encoding not found: " ^ pphex n )) - -let pp_tag_encoding n:string= (pp_maybe (fun n -> lookup_aB_a - instance_Basic_classes_Eq_Num_natural_dict n tag_encodings) n) -let pp_attribute_encoding n:string= (pp_maybe (fun n -> lookup_aBc_a - instance_Basic_classes_Eq_Num_natural_dict n attribute_encodings) n) -let pp_attribute_form_encoding n:string= (pp_maybe (fun n -> lookup_aBc_a - instance_Basic_classes_Eq_Num_natural_dict n attribute_form_encodings) n) -let pp_operation_encoding n:string= (pp_maybe (fun n -> lookup_aBcd_a - instance_Basic_classes_Eq_Num_natural_dict n operation_encodings) n) - -let tag_encode (s: string) : Nat_big_num.num= - ((match lookup_Ab_b - instance_Basic_classes_Eq_string_dict s tag_encodings with - | Some n -> n - | None -> failwith "attribute_encode" - )) - - -let attribute_encode (s: string) : Nat_big_num.num= - ((match lookup_Abc_b - instance_Basic_classes_Eq_string_dict s attribute_encodings with - | Some n -> n - | None -> failwith "attribute_encode" - )) - -let attribute_form_encode (s: string) : Nat_big_num.num= - ((match lookup_Abc_b - instance_Basic_classes_Eq_string_dict s attribute_form_encodings with - | Some n -> n - | None -> failwith "attribute_form_encode" - )) - - - -(** ************************************************************ *) -(** ** parser combinators and primitives ********************* *) -(** ************************************************************ *) - -(* parsing combinators *) - -type parse_context = { pc_bytes: char list; pc_offset: Nat_big_num.num } - -type 'a parse_result = - | PR_success of 'a * parse_context - | PR_fail of string * parse_context - -type 'a parser = parse_context -> 'a parse_result - -let pp_parse_context pc:string= ("pc_offset = " ^ pphex pc.pc_offset) - -let pp_parse_fail s pc:string= - ("Parse fail\n" ^ (s ^ (" at " ^ (pp_parse_context pc ^ "\n")))) - -let pp_parse_result ppa pr:string= - ((match pr with - | PR_success( x, pc) -> "Parse success\n" ^ (ppa x ^ ("\n" ^ (pp_parse_context pc ^ "\n"))) - | PR_fail( s, pc) -> pp_parse_fail s pc - )) - -(* [(>>=)] should be the monadic binding function for [parse_result]. *) -(* but there's a type clash if we use >>=, and lem seems to output bad ocaml for >>>=. So we just use a non-infix version for now *) - -(*val pr_bind : forall 'a 'b. parse_result 'a -> ('a -> parser 'b) -> parse_result 'b*) -let pr_bind x f:'b parse_result= - ((match x with - | PR_success( v, pc) -> f v pc - | PR_fail( err, pc) -> PR_fail( err, pc) - )) - -(*val pr_return : forall 'a. 'a -> (parser 'a)*) -let pr_return x pc:'a parse_result= (PR_success( x, pc)) - -(*val pr_map : forall 'a 'b. ('a -> 'b) -> parse_result 'a -> parse_result 'b*) -let pr_map f x:'b parse_result= - ((match x with - | PR_success( v, pc) -> PR_success( (f v), pc) - | PR_fail( err, pc) -> PR_fail( err, pc) - )) - -(*val pr_map2 : forall 'a 'b. ('a -> 'b) -> (parser 'a) -> (parser 'b)*) -let pr_map2 f p:parse_context ->'b parse_result= (fun pc -> pr_map f (p pc)) - -(*val pr_post_map1 : forall 'a 'b. (parse_result 'a) -> ('a -> 'b) -> (parse_result 'b)*) -let pr_post_map1 x f:'b parse_result= (pr_map f x) - -(* -val pr_post_map : forall 'a 'b 'c. ('c -> parse_result 'a) -> ('a -> 'b) -> ('c -> parse_result 'b) -let pr_post_map g f = fun x -> pr_map f (g x) -*) -(*val pr_post_map : forall 'a 'b. (parser 'a) -> ('a -> 'b) -> (parser 'b)*) -let pr_post_map p f:parse_context ->'b parse_result= (fun (pc: parse_context) -> pr_map f (p pc)) - - -(*val pr_with_pos : forall 'a. (parser 'a) -> (parser (natural * 'a))*) -let pr_with_pos p:parse_context ->(Nat_big_num.num*'a)parse_result= (fun pc -> pr_map (fun x -> (pc.pc_offset,x)) (p pc)) - - -(*val parse_pair : forall 'a 'b. (parser 'a) -> (parser 'b) -> (parser ('a * 'b))*) -let parse_pair p1 p2:parse_context ->('a*'b)parse_result= - (fun pc -> - let _ = (my_debug "pair ") in - pr_bind (p1 pc) (fun x pc' -> (match p2 pc' with - | PR_success( y, pc'') -> PR_success( (x,y), pc'') - | PR_fail( s, pc'') -> PR_fail( s, pc'') - ))) - -(*val parse_triple : forall 'a 'b 'c. (parser 'a) -> (parser 'b) -> (parser 'c) -> parser ('a * ('b * 'c))*) -let parse_triple p1 p2 p3:parse_context ->('a*('b*'c))parse_result= - (parse_pair p1 (parse_pair p2 p3)) - -(*val parse_quadruple : forall 'a 'b 'c 'd. (parser 'a) -> (parser 'b) -> (parser 'c) -> (parser 'd) -> parser ('a * ('b * ('c * 'd)))*) -let parse_quadruple p1 p2 p3 p4:parse_context ->('a*('b*('c*'d)))parse_result= - (parse_pair p1 (parse_pair p2 (parse_pair p3 p4))) - -(*val parse_pentuple : forall 'a 'b 'c 'd 'e. (parser 'a) -> (parser 'b) -> (parser 'c) -> (parser 'd) -> (parser 'e) -> parser ('a * ('b * ('c * ('d * 'e))))*) -let parse_pentuple p1 p2 p3 p4 p5:parse_context ->('a*('b*('c*('d*'e))))parse_result= - (parse_pair p1 (parse_pair p2 (parse_pair p3 (parse_pair p4 p5)))) - -(*val parse_sextuple : forall 'a 'b 'c 'd 'e 'f. (parser 'a) -> (parser 'b) -> (parser 'c) -> (parser 'd) -> (parser 'e) -> (parser 'f) -> parser ('a * ('b * ('c * ('d * ('e * 'f)))))*) -let parse_sextuple p1 p2 p3 p4 p5 p6:parse_context ->('a*('b*('c*('d*('e*'f)))))parse_result= - (parse_pair p1 (parse_pair p2 (parse_pair p3 (parse_pair p4 (parse_pair p5 p6))))) - -(*val parse_dependent_pair : forall 'a 'b. (parser 'a) -> ('a -> parser 'b) -> (parser ('a * 'b))*) -let parse_dependent_pair p1 p2:parse_context ->('a*'b)parse_result= - (fun pc -> - pr_bind (p1 pc) (fun x pc' -> (match p2 x pc' with - | PR_success( y, pc'') -> PR_success( (x,y), pc'') - | PR_fail( s, pc'') -> PR_fail( s, pc'') - ))) - -(*val parse_dependent : forall 'a 'b. (parser 'a) -> ('a -> parser 'b) -> (parser 'b)*) -let parse_dependent p1 p2:parse_context ->'b parse_result= - (fun pc -> - pr_bind (p1 pc) (fun x pc' -> p2 x pc')) - - - -(*val parse_list' : forall 'a. (parser (maybe 'a)) -> (list 'a -> parser (list 'a))*) -let rec parse_list' p1:'a list ->parse_context ->('a list)parse_result= - (fun acc pc -> let _ = (my_debug "list' ") in pr_bind (p1 pc) (fun mx pc' -> - (match mx with - | None -> PR_success( acc, pc') - | Some x -> parse_list' p1 (x :: acc) pc' - ))) - -(*val parse_list : forall 'a. (parser (maybe 'a)) -> (parser (list 'a))*) -let parse_list p1:parse_context ->('a list)parse_result= - (pr_post_map - (parse_list' p1 []) - (List.rev)) - -(*val parse_parser_list : forall 'a. (list (parser 'a)) -> (parser (list 'a))*) -let rec parse_parser_list ps:parse_context ->('a list)parse_result= - ((match ps with - | [] -> pr_return [] - | p::ps' -> - (fun pc -> pr_bind (p pc) (fun x pc' -> - (match parse_parser_list ps' pc' with - | PR_success( xs, pc'') -> PR_success( (x::xs), pc'') - | PR_fail( s, pc'') -> PR_fail( s, pc'') - ))) - )) - -(*val parse_maybe : forall 'a. parser 'a -> parser (maybe 'a)*) -let parse_maybe p:parse_context ->('a option)parse_result= - (fun pc -> - (match pc.pc_bytes with - | [] -> pr_return None pc - | _ -> - (match p pc with - | PR_success( v, pc'') -> PR_success( (Some v), pc'') - | PR_fail( s, pc'') -> PR_fail( s, pc'') - ) - )) - -(*val parse_demaybe : forall 'a. string ->parser (maybe 'a) -> parser 'a*) -let parse_demaybe s p:parse_context ->'a parse_result= - (fun pc -> - (match p pc with - | PR_success( (Some v), pc'') -> PR_success( v, pc'') - | PR_success( (None), pc'') -> PR_fail( s, pc'') - | PR_fail( s, pc'') -> PR_fail( s, pc'') - - )) - - -(*val parse_restrict_length : forall 'a. natural -> parser 'a -> parser 'a*) -let parse_restrict_length n p:parse_context ->'a parse_result= - (fun pc -> - (match mytake n pc.pc_bytes with - | None -> failwith "parse_restrict_length not given enough bytes" - | Some (xs,ys) -> - let pc' = ({ pc_bytes = xs; pc_offset = (pc.pc_offset) }) in - p pc' - )) - - -(* parsing of basic types *) - - -let parse_n_bytes (n:Nat_big_num.num) : ( char list) parser= - (fun (pc:parse_context) -> - (match mytake n pc.pc_bytes with - | None -> PR_fail( ("parse_n_bytes n=" ^ pphex n), pc) - | Some (xs,bs) -> PR_success( xs, ({pc_bytes=bs; pc_offset= (Nat_big_num.add pc.pc_offset (Nat_big_num.of_int (List.length xs))) } )) - )) - -let rec mytakestring' acc xs:((char)list*(char)list)option= - ((match xs with - | [] -> None - | x::xs' -> if Nat_big_num.equal (natural_of_byte x)(Nat_big_num.of_int 0) then Some (List.rev acc, xs') else mytakestring' (x::acc) xs' - )) - -let parse_string : ( char list) parser= - (fun (pc:parse_context) -> - (match mytakestring' [] pc.pc_bytes with - | None -> PR_fail( "parse_string", pc) - | Some (xs,bs) -> PR_success( xs, ({pc_bytes=bs; pc_offset = (Nat_big_num.add (Nat_big_num.add pc.pc_offset (Nat_big_num.of_int (List.length xs))) (Nat_big_num.of_int( 1))) } )) - )) - -(* parse a null-terminated string; return Nothing if it is empty, Just s otherwise *) -let parse_non_empty_string : ( ( char list)option) parser= - (fun (pc:parse_context) -> - (match mytakestring' [] pc.pc_bytes with - | None -> PR_fail( "parse_string", pc) - | Some (xs,bs) -> - (*let _ = my_debug5 ("**" ^string_of_bytes xs ^ "**\n") in *) - let pc' = ({pc_bytes=bs; pc_offset = (Nat_big_num.add (Nat_big_num.add pc.pc_offset (Nat_big_num.of_int (List.length xs))) (Nat_big_num.of_int( 1))) } ) in - if (listEqualBy (=) xs []) then PR_success( (None), pc') - else PR_success( (Some xs), pc') - )) - - -let parse_uint8 : Nat_big_num.num parser= - (fun (pc:parse_context) -> - let _ = (my_debug "uint8 ") in - (match pc.pc_bytes with - | b0::bytes' -> - let v = (natural_of_byte b0) in - PR_success( v, ({ pc_bytes = bytes'; pc_offset = (Nat_big_num.add pc.pc_offset(Nat_big_num.of_int 1)) })) - | _ -> PR_fail( "parse_uint32 not given enough bytes", pc) - )) - -let parse_uint16 c : Nat_big_num.num parser= - (fun (pc:parse_context) -> - let _ = (my_debug "uint16 ") in - (match pc.pc_bytes with - | b0::b1::bytes' -> - let v = (if c.endianness=Little then Nat_big_num.add - (natural_of_byte b0)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b1)) - else Nat_big_num.add - (natural_of_byte b1)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b0))) in - PR_success( v, ({ pc_bytes = bytes'; pc_offset = (Nat_big_num.add pc.pc_offset(Nat_big_num.of_int 2)) })) - | _ -> PR_fail( "parse_uint32 not given enough bytes", pc) - )) - -let parse_uint32 c : Nat_big_num.num parser= - (fun (pc:parse_context) -> - let _ = (my_debug "uint32 ") in - (match pc.pc_bytes with - | b0::b1::b2::b3::bytes' -> - let v = (if c.endianness=Little then Nat_big_num.add (Nat_big_num.add (Nat_big_num.add - (natural_of_byte b0)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b1)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b2)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b3)) - else Nat_big_num.add (Nat_big_num.add (Nat_big_num.add - (natural_of_byte b3)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b2)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b1)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b0))) in - PR_success( v, ({ pc_bytes = bytes'; pc_offset = (Nat_big_num.add pc.pc_offset(Nat_big_num.of_int 4)) })) - | _ -> PR_fail( "parse_uint32 not given enough bytes", pc) - )) - -let parse_uint64 c : Nat_big_num.num parser= - (fun (pc:parse_context) -> - let _ = (my_debug "uint64 ") in - (match pc.pc_bytes with - | b0::b1::b2::b3::b4::b5::b6::b7::bytes' -> - let v = (if c.endianness=Little then - Nat_big_num.add (Nat_big_num.add (Nat_big_num.add (Nat_big_num.add - (natural_of_byte b0)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b1)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b2)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b3))) (Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))( Nat_big_num.add (Nat_big_num.add (Nat_big_num.add(natural_of_byte b4)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b5)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b6)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b7)))) - else - Nat_big_num.add (Nat_big_num.add (Nat_big_num.add (Nat_big_num.add -(natural_of_byte b7)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b6)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b5)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b4))) (Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))( Nat_big_num.add (Nat_big_num.add (Nat_big_num.add(natural_of_byte b3)(Nat_big_num.mul(Nat_big_num.of_int 256)(natural_of_byte b2)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(natural_of_byte b1)))(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(natural_of_byte b0))))) - in - PR_success( v, ({ pc_bytes = bytes'; pc_offset = (Nat_big_num.add pc.pc_offset(Nat_big_num.of_int 8)) })) - | _ -> PR_fail( "parse_uint64 not given enough bytes", pc) - )) - -let integerFromTwosComplementNatural (n:Nat_big_num.num) (half: Nat_big_num.num) (all:Nat_big_num.num) : Nat_big_num.num= - (if Nat_big_num.less n half then n else Nat_big_num.sub ( n) all) - -let partialTwosComplementNaturalFromInteger (i:Nat_big_num.num) (half: Nat_big_num.num) (all:Nat_big_num.num) : Nat_big_num.num= - (if Nat_big_num.greater_equal i(Nat_big_num.of_int 0) && Nat_big_num.less i ( half) then partialNaturalFromInteger i - else if Nat_big_num.greater_equal i (Nat_big_num.sub(Nat_big_num.of_int 0)( half)) && Nat_big_num.less i(Nat_big_num.of_int 0) then partialNaturalFromInteger ( Nat_big_num.add all i) - else failwith "partialTwosComplementNaturalFromInteger") - - -let parse_sint8 : Nat_big_num.num parser= - (pr_post_map (parse_uint8) (fun n -> integerFromTwosComplementNatural n(Nat_big_num.of_int 128)(Nat_big_num.of_int 256))) - -let parse_sint16 c : Nat_big_num.num parser= - (pr_post_map (parse_uint16 c) (fun n -> integerFromTwosComplementNatural n (Nat_big_num.mul(Nat_big_num.of_int 128)(Nat_big_num.of_int 256)) (Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256)))) - -let parse_sint32 c : Nat_big_num.num parser= - (pr_post_map (parse_uint32 c) (fun n -> integerFromTwosComplementNatural n (Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 128)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256)) (Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256)))) - -let parse_sint64 c : Nat_big_num.num parser= - (pr_post_map (parse_uint64 c) (fun n -> integerFromTwosComplementNatural n (Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 128)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256)) (Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.of_int 256)(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256))(Nat_big_num.of_int 256)))) - -let rec parse_ULEB128' (acc: Nat_big_num.num) (shift_factor: Nat_big_num.num) : Nat_big_num.num parser= - (fun (pc:parse_context) -> - let _ = (my_debug "ULEB128' ") in - (match pc.pc_bytes with - | b::bytes' -> - let n = (natural_of_byte b) in - let acc' = (Nat_big_num.add (Nat_big_num.mul (Nat_big_num.bitwise_and n(Nat_big_num.of_int 127)) shift_factor) acc) in - let finished = ( Nat_big_num.equal(Nat_big_num.bitwise_and n(Nat_big_num.of_int 128))(Nat_big_num.of_int 0)) in - let pc' = ({ pc_bytes = bytes'; pc_offset = (Nat_big_num.add pc.pc_offset(Nat_big_num.of_int 1)) }) in - if finished then - PR_success( acc', pc') - else - parse_ULEB128' acc' ( Nat_big_num.mul shift_factor(Nat_big_num.of_int 128)) pc' - | _ -> - PR_fail( "parse_ULEB128' not given enough bytes", pc) - )) - -let parse_ULEB128 : Nat_big_num.num parser= - (fun (pc:parse_context) -> - parse_ULEB128'(Nat_big_num.of_int 0)(Nat_big_num.of_int 1) pc) - -let rec parse_SLEB128' (acc: Nat_big_num.num) (shift_factor: Nat_big_num.num) : (bool * Nat_big_num.num * Nat_big_num.num) parser= - (fun (pc:parse_context) -> - let _ = (my_debug "SLEB128' ") in - (match pc.pc_bytes with - | b::bytes' -> - let n = (natural_of_byte b) in - let acc' = (Nat_big_num.add acc (Nat_big_num.mul (Nat_big_num.bitwise_and n(Nat_big_num.of_int 127)) shift_factor)) in - let shift_factor' = (Nat_big_num.mul shift_factor(Nat_big_num.of_int 128)) in - let finished = ( Nat_big_num.equal(Nat_big_num.bitwise_and n(Nat_big_num.of_int 128))(Nat_big_num.of_int 0)) in - let positive = ( Nat_big_num.equal(Nat_big_num.bitwise_and n(Nat_big_num.of_int 64))(Nat_big_num.of_int 0)) in - let pc' = ({ pc_bytes = bytes'; pc_offset = (Nat_big_num.add pc.pc_offset(Nat_big_num.of_int 1)) }) in - if finished then - PR_success( (positive, shift_factor', acc'), pc') - else - parse_SLEB128' acc' shift_factor' pc' - | _ -> - PR_fail( "parse_SLEB128' not given enough bytes", pc) - )) - -let parse_SLEB128 : Nat_big_num.num parser= - (pr_post_map (parse_SLEB128'(Nat_big_num.of_int 0)(Nat_big_num.of_int 1)) (fun (positive, shift_factor, acc) -> - if positive then acc else Nat_big_num.sub ( acc) ( shift_factor))) - -let parse_nonzero_ULEB128_pair : ( (Nat_big_num.num*Nat_big_num.num)option) parser= - (let _ = (my_debug "nonzero_ULEB128_pair ") in - pr_post_map - (parse_pair parse_ULEB128 parse_ULEB128) - (fun (n1,n2) -> if Nat_big_num.equal n1(Nat_big_num.of_int 0) &&Nat_big_num.equal n2(Nat_big_num.of_int 0) then None else Some (n1,n2))) - -let parse_zero_terminated_ULEB128_pair_list : ( (Nat_big_num.num*Nat_big_num.num)list) parser= - (let _ = (my_debug "zero_terminated_ULEB128_pair_list ") in - parse_list parse_nonzero_ULEB128_pair) - -let parse_uintDwarfN c (df: dwarf_format) : Nat_big_num.num parser= - ((match df with - | Dwarf32 -> (parse_uint32 c) - | Dwarf64 -> (parse_uint64 c) - )) - -let parse_uint_address_size c (as': Nat_big_num.num) : Nat_big_num.num parser= - ( - if(Nat_big_num.equal as' (Nat_big_num.of_int 4)) then (parse_uint32 c) else - ( - if(Nat_big_num.equal as' (Nat_big_num.of_int 8)) then (parse_uint64 c) - else - (failwith ("cuh_address_size not 4 or 8: " ^ Nat_big_num.to_string as')))) - -let parse_uint_segment_selector_size c (ss: Nat_big_num.num) : ( Nat_big_num.num option) parser= - ( - if(Nat_big_num.equal ss (Nat_big_num.of_int 0)) then (pr_return None) else - ( - if(Nat_big_num.equal ss (Nat_big_num.of_int 1)) then - (pr_post_map (parse_uint8) (fun n -> Some n)) else - ( - if(Nat_big_num.equal ss (Nat_big_num.of_int 2)) then - (pr_post_map (parse_uint16 c) (fun n -> Some n)) else - ( - if(Nat_big_num.equal ss (Nat_big_num.of_int 4)) then - (pr_post_map (parse_uint32 c) (fun n -> Some n)) else - ( - if(Nat_big_num.equal ss (Nat_big_num.of_int 8)) then - (pr_post_map (parse_uint64 c) (fun n -> Some n)) else - (failwith "cuh_address_size not 4 or 8")))))) - - - -(** ************************************************************ *) -(** ** parsing and pretty printing of .debug_* sections ****** *) -(** ************************************************************ *) - - -(** abbreviations table: pp and parsing *) - -let pp_abbreviation_declaration (x:abbreviation_declaration):string= - (" " - ^ (Nat_big_num.to_string x.ad_abbreviation_code ^ (" " - ^ (pp_tag_encoding x.ad_tag ^ (" " - ^ ((if x.ad_has_children then "[has children]" else "[no children]") - ^ ("\n" -(* ^ " "^show (List.length x.ad_attribute_specifications) ^ " attributes\n"*) - ^ myconcat "" - (Lem_list.map - (fun (n1,n2) -> - " " ^ (pp_attribute_encoding n1 ^ (" " ^ (pp_attribute_form_encoding n2 ^ "\n")))) - x.ad_attribute_specifications)))))))) - -let pp_abbreviations_table (x:abbreviations_table):string= - (myconcat "" (Lem_list.map (pp_abbreviation_declaration) x)) - -let parse_abbreviation_declaration c : ( abbreviation_declaration option) parser= - (fun (pc: parse_context) -> - pr_bind (parse_ULEB128 pc) (fun n1 pc' -> - if Nat_big_num.equal n1(Nat_big_num.of_int 0) then - PR_success( None, pc') - else - pr_bind (parse_ULEB128 pc') (fun n2 pc'' -> - pr_bind (parse_uint8 pc'') (fun c pc''' -> - pr_post_map1 - (parse_zero_terminated_ULEB128_pair_list pc''') - (fun l -> - Some ( let ad = - ({ - ad_abbreviation_code = n1; - ad_tag = n2; - ad_has_children = (not (Nat_big_num.equal c(Nat_big_num.of_int 0))); - ad_attribute_specifications = l; - }) in let _ = (my_debug2 (pp_abbreviation_declaration ad)) in ad) - ))))) - -let parse_abbreviations_table c:parse_context ->((abbreviation_declaration)list)parse_result= - (parse_list (parse_abbreviation_declaration c)) - - -(** debug_str entry *) - -(*val mydrop : forall 'a. natural -> list 'a -> maybe (list 'a)*) -let rec mydrop n xs:('a list)option= - (if Nat_big_num.equal n(Nat_big_num.of_int 0) then Some xs - else - (match xs with - | x::xs' -> mydrop (Nat_big_num.sub_nat n(Nat_big_num.of_int 1)) xs' - | [] -> None - )) - -let rec null_terminated_list (acc: char list) (xs: char list) : char list= - ((match xs with - | [] -> List.rev acc (* TODO: flag failure? *) - | x::xs' -> if Nat_big_num.equal (natural_of_byte x)(Nat_big_num.of_int 0) then List.rev acc else null_terminated_list (x::acc) xs' - )) - -let pp_debug_str_entry (str: char list) (n: Nat_big_num.num):string= - ((match mydrop n str with - | None -> "strp beyond .debug_str extent" - | Some xs -> string_of_bytes (null_terminated_list [] xs) - )) - -(** operations: pp and parsing *) - -let pp_operation_argument_value (oav:operation_argument_value) : string= - ((match oav with - | OAV_natural n -> pphex n - | OAV_integer n -> Nat_big_num.to_string n - | OAV_block( n, bs) -> pphex n ^ (" " ^ ppbytes - instance_Show_Show_Missing_pervasives_byte_dict bs) - )) - -let pp_operation_semantics (os: operation_semantics) : string= - ((match os with - | OpSem_lit -> "OpSem_lit" - | OpSem_deref -> "OpSem_deref" - | OpSem_stack _ -> "OpSem_stack ..." - | OpSem_not_supported -> "OpSem_not_supported" - | OpSem_binary _ -> "OpSem_binary ..." - | OpSem_unary _ -> "OpSem_unary ..." - | OpSem_opcode_lit _ -> "OpSem_opcode_lit ..." - | OpSem_reg -> "OpSem_reg" - | OpSem_breg -> "OpSem_breg" - | OpSem_bregx -> "OpSem_bregx" - | OpSem_fbreg -> "OpSem_fbreg" - | OpSem_deref_size -> "OpSem_deref_size" - | OpSem_nop -> "OpSem_nop" - | OpSem_piece -> "OpSem_piece" - | OpSem_bit_piece -> "OpSem_bitpiece" - | OpSem_implicit_value -> "OpSem_implicit_value" - | OpSem_stack_value -> "OpSem_stack_value" - | OpSem_call_frame_cfa -> "OpSem_call_frame_cfa" - )) - -let pp_operation (op: operation) : string= - (op.op_string ^ (" " ^ (myconcat " " (Lem_list.map pp_operation_argument_value op.op_argument_values) ^ (" (" ^ (pp_operation_semantics op.op_semantics ^ ")"))))) - -let pp_operations (ops: operation list) : string= - (myconcat "; " (Lem_list.map pp_operation ops)) - -(*val parser_of_operation_argument_type : p_context -> compilation_unit_header -> operation_argument_type -> (parser operation_argument_value)*) -let parser_of_operation_argument_type c cuh oat:parse_context ->(operation_argument_value)parse_result= - ((match oat with - | OAT_addr -> - pr_map2 (fun n -> OAV_natural n) (parse_uint_address_size c cuh.cuh_address_size) - | OAT_dwarf_format_t -> - pr_map2 (fun n -> OAV_natural n) (parse_uintDwarfN c cuh.cuh_dwarf_format) - | OAT_uint8 -> pr_map2 (fun n -> OAV_natural n) (parse_uint8) - | OAT_uint16 -> pr_map2 (fun n -> OAV_natural n) (parse_uint16 c) - | OAT_uint32 -> pr_map2 (fun n -> OAV_natural n) (parse_uint32 c) - | OAT_uint64 -> pr_map2 (fun n -> OAV_natural n) (parse_uint64 c) - | OAT_sint8 -> pr_map2 (fun n -> OAV_integer n) (parse_sint8) - | OAT_sint16 -> pr_map2 (fun n -> OAV_integer n) (parse_sint16 c) - | OAT_sint32 -> pr_map2 (fun n -> OAV_integer n) (parse_sint32 c) - | OAT_sint64 -> pr_map2 (fun n -> OAV_integer n) (parse_sint64 c) - | OAT_ULEB128 -> pr_map2 (fun n -> OAV_natural n) parse_ULEB128 - | OAT_SLEB128 -> pr_map2 (fun n -> OAV_integer n) parse_SLEB128 - | OAT_block -> - (fun pc -> pr_bind (parse_ULEB128 pc) (fun n pc' -> - pr_map (fun bs -> OAV_block( n, bs)) (parse_n_bytes n pc'))) - )) - -(*val parse_operation : p_context -> compilation_unit_header -> parser (maybe operation)*) -let parse_operation c cuh pc:((operation)option)parse_result= - ((match parse_uint8 pc with - | PR_fail( s, pc') -> PR_success( None, pc) - | PR_success( code, pc') -> - (match lookup_aBcd_acd - instance_Basic_classes_Eq_Num_natural_dict code operation_encodings with - | None -> PR_fail( ("encoding not found: " ^ pphex code), pc) - | Some (s,oats,opsem) -> - let ps = (Lem_list.map (parser_of_operation_argument_type c cuh) oats) in - (pr_post_map - (parse_parser_list ps) - (fun oavs -> Some { op_code = code; op_string = s; op_argument_values = oavs; op_semantics = opsem }) - ) - pc' - ) - )) - -(*val parse_operations : p_context -> compilation_unit_header -> parser (list operation)*) -let parse_operations c cuh:parse_context ->((operation)list)parse_result= - (parse_list (parse_operation c cuh)) - -(*val parse_and_pp_operations : p_context -> compilation_unit_header -> list byte -> string*) -let parse_and_pp_operations c cuh bs:string= - (let pc = ({pc_bytes = bs; pc_offset =(Nat_big_num.of_int 0) }) in - (match parse_operations c cuh pc with - | PR_fail( s, pc') -> "parse_operations fail: " ^ pp_parse_fail s pc' - | PR_success( ops, pc') -> - pp_operations ops - ^ (if not ((listEqualBy (=) pc'.pc_bytes [])) then " Warning: extra non-parsed bytes" else "") - )) - - -(** attribute values: pp and parsing *) - -(*val pp_attribute_value : p_context -> compilation_unit_header -> list byte -> natural (*attribute tag*) -> attribute_value -> string*) -let pp_attribute_value c cuh str at av:string= - ((match av with - | AV_addr x -> "AV_addr " ^ pphex x - | AV_block( n, bs) -> "AV_block " ^ (Nat_big_num.to_string n ^ (" " ^ (ppbytes - instance_Show_Show_Missing_pervasives_byte_dict bs - ^ (if Nat_big_num.equal at (attribute_encode "DW_AT_location") then " " ^ parse_and_pp_operations c cuh bs else "")))) - | AV_constantN( n, bs) -> "AV_constantN " ^ (Nat_big_num.to_string n ^ (" " ^ ppbytes - instance_Show_Show_Missing_pervasives_byte_dict bs)) - | AV_constant_SLEB128 i -> "AV_constant_SLEB128 " ^ Nat_big_num.to_string i - | AV_constant_ULEB128 n -> "AV_constant_ULEB128 " ^ Nat_big_num.to_string n - | AV_exprloc( n, bs) -> "AV_exprloc " ^ (Nat_big_num.to_string n ^ (" " ^ (ppbytes - instance_Show_Show_Missing_pervasives_byte_dict bs - ^ (" " ^ parse_and_pp_operations c cuh bs)))) - | AV_flag b -> "AV_flag " ^ string_of_bool b - | AV_ref n -> "AV_ref " ^ pphex n - | AV_ref_addr n -> "AV_ref_addr " ^ pphex n - | AV_ref_sig8 n -> "AV_ref_sig8 " ^ pphex n - | AV_sec_offset n -> "AV_sec_offset " ^ pphex n - | AV_string bs -> string_of_bytes bs - | AV_strp n -> "AV_sec_offset " ^ (pphex n ^ (" " - ^ pp_debug_str_entry str n)) - )) - - -(*val parser_of_attribute_form_non_indirect : p_context -> compilation_unit_header -> natural -> parser attribute_value*) -let parser_of_attribute_form_non_indirect c cuh n:parse_context ->(attribute_value)parse_result= -( -(* address*)if Nat_big_num.equal n (attribute_form_encode "DW_FORM_addr") then - pr_map2 (fun n -> AV_addr n) (parse_uint_address_size c cuh.cuh_address_size) -(* block *) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_block1") then - (fun pc -> pr_bind (parse_uint8 pc) (fun n pc' -> - pr_map (fun bs -> AV_block( n, bs)) (parse_n_bytes n pc'))) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_block2") then - (fun pc -> pr_bind (parse_uint16 c pc) (fun n pc' -> - pr_map (fun bs -> AV_block( n, bs)) (parse_n_bytes n pc'))) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_block4") then - (fun pc -> pr_bind (parse_uint32 c pc) (fun n pc' -> - pr_map (fun bs -> AV_block( n, bs)) (parse_n_bytes n pc'))) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_block") then - (fun pc -> pr_bind (parse_ULEB128 pc) (fun n pc' -> - pr_map (fun bs -> AV_block( n, bs)) (parse_n_bytes n pc'))) -(* constant *) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_data1") then - pr_map2 (fun bs -> AV_block((Nat_big_num.of_int 1), bs)) (parse_n_bytes(Nat_big_num.of_int 1)) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_data2") then - pr_map2 (fun bs -> AV_block((Nat_big_num.of_int 2), bs)) (parse_n_bytes(Nat_big_num.of_int 2)) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_data4") then - pr_map2 (fun bs -> AV_block((Nat_big_num.of_int 4), bs)) (parse_n_bytes(Nat_big_num.of_int 4)) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_data8") then - pr_map2 (fun bs -> AV_block((Nat_big_num.of_int 8), bs)) (parse_n_bytes(Nat_big_num.of_int 8)) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_sdata") then - pr_map2 (fun i -> AV_constant_SLEB128 i) parse_SLEB128 - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_udata") then - pr_map2 (fun n -> AV_constant_ULEB128 n) parse_ULEB128 -(* exprloc *) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_exprloc") then - (fun pc -> pr_bind (parse_ULEB128 pc) (fun n pc' -> - pr_map (fun bs -> AV_exprloc( n, bs)) (parse_n_bytes n pc'))) -(* flag *) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_flag") then - pr_map2 (fun n -> AV_flag (not (Nat_big_num.equal n(Nat_big_num.of_int 0)))) (parse_uint8) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_flag_present") then - pr_map2 (fun () -> AV_flag true) (pr_return ()) -(* lineptr, loclistptr, macptr, rangelistptr *) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_sec_offset") then - pr_map2 (fun n -> AV_sec_offset n) (parse_uintDwarfN c cuh.cuh_dwarf_format) -(* reference - first type *) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_ref1") then - pr_map2 (fun n -> AV_ref n) (parse_uint8) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_ref2") then - pr_map2 (fun n -> AV_ref n) (parse_uint16 c) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_ref4") then - pr_map2 (fun n -> AV_ref n) (parse_uint32 c) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_ref8") then - pr_map2 (fun n -> AV_ref n) (parse_uint64 c) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_ref_udata") then - pr_map2 (fun n -> AV_ref n) parse_ULEB128 -(* reference - second type *) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_ref_addr") then - pr_map2 (fun n -> AV_ref_addr n) (parse_uintDwarfN c cuh.cuh_dwarf_format) -(* reference - third type *) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_ref_sig8") then - pr_map2 (fun n -> AV_ref_sig8 n) (parse_uint64 c) -(* string *) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_string") then - pr_map2 (fun bs -> AV_string bs) parse_string - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_strp") then - pr_map2 (fun n -> AV_strp n) (parse_uintDwarfN c cuh.cuh_dwarf_format) -(* indirect (cycle detection) *) - else if Nat_big_num.equal n (attribute_form_encode "DW_FORM_indirect") then - failwith "DW_FORM_INDIRECT cycle" -(* unknown *) - else - failwith "parser_of_attribute_form_non_indirect: unknown attribute form") - - -let parser_of_attribute_form c cuh n:parse_context ->(attribute_value)parse_result= - (if Nat_big_num.equal n (attribute_form_encode "DW_FORM_indirect") then - (fun pc -> pr_bind (parse_ULEB128 pc) (fun n -> - parser_of_attribute_form_non_indirect c cuh n) ) - else - parser_of_attribute_form_non_indirect c cuh n) - -(** attribute find *) - -let find_name str ats : string option= - (myfindmaybe - (fun (((at: Nat_big_num.num), (af: Nat_big_num.num)), ((pos: Nat_big_num.num),(av:attribute_value))) -> - if Nat_big_num.equal (attribute_encode "DW_AT_name") at then - let name1 = - ((match av with - | AV_string bs -> string_of_bytes bs - | AV_strp n -> pp_debug_str_entry str n - | _ -> "av_name AV not understood" - )) in - Some name1 - else - None) - ats) - -let find_name_of_die str die1 : string option= - (let ats = (Lem_list.list_combine - die1.die_abbreviation_declaration.ad_attribute_specifications - die1.die_attribute_values) in - find_name str ats) - -let find_attribute_value (an: string) (die1:die) : attribute_value option= - (let at = (attribute_encode an) in - let ats = (Lem_list.list_combine - die1.die_abbreviation_declaration.ad_attribute_specifications - die1.die_attribute_values) in - myfindmaybe - (fun (((at': Nat_big_num.num), (af: Nat_big_num.num)), ((pos: Nat_big_num.num),(av:attribute_value))) -> - if Nat_big_num.equal at' at then Some av else None) - ats) - -(** compilation unit header: pp and parsing *) - -let pp_dwarf_format df:string= ((match df with Dwarf32 -> "(32-bit)" | Dwarf64 -> "(64-bit)" )) - -let pp_unit_header (s:string) (x:compilation_unit_header) : string= - (" " ^ (s ^ (" Unit @ offset " ^ (pphex x.cuh_offset ^ (":\n" - ^ (" Length: " ^ (pphex x.cuh_unit_length ^ (" " ^ (pp_dwarf_format x.cuh_dwarf_format ^ ("\n" - ^ (" Version: " ^ (Nat_big_num.to_string x.cuh_version ^ ("\n" - ^ (" Abbrev Offset: " ^ (pphex x.cuh_debug_abbrev_offset ^ ("\n" - ^ (" Pointer Size: " ^ (Nat_big_num.to_string x.cuh_address_size ^ "\n")))))))))))))))))) - -let pp_compilation_unit_header (x:compilation_unit_header) : string= - (pp_unit_header "Compilation" x) - -let parse_unit_length c : (dwarf_format * Nat_big_num.num) parser= - (fun (pc: parse_context) -> - pr_bind (parse_uint32 c pc) (fun x pc' -> - if Nat_big_num.less x (natural_of_hex "0xfffffff0") then PR_success( (Dwarf32,x), pc') - else if not (Nat_big_num.equal x (natural_of_hex "0xffffffff")) then PR_fail( "bad unit_length", pc) - else - pr_bind (parse_uint64 c pc') (fun x' pc'' -> - PR_success( (Dwarf64, x'), pc')))) - - -let parse_compilation_unit_header c : compilation_unit_header parser= - (pr_post_map - (pr_with_pos - (parse_dependent_pair - (parse_unit_length c) - (fun (df,ul) -> - parse_triple - (parse_uint16 c) (* version *) - (parse_uintDwarfN c df) (* debug abbrev offset *) - (parse_uint8) (* address_size *)))) - (fun (offset,((df,ul), (v, (dao, as')))) -> - { - cuh_offset = offset; - cuh_dwarf_format = df; - cuh_unit_length = ul; - cuh_version = v; - cuh_debug_abbrev_offset = dao; - cuh_address_size = as'; - })) - - -(** type unit header: pp and parsing *) - -(* the test binaries don't have a .debug_types section, so this isn't tested *) - -let pp_type_unit_header (x:type_unit_header) : string= - (pp_unit_header "Type" x.tuh_cuh - ^ (" Type Signature: " ^ (pphex x.tuh_type_signature ^ ("\n" - ^ (" Type Offset: " ^ (pphex x.tuh_type_offset ^ "\n")))))) - - -let parse_type_unit_header c : type_unit_header parser= - (pr_post_map - (parse_dependent_pair - (parse_compilation_unit_header c) - (fun cuh -> - parse_pair - (parse_uint64 c) (* type signature *) - (parse_uintDwarfN c cuh.cuh_dwarf_format) (* type offset *) )) - (fun (cuh, (ts, to')) -> - { - tuh_cuh = cuh; - tuh_type_signature = ts; - tuh_type_offset = to'; - })) - - -(** debugging information entries: pp and parsing *) - -(* example pp from readelf - <2><51>: Abbrev Number: 3 (DW_TAG_variable) - <52> DW_AT_name : x - <54> DW_AT_decl_file : 1 - <55> DW_AT_decl_line : 2 - <56> DW_AT_type : <0x6a> - <5a> DW_AT_location : 2 byte block: 91 6c (DW_OP_fbreg: -20) -*) - -let pp_pos pos:string= ("<" ^ (pphex pos ^">")) - -let indent_level (level: Nat_big_num.num):string= (Xstring.implode (replicate0 ( Nat_big_num.mul(Nat_big_num.of_int 3) level) ' ')) - -let pp_die_attribute c (cuh:compilation_unit_header) (str : char list) (level: Nat_big_num.num) (((at: Nat_big_num.num), (af: Nat_big_num.num)), ((pos: Nat_big_num.num),(av:attribute_value))) : string= - (indent_level ( Nat_big_num.add level(Nat_big_num.of_int 1)) ^ (pp_pos pos ^ (" " - ^ (pp_attribute_encoding at ^ (" : " - ^ ("(" ^ (pp_attribute_form_encoding af ^ (") " - ^ (pp_attribute_value c cuh str at av - ^ "\n"))))))))) - -(*val pp_die : p_context -> compilation_unit_header -> list byte -> natural -> bool -> die -> string*) -let rec pp_die c cuh str level (pp_children:bool) die1:string= - (indent_level level ^ ("<" ^ (Nat_big_num.to_string level ^ (">" - ^ (pp_pos die1.die_offset - ^ (": Abbrev Number: " ^ (Nat_big_num.to_string die1.die_abbreviation_code - ^ (" (" ^ (pp_tag_encoding die1.die_abbreviation_declaration.ad_tag ^(")\n" - ^ -(let ats = (Lem_list.list_combine - die1.die_abbreviation_declaration.ad_attribute_specifications - die1.die_attribute_values) in - (myconcat "" (Lem_list.map (pp_die_attribute c cuh str level) ats)) - ^ -(if pp_children then myconcat "" (Lem_list.map (pp_die c cuh str ( Nat_big_num.add level(Nat_big_num.of_int 1)) pp_children) die1.die_children) else "")))))))))))) - -(*val pp_die_abbrev : p_context -> compilation_unit_header -> list byte -> natural -> bool -> (list die) -> die -> string*) -let rec pp_die_abbrev c cuh str level (pp_children:bool) parents die1:string= - (indent_level level - ^ (pp_tag_encoding die1.die_abbreviation_declaration.ad_tag - ^ (" (" ^ (pp_pos die1.die_offset ^ (") " -(* ^ ": Abbrev Number: " ^ show die.die_abbreviation_code *) - ^ -(let ats = (Lem_list.list_combine - die1.die_abbreviation_declaration.ad_attribute_specifications - die1.die_attribute_values) in - ((match find_name str ats with Some s -> s | None -> "-" )) - ^ (" : " ^ (myconcat " : " (Lem_list.map (fun die' -> pp_tag_encoding die'.die_abbreviation_declaration.ad_tag) parents) - ^ ("\n" - ^ - -( (*(myconcat "" (List.map (pp_die_abbrev_attribute c cuh str) ats))*)if pp_children then myconcat "" (Lem_list.map (pp_die_abbrev c cuh str ( Nat_big_num.add level(Nat_big_num.of_int 1)) pp_children (die1::parents)) die1.die_children) else "")))))))))) - - - -(*val parse_die : p_context -> list byte -> compilation_unit_header -> (natural->abbreviation_declaration) -> parser (maybe die)*) -let rec parse_die c str cuh find_abbreviation_declaration:parse_context ->((die)option)parse_result= - (fun (pc: parse_context) -> - let _ = (my_debug3 ("parse_die called at " ^ (pp_parse_context pc ^ "\n"))) in - pr_bind (parse_ULEB128 pc) (fun abbreviation_code pc' -> - if Nat_big_num.equal abbreviation_code(Nat_big_num.of_int 0) then PR_success( None, pc') - else - let _ = (my_debug3 ("parse_die abbreviation code "^(pphex abbreviation_code ^"\n"))) in - let ad = (find_abbreviation_declaration abbreviation_code) in - let attribute_value_parsers = (Lem_list.map (fun (at,af) -> pr_with_pos (parser_of_attribute_form c cuh af)) ad.ad_attribute_specifications) in - pr_bind (parse_parser_list attribute_value_parsers pc') (fun avs pc'' -> - -(* - let die_header = - <| - die_offset = pc.pc_offset; - die_abbreviation_code = abbreviation_code; - die_abbreviation_declaration = ad; - die_attribute_values = avs; - die_children = []; - |> in let _ = my_debug3 ("die_header " ^ pp_die cuh str 999 die_header) in - *) - pr_bind - (if ad.ad_has_children then parse_list (parse_die c str cuh find_abbreviation_declaration) pc'' else pr_return [] pc'') - (fun dies pc''' -> - PR_success( (Some ( let die1 = - ({ - die_offset = (pc.pc_offset); - die_abbreviation_code = abbreviation_code; - die_abbreviation_declaration = ad; - die_attribute_values = avs; - die_children = dies; - }) in (* let _ = my_debug3 ("die entire " ^ pp_die cuh str 999 die) in *)die1)), pc'''))))) - -let has_attribute (an: string) (die1: die) : bool= - (Lem_list.elem instance_Basic_classes_Eq_Num_natural_dict - (attribute_encode an) - (Lem_list.map fst die1.die_abbreviation_declaration.ad_attribute_specifications)) - - -(** compilation units: pp and parsing *) - -let pp_compilation_unit c (debug_str_section_body: char list) cu:string= - - ("*** compilation unit header ***\n" - ^ (pp_compilation_unit_header cu.cu_header - ^ ("\n*** compilation unit abbreviation table ***\n" - ^ (pp_abbreviations_table cu.cu_abbreviations_table - ^ ("\n*** compilation unit die tree ***\n" - ^ (pp_die c cu.cu_header debug_str_section_body(Nat_big_num.of_int 0) true cu.cu_die - ^ "\n")))))) - -let pp_compilation_units c debug_string_section_body (compilation_units1: compilation_unit list) : string= - (myconcat "" (Lem_list.map (pp_compilation_unit c debug_string_section_body) compilation_units1)) - - -let pp_compilation_unit_abbrev c (debug_str_section_body: char list) cu:string= - (pp_compilation_unit_header cu.cu_header -(* ^ pp_abbreviations_table cu.cu_abbreviations_table*) - ^ pp_die_abbrev c cu.cu_header debug_str_section_body(Nat_big_num.of_int 0) true [] cu.cu_die) - -let pp_compilation_units_abbrev c debug_string_section_body (compilation_units1: compilation_unit list) : string= - (myconcat "" (Lem_list.map (pp_compilation_unit_abbrev c debug_string_section_body) compilation_units1)) - - -let parse_compilation_unit c (debug_str_section_body: char list) (debug_abbrev_section_body: char list) : ( compilation_unit option) parser= - (fun (pc:parse_context) -> - - if (listEqualBy (=) pc.pc_bytes []) then PR_success( None, pc) else - - let (cuh, pc') = - - ((match parse_compilation_unit_header c pc with - | PR_fail( s, pc') -> failwith ("parse_cuh_header fail: " ^ pp_parse_fail s pc') - | PR_success( cuh, pc') -> (cuh,pc') - )) in - - let _ = (my_debug4 (pp_compilation_unit_header cuh)) in - - let pc_abbrev = ({pc_bytes = ((match mydrop cuh.cuh_debug_abbrev_offset debug_abbrev_section_body with Some bs -> bs | None -> failwith "mydrop of debug_abbrev" )); pc_offset = (cuh.cuh_debug_abbrev_offset) }) in - - let abbreviations_table1 = - ((match parse_abbreviations_table c pc_abbrev with - | PR_fail( s, pc_abbrev') -> failwith ("parse_abbrevations_table fail: " ^ pp_parse_fail s pc_abbrev') - | PR_success( at, pc_abbrev') -> at - )) in - - let _ = (my_debug4 (pp_abbreviations_table abbreviations_table1)) in - - let find_abbreviation_declaration (ac:Nat_big_num.num) : abbreviation_declaration= - (let _ = (my_debug4 ("find_abbreviation_declaration "^pphex ac)) in - myfindNonPure (fun ad -> Nat_big_num.equal ad.ad_abbreviation_code ac) abbreviations_table1) in - - let _ = (my_debug3 (pp_abbreviations_table abbreviations_table1)) in - - (match parse_die c debug_str_section_body cuh find_abbreviation_declaration pc' with - | PR_fail( s, pc'') -> failwith ("parse_die fail: " ^ pp_parse_fail s pc'') - | PR_success( (None), pc'') -> failwith ("parse_die returned Nothing: " ^ pp_parse_context pc'') - | PR_success( (Some die1), pc'') -> - let cu = - ({ - cu_header = cuh; - cu_abbreviations_table = abbreviations_table1; - cu_die = die1; - }) in - PR_success( (Some cu), pc'') - )) - -let parse_compilation_units c (debug_str_section_body: char list) (debug_abbrev_section_body: char list): ( compilation_unit list) parser= - - (parse_list (parse_compilation_unit c debug_str_section_body debug_abbrev_section_body)) - - -(** type units: pp and parsing *) - -let pp_type_unit c (debug_str_section_body: char list) tu:string= - (pp_type_unit_header tu.tu_header - ^ (pp_abbreviations_table tu.tu_abbreviations_table - ^ pp_die c tu.tu_header.tuh_cuh debug_str_section_body(Nat_big_num.of_int 0) true tu.tu_die)) - -let pp_type_units c debug_string_section_body (type_units1: type_unit list) : string= - (myconcat "" (Lem_list.map (pp_type_unit c debug_string_section_body) type_units1)) - - -let parse_type_unit c (debug_str_section_body: char list) (debug_abbrev_section_body: char list) : ( type_unit option) parser= - (fun (pc:parse_context) -> - - if (listEqualBy (=) pc.pc_bytes []) then PR_success( None, pc) else - - let (tuh, pc') = - ((match parse_type_unit_header c pc with - | PR_fail( s, pc') -> failwith ("parse_tuh_header fail: " ^ pp_parse_fail s pc') - | PR_success( tuh, pc') -> (tuh,pc') - )) in - - let _ = (my_debug4 (pp_type_unit_header tuh)) in - - let pc_abbrev = (let n = (tuh.tuh_cuh.cuh_debug_abbrev_offset) in {pc_bytes = ((match mydrop n debug_abbrev_section_body with Some bs -> bs | None -> failwith "mydrop of debug_abbrev" )); pc_offset = n }) in - - let abbreviations_table1 = - ((match parse_abbreviations_table c pc_abbrev with - | PR_fail( s, pc_abbrev') -> failwith ("parse_abbrevations_table fail: " ^ pp_parse_fail s pc_abbrev') - | PR_success( at, pc_abbrev') -> at - )) in - - let _ = (my_debug4 (pp_abbreviations_table abbreviations_table1)) in - - let find_abbreviation_declaration (ac:Nat_big_num.num) : abbreviation_declaration= - (let _ = (my_debug4 ("find_abbreviation_declaration "^pphex ac)) in - myfindNonPure (fun ad -> Nat_big_num.equal ad.ad_abbreviation_code ac) abbreviations_table1) in - - let _ = (my_debug3 (pp_abbreviations_table abbreviations_table1)) in - - (match parse_die c debug_str_section_body tuh.tuh_cuh find_abbreviation_declaration pc' with - | PR_fail( s, pc'') -> failwith ("parse_die fail: " ^ pp_parse_fail s pc'') - | PR_success( (None), pc'') -> failwith ("parse_die returned Nothing: " ^ pp_parse_context pc'') - | PR_success( (Some die1), pc'') -> - let tu = - ({ - tu_header = tuh; - tu_abbreviations_table = abbreviations_table1; - tu_die = die1; - }) in - PR_success( (Some tu), pc'') - )) - -let parse_type_units c (debug_str_section_body: char list) (debug_abbrev_section_body: char list): ( type_unit list) parser= - - (parse_list (parse_type_unit c debug_str_section_body debug_abbrev_section_body)) - -(** location lists, pp and parsing *) - -(* readelf example -Contents of the .debug_loc section: - - Offset Begin End Expression - 00000000 0000000000400168 0000000000400174 (DW_OP_reg0 (r0)) - 00000000 0000000000400174 0000000000400184 (DW_OP_GNU_entry_value: (DW_OP_reg0 (r0)); DW_OP_stack_value) - 00000000 <End of list> - 00000039 000000000040017c 0000000000400180 (DW_OP_lit1; DW_OP_stack_value) -*) - -let pp_location_list_entry c (cuh:compilation_unit_header) (offset:Nat_big_num.num) (x:location_list_entry) : string= - (" " ^ (pphex offset - ^ (" " ^ (pphex x.lle_beginning_address_offset - ^ (" " ^ (pphex x.lle_ending_address_offset - ^ (" (" ^ (parse_and_pp_operations c cuh x.lle_single_location_description ^(")" - ^ "\n"))))))))) - -let pp_base_address_selection_entry c (cuh:compilation_unit_header) (offset:Nat_big_num.num) (x:base_address_selection_entry) : string= - (" " ^ (pphex offset - ^ (" " ^ (pphex x.base_address - ^ "\n")))) - -let pp_location_list_item c (cuh: compilation_unit_header) (offset: Nat_big_num.num) (x:location_list_item):string= - ((match x with - | LLI_lle lle -> pp_location_list_entry c cuh offset lle - | LLI_base base -> pp_base_address_selection_entry c cuh offset base - )) - -let pp_location_list c (cuh: compilation_unit_header) ((offset:Nat_big_num.num), (llis: location_list_item list)):string= - (myconcat "" (Lem_list.map (pp_location_list_item c cuh offset) llis)) -(* ^ " " ^ pphex offset ^ " <End of list>\n"*) - -let pp_loc c (cuh: compilation_unit_header) (lls: location_list list):string= - (" Offset Begin End Expression\n" - ^ myconcat "" (Lem_list.map (pp_location_list c cuh) lls)) - -(* Note that this is just pp'ing the raw location list data - Sectoin -3.1.1 says: The applicable base address of a location list entry is -determined by the closest preceding base address selection entry in -the same location list. If there is no such selection entry, then the -applicable base address defaults to the base address of the -compilation unit. That is handled by the interpret_location_list below *) - - - -let parse_location_list_item c (cuh: compilation_unit_header) : ( location_list_item option) parser= - (fun (pc:parse_context) -> - pr_bind - (parse_pair - (parse_uint_address_size c cuh.cuh_address_size) - (parse_uint_address_size c cuh.cuh_address_size) - pc) - (fun ((a1: Nat_big_num.num),(a2:Nat_big_num.num)) pc' -> - let _ = (my_debug4 ("offset="^(pphex pc.pc_offset ^ (" begin=" ^ (pphex a1 ^ (" end=" ^ pphex a2)))))) in - if Nat_big_num.equal a1(Nat_big_num.of_int 0) &&Nat_big_num.equal a2(Nat_big_num.of_int 0) then - PR_success( None, pc') - else if Nat_big_num.equal a1 (max_address cuh.cuh_address_size) then - let x = (LLI_base { (*base_offset=pc.pc_offset;*) base_address=a1 }) in - PR_success( (Some x (*(pc.pc_offset, x)*)), pc') - else - pr_bind (parse_uint16 c pc') (fun n pc'' -> - pr_post_map1 - (parse_n_bytes n pc'') - (fun bs -> - let x = - (LLI_lle { - (*lle_offset = pc.pc_offset;*) - lle_beginning_address_offset = a1; - lle_ending_address_offset = a2; - lle_single_location_description = bs; - }) in - Some x (*(pc.pc_offset, x)*)) - ) - )) - -let parse_location_list c cuh : ( location_list option) parser= - (fun (pc: parse_context) -> - if (listEqualBy (=) pc.pc_bytes []) then - PR_success( None, pc) - else - pr_post_map1 - (parse_list (parse_location_list_item c cuh) pc) - (fun llis -> (Some (pc.pc_offset, llis)))) - -let parse_location_list_list c cuh : location_list_list parser= - (parse_list (parse_location_list c cuh)) - -let find_location_list dloc n : location_list= - (myfindNonPure (fun (n',_)->Nat_big_num.equal n' n) dloc) - (* fails if location list not found *) - -(* interpretation of a location list applies the base_address and LLI_base offsets to give a list indexed by concrete address ranges *) - -let rec interpret_location_list (base_address1: Nat_big_num.num) (llis: location_list_item list) : (Nat_big_num.num * Nat_big_num.num * single_location_description) list= - ((match llis with - | [] -> [] - | LLI_base base::llis' -> interpret_location_list base.base_address llis' - | LLI_lle lle :: llis' -> (Nat_big_num.add base_address1 lle.lle_beginning_address_offset,Nat_big_num.add base_address1 lle.lle_ending_address_offset, lle.lle_single_location_description) :: interpret_location_list base_address1 llis' - )) - - -(** range lists, pp and parsing *) - -(* readelf example -Contents of the .debug_aranges section: - - Length: 44 - Version: 2 - Offset into .debug_info: 0x0 - Pointer Size: 8 - Segment Size: 0 - - Address Length - 00000000100000e8 0000000000000090 - 0000000000000000 0000000000000000 - Length: 44 - Version: 2 - Offset into .debug_info: 0x1de - Pointer Size: 8 - Segment Size: 0 -*) - -let pp_range_list_entry c (cuh:compilation_unit_header) (offset:Nat_big_num.num) (x:range_list_entry) : string= - (" " ^ (pphex offset - ^ (" " ^ (pphex x.rle_beginning_address_offset - ^ (" " ^ (pphex x.rle_ending_address_offset - ^ "\n")))))) - -let pp_range_list_item c (cuh: compilation_unit_header) (offset: Nat_big_num.num) (x:range_list_item):string= - ((match x with - | RLI_rle rle -> pp_range_list_entry c cuh offset rle - | RLI_base base -> pp_base_address_selection_entry c cuh offset base - )) - -let pp_range_list c (cuh: compilation_unit_header) ((offset:Nat_big_num.num), (rlis: range_list_item list)):string= - (myconcat "" (Lem_list.map (pp_range_list_item c cuh offset) rlis)) -(* ^ " " ^ pphex offset ^ " <End of list>\n"*) - -let pp_ranges c (cuh: compilation_unit_header) (rls: range_list list):string= - (" Offset Begin End Expression\n" - ^ myconcat "" (Lem_list.map (pp_range_list c cuh) rls)) - -(* Note that this is just pp'ing the raw range list data - see also -the interpret_range_list below *) - - -let parse_range_list_item c (cuh: compilation_unit_header) : ( range_list_item option) parser= - (fun (pc:parse_context) -> - pr_bind - (parse_pair - (parse_uint_address_size c cuh.cuh_address_size) - (parse_uint_address_size c cuh.cuh_address_size) - pc) - (fun ((a1: Nat_big_num.num),(a2:Nat_big_num.num)) pc' -> - let _ = (my_debug4 ("offset="^(pphex pc.pc_offset ^ (" begin=" ^ (pphex a1 ^ (" end=" ^ pphex a2)))))) in - if Nat_big_num.equal a1(Nat_big_num.of_int 0) &&Nat_big_num.equal a2(Nat_big_num.of_int 0) then - PR_success( None, pc') - else if Nat_big_num.equal a1 (max_address cuh.cuh_address_size) then - let x = (RLI_base { base_address=a1 }) in - PR_success( (Some x), pc') - else - let x = - (RLI_rle { - rle_beginning_address_offset = a1; - rle_ending_address_offset = a2; - }) in - PR_success( (Some x (*(pc.pc_offset, x)*)), pc') - )) - -let parse_range_list c cuh : ( range_list option) parser= - (fun (pc: parse_context) -> - if (listEqualBy (=) pc.pc_bytes []) then - PR_success( None, pc) - else - pr_post_map1 - (parse_list (parse_range_list_item c cuh) pc) - (fun rlis -> (Some (pc.pc_offset, rlis)))) - -let parse_range_list_list c cuh : range_list_list parser= - (parse_list (parse_range_list c cuh)) - -let find_range_list dranges n : range_list= - (myfindNonPure (fun (n',_)->Nat_big_num.equal n' n) dranges) - (* fails if range list not found *) - -(* interpretation of a range list applies the base_address and RLI_base offsets to give a list of concrete address ranges *) - -let rec interpret_range_list (base_address1: Nat_big_num.num) (rlis: range_list_item list) : (Nat_big_num.num * Nat_big_num.num) list= - ((match rlis with - | [] -> [] - | RLI_base base::rlis' -> interpret_range_list base.base_address rlis' - | RLI_rle rle :: rlis' -> (Nat_big_num.add base_address1 rle.rle_beginning_address_offset,Nat_big_num.add base_address1 rle.rle_ending_address_offset) :: interpret_range_list base_address1 rlis' - )) - -(** frame information, pp and parsing *) - -(* readelf example - -Contents of the .debug_frame section: - -00000000 0000000c ffffffff CIE - Version: 1 - Augmentation: "" - Code alignment factor: 4 - Data alignment factor: -8 - Return address column: 65 - - DW_CFA_def_cfa: r1 ofs 0 - -00000010 00000024 00000000 FDE cie=00000000 pc=100000b0..10000120 - DW_CFA_advance_loc: 8 to 100000b8 - DW_CFA_def_cfa_offset: 80 - DW_CFA_offset: r31 at cfa-8 - DW_CFA_advance_loc: 4 to 100000bc - DW_CFA_def_cfa_register: r31 - DW_CFA_advance_loc: 80 to 1000010c - DW_CFA_def_cfa: r1 ofs 0 - DW_CFA_nop - DW_CFA_nop - DW_CFA_nop - DW_CFA_nop - -00000038 00000024 00000000 FDE cie=00000000 pc=10000120..100001a4 - DW_CFA_advance_loc: 16 to 10000130 - DW_CFA_def_cfa_offset: 144 - DW_CFA_offset_extended_sf: r65 at cfa+16 - DW_CFA_offset: r31 at cfa-8 - DW_CFA_advance_loc: 4 to 10000134 - DW_CFA_def_cfa_register: r31 - DW_CFA_advance_loc: 84 to 10000188 - DW_CFA_def_cfa: r1 ofs 0 -*) - - - -let pp_cfa_address a:string= (pphex a) -let pp_cfa_block dict_Show_Show_a b:string= (ppbytes - dict_Show_Show_a b) -let pp_cfa_delta d:string= (pphex d) -(*let pp_cfa_offset n = pphex n -let pp_cfa_register r = show r*) -let pp_cfa_sfoffset dict_Show_Show_a i:string= ( - dict_Show_Show_a.show_method i) - -let pp_cfa_register dict_Show_Show_a r:string= ("r"^ - dict_Show_Show_a.show_method r) (*TODO: arch-specific register names *) - -let pp_cfa_offset (i:Nat_big_num.num):string= (if Nat_big_num.equal i(Nat_big_num.of_int 0) then "" else if Nat_big_num.less i(Nat_big_num.of_int 0) then Nat_big_num.to_string i else "+" ^ Nat_big_num.to_string i) - -let pp_cfa_rule (cr:cfa_rule) : string= - ((match cr with - | CR_undefined -> "u" - | CR_register( r, i) -> pp_cfa_register - instance_Show_Show_Num_natural_dict r ^ pp_cfa_offset i - | CR_expression bs -> "exp" - )) - -let pp_register_rule (rr:register_rule) : string= -( (*TODO make this more readelf-like *)(match rr with - | RR_undefined -> "u" - | RR_same_value -> "s" - | RR_offset i -> "c" ^ pp_cfa_offset i - | RR_val_offset i -> "val(c" ^ (pp_cfa_offset i ^ ")") - | RR_register r -> pp_cfa_register - instance_Show_Show_Num_natural_dict r - | RR_expression bs -> "exp" - | RR_val_expression bs -> "val(exp)" - | RR_architectural -> "" - )) - - - -let pp_call_frame_instruction i:string= - ((match i with - | DW_CFA_advance_loc d -> "DW_CFA_advance_loc" ^ (" " ^ pp_cfa_delta d) - | DW_CFA_offset( r, n) -> "DW_CFA_offset" ^ (" " ^ (pp_cfa_register - instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_offset ( n)))) - | DW_CFA_restore r -> "DW_CFA_restore" ^ (" " ^ pp_cfa_register - instance_Show_Show_Num_natural_dict r) - | DW_CFA_nop -> "DW_CFA_nop" - | DW_CFA_set_loc a -> "DW_CFA_set_loc" ^ (" " ^ pp_cfa_address a) - | DW_CFA_advance_loc1 d -> "DW_CFA_advance_loc1" ^ (" " ^ pp_cfa_delta d) - | DW_CFA_advance_loc2 d -> "DW_CFA_advance_loc2" ^ (" " ^ pp_cfa_delta d) - | DW_CFA_advance_loc4 d -> "DW_CFA_advance_loc4" ^ (" " ^ pp_cfa_delta d) - | DW_CFA_offset_extended( r, n) -> "DW_CFA_offset_extended" ^ (" " ^ (pp_cfa_register - instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_offset ( n)))) - | DW_CFA_restore_extended r -> "DW_CFA_restore_extended" ^ (" " ^ pp_cfa_register - instance_Show_Show_Num_natural_dict r) - | DW_CFA_undefined r -> "DW_CFA_undefined" ^ (" " ^ pp_cfa_register - instance_Show_Show_Num_natural_dict r) - | DW_CFA_same_value r -> "DW_CFA_same_value" ^ (" " ^ pp_cfa_register - instance_Show_Show_Num_natural_dict r) - | DW_CFA_register( r1, r2) -> "DW_CFA_register" ^ (" " ^ (pp_cfa_register - instance_Show_Show_Num_natural_dict r1 ^ (" " ^ pp_cfa_register - instance_Show_Show_Num_natural_dict r2))) - | DW_CFA_remember_state -> "DW_CFA_remember_state" - | DW_CFA_restore_state -> "DW_CFA_restore_state" - | DW_CFA_def_cfa( r, n) -> "DW_CFA_def_cfa" ^ (" " ^ (pp_cfa_register - instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_offset ( n)))) - | DW_CFA_def_cfa_register r -> "DW_CFA_def_cfa_register" ^ (" " ^ pp_cfa_register - instance_Show_Show_Num_natural_dict r) - | DW_CFA_def_cfa_offset n -> "DW_CFA_def_cfa_offset" ^ (" " ^ pp_cfa_offset ( n)) - | DW_CFA_def_cfa_expression b -> "DW_CFA_def_cfa_expression" ^ (" " ^ pp_cfa_block - instance_Show_Show_Missing_pervasives_byte_dict b) - | DW_CFA_expression( r, b) -> "DW_CFA_expression" ^ (" " ^ (pp_cfa_register - instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_block - instance_Show_Show_Missing_pervasives_byte_dict b))) - | DW_CFA_offset_extended_sf( r, i) -> "DW_CFA_offset_extended_sf" ^ (" " ^ (pp_cfa_register - instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_sfoffset - instance_Show_Show_Num_integer_dict i))) - | DW_CFA_def_cfa_sf( r, i) -> "DW_CFA_def_cfa_sf" ^ (" " ^ (pp_cfa_register - instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_sfoffset - instance_Show_Show_Num_integer_dict i))) - | DW_CFA_def_cfa_offset_sf i -> "DW_CFA_def_cfa_offset_sf" ^ (" " ^ pp_cfa_sfoffset - instance_Show_Show_Num_integer_dict i) - | DW_CFA_val_offset( r, n) -> "DW_CFA_val_offset" ^ (" " ^ (pp_cfa_register - instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_offset ( n)))) - | DW_CFA_val_offset_sf( r, i) -> "DW_CFA_val_offset_sf" ^ (pp_cfa_register - instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_sfoffset - instance_Show_Show_Num_integer_dict i)) - | DW_CFA_val_expression( r, b) -> "DW_CFA_val_expression" ^ (" " ^ (pp_cfa_register - instance_Show_Show_Num_natural_dict r ^ (" " ^ pp_cfa_block - instance_Show_Show_Missing_pervasives_byte_dict b))) - | DW_CFA_unknown bt -> "DW_CFA_unknown" ^ (" " ^ hex_string_of_byte bt) - )) - -let pp_call_frame_instructions is:string= (myconcat "" (Lem_list.map (fun i -> " " ^ (pp_call_frame_instruction i ^ "\n")) is)) - - -let parser_of_call_frame_argument_type c cuh (cfat: call_frame_argument_type) : call_frame_argument_value parser= - ((match cfat with - | CFAT_address -> pr_map2 (fun n -> CFAV_address n) (parse_uint_address_size c cuh.cuh_address_size) - | CFAT_delta1 -> pr_map2 (fun n -> CFAV_delta n) (parse_uint8) - | CFAT_delta2 -> pr_map2 (fun n -> CFAV_delta n) (parse_uint16 c) - | CFAT_delta4 -> pr_map2 (fun n -> CFAV_delta n) (parse_uint32 c) - | CFAT_delta_ULEB128 -> pr_map2 (fun n -> CFAV_delta n) (parse_ULEB128) - | CFAT_offset -> pr_map2 (fun n -> CFAV_offset n) (parse_ULEB128) - | CFAT_sfoffset -> pr_map2 (fun n -> CFAV_sfoffset n) (parse_SLEB128) - | CFAT_register -> pr_map2 (fun n -> CFAV_register n) (parse_ULEB128) - | CFAT_block -> - (fun pc -> pr_bind (parse_ULEB128 pc) (fun n pc' -> - pr_map (fun bs -> CFAV_block bs) (parse_n_bytes n pc'))) - )) - -let parse_call_frame_instruction c cuh : ( call_frame_instruction option) parser= - (fun pc -> - (match pc.pc_bytes with - | [] -> PR_success( None, pc) - | b::bs' -> - let pc' = ({ pc_bytes = bs'; pc_offset = (Nat_big_num.add pc.pc_offset(Nat_big_num.of_int 1)) }) in - let ch = (Uint32.of_int (Char.code b)) in - let high_bits = (Uint32.logand ch (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 192)))) in - let low_bits = (Nat_big_num.of_string (Uint32.to_string (Uint32.logand ch (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 63)))))) in - if high_bits = Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0)) then - (match lookup_abCde_de - instance_Basic_classes_Eq_Num_natural_dict low_bits call_frame_instruction_encoding with - | Some ((args: call_frame_argument_type list), result) -> - let ps = (Lem_list.map (parser_of_call_frame_argument_type c cuh) args) in - let p = - (pr_post_map - (parse_parser_list ps) - result) in - (match p pc' with - | PR_success( (Some cfi), pc'') -> PR_success( (Some cfi), pc'') - | PR_success( (None), pc'') -> failwith "bad call frame instruction argument 1" - | PR_fail( s, pc'') -> failwith "bad call frame instruction argument 2" - ) - | None -> - (*Assert_extra.failwith ("can't parse " ^ show b ^ " as call frame instruction")*) - PR_success( (Some (DW_CFA_unknown b)), pc') - ) - else - if high_bits = Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 64)) then - PR_success( (Some (DW_CFA_advance_loc low_bits)), pc') - else if high_bits = Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 192)) then - PR_success( (Some (DW_CFA_restore low_bits)), pc') - else - let p = (parser_of_call_frame_argument_type c cuh CFAT_offset) in - (match p pc' with - | PR_success( (CFAV_offset n), pc'') -> PR_success( (Some (DW_CFA_offset( low_bits, n))), pc'') - | PR_success( _, pc'') -> failwith "bad call frame instruction argument 3" - | PR_fail( s, pc'') -> failwith "bad call frame instruction argument 4" - ) - )) - -let parse_call_frame_instructions c cuh : ( call_frame_instruction list) parser= - (parse_list (parse_call_frame_instruction c cuh)) - -(*val parse_and_pp_call_frame_instructions : p_context -> compilation_unit_header -> list byte -> string*) -let parse_and_pp_call_frame_instructions c cuh bs:string= - (let pc = ({pc_bytes = bs; pc_offset =(Nat_big_num.of_int 0) }) in - (match parse_call_frame_instructions c cuh pc with - | PR_fail( s, pc') -> "parse_call_frame_instructions fail: " ^ pp_parse_fail s pc' - | PR_success( is, pc') -> - pp_call_frame_instructions is - ^ (if not ((listEqualBy (=) pc'.pc_bytes [])) then " Warning: extra non-parsed bytes" else "") - )) - - - -let pp_call_frame_instructions' c cuh bs:string= -( - (* ppbytes bs ^ "\n" *)parse_and_pp_call_frame_instructions c cuh bs) - - - -let pp_cie c cuh cie1:string= - (pphex cie1.cie_offset - ^ (" " ^ (pphex cie1.cie_length - ^ (" " ^ (pphex cie1.cie_id - ^ (" CIE\n" - ^ (" Version: " ^ (Nat_big_num.to_string cie1.cie_version ^ ("\n" - ^ (" Augmentation: \""^ (string_of_string (Xstring.implode (Lem_list.map (fun x-> x) cie1.cie_augmentation)) ^ ("\"\n" - ^ (" Code alignment factor: " ^ (Nat_big_num.to_string cie1.cie_code_alignment_factor ^ ("\n" - ^ (" Data alignment factor: " ^ (Nat_big_num.to_string cie1.cie_data_alignment_factor ^ ("\n" - ^ (" Return address column: " ^ (Nat_big_num.to_string cie1.cie_return_address_register ^ ("\n" - ^ ("\n" - ^ (ppbytes instance_Show_Show_Missing_pervasives_byte_dict cie1.cie_initial_instructions_bytes ^ ("\n" - ^ pp_call_frame_instructions cie1.cie_initial_instructions)))))))))))))))))))))))) - -(* cie_address_size: natural; (* not shown by readelf - must match compilation unit *)*) -(* cie_segment_size: natural; (* not shown by readelf *)*) -(* readelf says "Return address column", but the DWARF spec says "Return address register" *) - - -let pp_fde c cuh fde1:string= - (pphex fde1.fde_offset - ^ (" " ^ (pphex fde1.fde_length - ^ (" " ^ (pphex fde1.fde_cie_pointer (* not what this field of readelf output is *) - ^ (" FDE" - ^ (" cie=" ^ (pphex fde1.fde_cie_pointer (* duplicated?? *) - ^ (" pc=" ^ ((match fde1.fde_initial_location_segment_selector with None -> "" | Some segment_selector -> "("^(pphex segment_selector^")") ) ^ (pphex fde1.fde_initial_location_address ^ (".." ^ (pphex ( Nat_big_num.add fde1.fde_initial_location_address fde1.fde_address_range) ^ ("\n" - ^ (ppbytes instance_Show_Show_Missing_pervasives_byte_dict fde1.fde_instructions_bytes ^ ("\n" - ^ pp_call_frame_instructions fde1.fde_instructions)))))))))))))))) - -let pp_frame_info_element c cuh fie:string= - ((match fie with - | FIE_cie cie1 -> pp_cie c cuh cie1 - | FIE_fde fde1 -> pp_fde c cuh fde1 - )) - -let pp_frame_info c cuh fi:string= - ("Contents of the .debug_frame section:\n\n" - ^ (myconcat "\n" (Lem_list.map (pp_frame_info_element c cuh) fi) - ^ "\n")) - - - -let rec find_cie fi cie_id1:cie= - ((match fi with - | [] -> failwith "find_cie: cie_id not found" - | FIE_fde _ :: fi' -> find_cie fi' cie_id1 - | FIE_cie cie1 :: fi' -> if Nat_big_num.equal cie_id1 cie1.cie_offset then cie1 else find_cie fi' cie_id1 - )) - -let parse_initial_location c cuh mss mas' : (( Nat_big_num.num option) * Nat_big_num.num) parser= -( (*(segment selector and target address)*) - (* assume segment selector size is zero unless given explicitly. Probably we need to do something architecture-specific for earlier dwarf versions?*)parse_pair - (parse_uint_segment_selector_size c ((match mss with Some n -> n | None ->Nat_big_num.of_int 0 ))) - (parse_uint_address_size c ((match mas' with Some n -> n | None -> cuh.cuh_address_size )))) - - -let parse_call_frame_instruction_bytes offset' ul:parse_context ->((char)list)parse_result= - (fun (pc: parse_context) -> - parse_n_bytes ( Nat_big_num.sub_nat ul ( Nat_big_num.sub_nat pc.pc_offset offset')) pc) - -let parse_frame_info_element c cuh (fi: frame_info_element list) : frame_info_element parser= - (parse_dependent - (pr_with_pos - (parse_dependent_pair - (parse_unit_length c) - (fun (df,ul) -> - pr_with_pos - (parse_uintDwarfN c df) (* CIE_id (cie) or CIE_pointer (fde) *) - ))) - (fun (offset,((df,ul),(offset',cie_id1))) -> - if ( Nat_big_num.equal cie_id1 - (match df with - | Dwarf32 -> natural_of_hex "0xffffffff" - | Dwarf64 -> natural_of_hex "0xffffffffffffffff" - )) - then - (* parse cie *) - pr_post_map - (parse_pair - (parse_dependent_pair - parse_uint8 (* version *) - (fun v -> - parse_triple - parse_string (* augmentation *) - (if Nat_big_num.equal v(Nat_big_num.of_int 4) ||Nat_big_num.equal v(Nat_big_num.of_int 46) then pr_post_map parse_uint8 (fun i->Some i) else pr_return None) (* address_size *) - (if Nat_big_num.equal v(Nat_big_num.of_int 4) ||Nat_big_num.equal v(Nat_big_num.of_int 46) then pr_post_map parse_uint8 (fun i->Some i) else pr_return None))) (* segment_size *) - (parse_quadruple - parse_ULEB128 (* code_alignment_factor *) - parse_SLEB128 (* data_alignment_factor *) - parse_ULEB128 (* return address register *) - (parse_call_frame_instruction_bytes offset' ul))) - (fun ( (v,(aug,(mas',mss))), (caf,(daf,(rar,bs))) ) -> - let pc = ({pc_bytes = bs; pc_offset =(Nat_big_num.of_int 0) }) in - (match parse_call_frame_instructions c cuh pc with - | PR_success( is, _) -> - FIE_cie - ( - { - cie_offset = offset; - cie_length = ul; - cie_id = cie_id1; - cie_version = v; - cie_augmentation = aug; - cie_address_size = mas'; - cie_segment_size = mss; - cie_code_alignment_factor = caf; - cie_data_alignment_factor = daf; - cie_return_address_register = rar; - cie_initial_instructions_bytes = bs; - cie_initial_instructions = is; - }) - | PR_fail( s, _) -> failwith s - ) - ) - - else - (* parse fde *) - let cie1 = (find_cie fi cie_id1) in - let _ = (my_debug4 (pp_cie c cuh cie1)) in - pr_post_map - (parse_triple - (parse_initial_location c cuh cie1.cie_segment_size cie1.cie_address_size) (*(segment selector and target address)*) - (parse_uint_address_size c ((match cie1.cie_address_size with Some n -> n | None -> cuh.cuh_address_size ))) (* address_range (target address) *) - (parse_call_frame_instruction_bytes offset' ul) - ) - (fun ( (ss,adr), (ar, bs)) -> - let pc = ({pc_bytes = bs; pc_offset =(Nat_big_num.of_int 0) }) in - (match parse_call_frame_instructions c cuh pc with - | PR_success( is, _) -> - FIE_fde - ( - { - fde_offset = offset; - fde_length = ul; - fde_cie_pointer = cie_id1; - fde_initial_location_segment_selector = ss; - fde_initial_location_address = adr; - fde_address_range = ar; - fde_instructions_bytes = bs; - fde_instructions = is; - } ) - | PR_fail( s, _) -> failwith s - ) - ) - )) - -(* you can't even parse an fde without accessing the cie it refers to -(to determine the segment selector size). Gratuitous complexity or what? -Hence the following, which should be made more tail-recursive. *) - -(*val parse_dependent_list' : forall 'a. (list 'a -> parser 'a) -> list 'a -> parser (list 'a)*) -let rec parse_dependent_list' p1 acc:parse_context ->('a list)parse_result= - (fun pc -> - if (listEqualBy (=) pc.pc_bytes []) then - PR_success( (List.rev acc), pc) - else - pr_bind - (p1 acc pc) - (fun x pc' -> - parse_dependent_list' p1 (x::acc) pc')) - -(*val parse_dependent_list : forall 'a. (list 'a -> parser 'a) -> parser (list 'a)*) -let parse_dependent_list p1:parse_context ->('a list)parse_result= (parse_dependent_list' p1 []) - - -let parse_frame_info c cuh : frame_info parser= - -(parse_dependent_list (parse_frame_info_element c cuh)) - - -(** line numbers .debug_line, pp and parsing *) - -let pp_line_number_file_entry lnfe:string= - ("lnfe_path = " ^ (string_of_bytes lnfe.lnfe_path ^ ("\n" -^ ("lnfe_directory_index " ^ (Nat_big_num.to_string lnfe.lnfe_directory_index ^ ("\n" -^ ("lnfe_last_modification = " ^ (Nat_big_num.to_string lnfe.lnfe_last_modification ^ ("\n" -^ ("lnfe_length = " ^ (Nat_big_num.to_string lnfe.lnfe_length ^ "\n"))))))))))) - - -let pp_line_number_header lnh:string= - ("offset = " ^ (pphex lnh.lnh_offset ^ ("\n" -^ ("dwarf_format = " ^ (pp_dwarf_format lnh.lnh_dwarf_format ^ ("\n" -^ ("unit_length = " ^ (Nat_big_num.to_string lnh.lnh_unit_length ^ ("\n" -^ ("version = " ^ (Nat_big_num.to_string lnh.lnh_version ^ ("\n" -^ ("header_length = " ^ (Nat_big_num.to_string lnh.lnh_header_length ^ ("\n" -^ ("minimum_instruction_length = " ^ (Nat_big_num.to_string lnh.lnh_minimum_instruction_length ^ ("\n" -^ ("maximum_operations_per_instruction = " ^ (Nat_big_num.to_string lnh.lnh_maximum_operations_per_instruction ^ ("\n" -^ ("default_is_stmt = " ^ (string_of_bool lnh.lnh_default_is_stmt ^ ("\n" -^ ("line_base = " ^ (Nat_big_num.to_string lnh.lnh_line_base ^ ("\n" -^ ("line_range = " ^ (Nat_big_num.to_string lnh.lnh_line_range ^ ("\n" -^ ("opcode_base = " ^ (Nat_big_num.to_string lnh.lnh_opcode_base ^ ("\n" -^ ("standard_opcode_lengths = " ^ (string_of_list - instance_Show_Show_Num_natural_dict lnh.lnh_standard_opcode_lengths ^ ("\n" -^ ("include_directories = " ^ (myconcat ", " (Lem_list.map string_of_bytes lnh.lnh_include_directories) ^ ("\n" -^ ("file_names = \n\n" ^ (myconcat "\n" (Lem_list.map pp_line_number_file_entry lnh.lnh_file_names) ^ "\n"))))))))))))))))))))))))))))))))))))))))) - -let pp_line_number_operation lno:string= - ((match lno with - | DW_LNS_copy -> "DW_LNS_copy" - | DW_LNS_advance_pc n -> "DW_LNS_advance_pc" ^ (" " ^ Nat_big_num.to_string n) - | DW_LNS_advance_line i -> "DW_LNS_advance_line" ^ (" " ^ Nat_big_num.to_string i) - | DW_LNS_set_file n -> "DW_LNS_set_file" ^ (" " ^ Nat_big_num.to_string n) - | DW_LNS_set_column n -> "DW_LNS_set_column" ^ (" " ^ Nat_big_num.to_string n) - | DW_LNS_negate_stmt -> "DW_LNS_negate_stmt" - | DW_LNS_set_basic_block -> "DW_LNS_set_basic_block" - | DW_LNS_const_add_pc -> "DW_LNS_const_add_pc" - | DW_LNS_fixed_advance_pc n -> "DW_LNS_fixed_advance_pc" ^ (" " ^ Nat_big_num.to_string n) - | DW_LNS_set_prologue_end -> "DW_LNS_set_prologue_end" - | DW_LNS_set_epilogue_begin -> "DW_LNS_set_epilogue_begin" - | DW_LNS_set_isa n -> "DW_LNS_set_isa" ^ (" " ^ Nat_big_num.to_string n) - | DW_LNE_end_sequence -> "DW_LNE_end_sequence" - | DW_LNE_set_address n -> "DW_LNE_set_address" ^ (" " ^ pphex n) - | DW_LNE_define_file( s, n1, n2, n3) -> "DW_LNE_define_file" ^ (" " ^ (string_of_list - instance_Show_Show_Missing_pervasives_byte_dict s ^ (" " ^ (Nat_big_num.to_string n1 ^ (" " ^ (Nat_big_num.to_string n2 ^ (" " ^ Nat_big_num.to_string n3))))))) - | DW_LNE_set_discriminator n -> "DW_LNE_set_discriminator" ^ (" " ^ Nat_big_num.to_string n) - | DW_LN_special n -> "DW_LN_special" ^ (" " ^ Nat_big_num.to_string n) - )) - -let pp_line_number_program lnp:string= - (pp_line_number_header lnp.lnp_header - ^ ("[" ^ (myconcat ", " (Lem_list.map pp_line_number_operation lnp.lnp_operations) ^ "]\n"))) - - - -let parse_line_number_file_entry : ( line_number_file_entry option) parser= - -(parse_dependent - (parse_non_empty_string) - (fun ms -> - (match ms with - | None -> - pr_return None - | Some s -> - pr_post_map - (parse_triple - parse_ULEB128 - parse_ULEB128 - parse_ULEB128 - ) - (fun (n1,(n2,n3)) -> - (Some - { - lnfe_path = s; - lnfe_directory_index = n1; - lnfe_last_modification = n2; - lnfe_length = n3; - } ) - ) - ) - )) - -let parse_line_number_header c : line_number_header parser= - (parse_dependent - ((pr_with_pos - (parse_unit_length c) )) - (fun (pos,(df,ul)) -> - parse_dependent - (parse_pair - (parse_triple - (parse_uint16 c) (* version *) - (parse_uintDwarfN c df) (* header_length *) - (parse_uint8) (* minimum_instruction_length *) - (* (parse_uint8) (* maximum_operations_per_instruction *) NOT IN DWARF 2*) - ) - (parse_quadruple - (parse_uint8) (* default_is_stmt *) - (parse_sint8) (* line_base *) - (parse_uint8) (* line_range *) - (parse_uint8) (* opcode_base *) - )) - (fun ((v,(hl,(minil(*,maxopi*)))),(dis,(lb,(lr,ob)))) -> - pr_post_map - (parse_triple - (pr_post_map (parse_n_bytes (Nat_big_num.sub_nat ob(Nat_big_num.of_int 1))) (Lem_list.map natural_of_byte)) (* standard_opcode_lengths *) - ((*pr_return [[]]*) parse_list parse_non_empty_string) (* include_directories *) - (parse_list parse_line_number_file_entry) (* file names *) - ) - (fun (sols, (ids, fns)) -> - { - lnh_offset = pos; - lnh_dwarf_format = df; - lnh_unit_length = ul; - lnh_version = v; - lnh_header_length = hl; - lnh_minimum_instruction_length = minil; - lnh_maximum_operations_per_instruction =(Nat_big_num.of_int 1) (*maxopi*); - lnh_default_is_stmt = (not (Nat_big_num.equal dis(Nat_big_num.of_int 0))); - lnh_line_base = lb; - lnh_line_range = lr; - lnh_opcode_base = ob; - lnh_standard_opcode_lengths = sols; - lnh_include_directories = ids; - lnh_file_names = fns; - } - ) - ) - ) - ) - -let parser_of_line_number_argument_type c (cuh: compilation_unit_header) (lnat: line_number_argument_type) : line_number_argument_value parser= - ((match lnat with - | LNAT_address -> pr_map2 (fun n -> LNAV_address n) (parse_uint_address_size c cuh.cuh_address_size) - | LNAT_ULEB128 -> pr_map2 (fun n -> LNAV_ULEB128 n) (parse_ULEB128) - | LNAT_SLEB128 -> pr_map2 (fun i -> LNAV_SLEB128 i) (parse_SLEB128) - | LNAT_uint16 -> pr_map2 (fun n -> LNAV_uint16 n) (parse_uint16 c) - | LNAT_string -> pr_map2 (fun s -> LNAV_string s) (parse_string) - )) - -let parse_line_number_operation c (cuh: compilation_unit_header) (lnh: line_number_header) : line_number_operation parser= - (parse_dependent - parse_uint8 - (fun opcode -> - if Nat_big_num.equal opcode(Nat_big_num.of_int 0) then - (* parse extended opcode *) - parse_dependent - (parse_pair - parse_ULEB128 - parse_uint8) - (fun (size2,opcode') -> - (match lookup_aBcd_acd - instance_Basic_classes_Eq_Num_natural_dict opcode' line_number_extended_encodings with - | Some (_, arg_types, result) -> - let ps = (Lem_list.map (parser_of_line_number_argument_type c cuh) arg_types) in - parse_demaybe ("parse_line_number_operation fail") - (pr_post_map - (parse_parser_list ps) - result ) - | None -> - failwith ("parse_line_number_operation extended opcode not found: " ^ Nat_big_num.to_string opcode') - )) - (* it's not clear what the ULEB128 size field is for, as the extended opcides all seem to have well-defined sizes. perhaps there can be extra padding that needs to be absorbed? *) - else if Nat_big_num.greater_equal opcode lnh.lnh_opcode_base then - (* parse special opcode *) - let adjusted_opcode = (Nat_big_num.sub_nat opcode lnh.lnh_opcode_base) in - pr_return (DW_LN_special adjusted_opcode) - else - (* parse standard opcode *) - (match lookup_aBcd_acd - instance_Basic_classes_Eq_Num_natural_dict opcode line_number_standard_encodings with - | Some (_, arg_types, result) -> - let ps = (Lem_list.map (parser_of_line_number_argument_type c cuh) arg_types) in - parse_demaybe ("parse_line_number_operation fail") - (pr_post_map - (parse_parser_list ps) - result) - | None -> - failwith ("parse_line_number_operation standard opcode not found: " ^ Nat_big_num.to_string opcode) - (* the standard_opcode_lengths machinery is intended to allow vendor specific extension instructions to be parsed and ignored, but here we couldn't usefully process such instructions in any case, so we just fail *) - ))) - - -let parse_line_number_operations c (cuh:compilation_unit_header) (lnh:line_number_header) : ( line_number_operation list) parser= - (parse_list (parse_maybe (parse_line_number_operation c cuh lnh))) - - - (* assume operations start immediately after the header - not completely clear in DWARF whether the header_length is just an optimisation or whether it's intended to allow the operations to start later *) - (* line number operations have no no-op and no termination operation, so we have to cut down the available bytes to the right length *) - -let parse_line_number_program c (cuh:compilation_unit_header) : line_number_program parser= - (parse_dependent - (parse_line_number_header c) - (fun lnh -> - let byte_count_of_operations = (Nat_big_num.sub_nat - lnh.lnh_unit_length ( Nat_big_num.add (Nat_big_num.add lnh.lnh_header_length(Nat_big_num.of_int 2)) ((match lnh.lnh_dwarf_format with Dwarf32 ->Nat_big_num.of_int 4 | Dwarf64 ->Nat_big_num.of_int 8 )))) in - pr_post_map - (parse_restrict_length - byte_count_of_operations - (parse_line_number_operations c cuh lnh) - ) - (fun ops -> - { - lnp_header = lnh; - lnp_operations = ops; - }) - )) - -let parse_line_number_info c (d_line: char list) (cu: compilation_unit) : line_number_program= - (let f n= - (let d_line' = ((match mydrop n d_line with Some xs -> xs | None -> failwith "parse_line_number_info drop" )) in - let pc = ({ pc_bytes = d_line'; pc_offset = n}) in - (match parse_line_number_program c cu.cu_header pc with - | PR_success( lnp, pc') -> - (*let _ = print_endline (pp_line_number_program lnp) in*) - lnp - | PR_fail( s, pc') -> failwith ("parse_line_number_header failed: " ^ s) - )) in - (match find_attribute_value "DW_AT_stmt_list" cu.cu_die with - | Some (AV_sec_offset n) -> f n - | Some (AV_block( n, bs)) -> f (natural_of_bytes c.endianness bs) - (* a 32-bit MIPS example used a 4-byte AV_block not AV_sec_offset *) - | Some _ -> failwith "compilation unit DW_AT_stmt_list attribute was not an AV_sec_offset" - | _ -> failwith "compilation unit did not have a DW_AT_stmt_list attribute" - )) - - -let parse_line_number_infos c debug_line_section_body compilation_units1:(line_number_program)list= - - (Lem_list.map (parse_line_number_info c debug_line_section_body) compilation_units1) - -let pp_line_info li:string= - -(myconcat "\n" (Lem_list.map (pp_line_number_program) li)) - - -(** all dwarf info: pp and parsing *) - -let pp_dwarf d:string= - (let c : p_context = ({ endianness = (d.d_endianness) }) in - - "\n************** .debug_info section - abbreviated *****************\n" - ^ (pp_compilation_units_abbrev c d.d_str d.d_compilation_units - ^ ("\n************** .debug_info section - full ************************\n" - ^ (pp_compilation_units c d.d_str d.d_compilation_units - ^ ("\n************** .debug_loc section: location lists ****************\n" - ^ (let (cuh_default : compilation_unit_header) = (let cu = (myhead d.d_compilation_units) in cu.cu_header) in - pp_loc c cuh_default d.d_loc - ^ ("\n************** .debug_ranges section: range lists ****************\n" - ^ (pp_ranges c cuh_default d.d_ranges - ^ ("\n************** .debug_frame section: frame info ****************\n" - ^ (pp_frame_info c cuh_default d.d_frame_info - ^ ("\n************** .debug_line section: line number info ****************\n" - ^ pp_line_info d.d_line_info))))))))))) - - -let parse_dwarf c - (debug_info_section_body: char list) - (debug_abbrev_section_body: char list) - (debug_str_section_body: char list) - (debug_loc_section_body: char list) - (debug_ranges_section_body: char list) - (debug_frame_section_body: char list) - (debug_line_section_body: char list) - : dwarf= - - (let pc_info = ({pc_bytes = debug_info_section_body; pc_offset =(Nat_big_num.of_int 0) }) in - - let compilation_units1 = - ((match parse_compilation_units c debug_str_section_body debug_abbrev_section_body pc_info with - | PR_fail( s, pc_info') -> failwith ("parse_compilation_units: " ^ pp_parse_fail s pc_info') - | PR_success( cus, pc_info') -> cus - )) in - - (*let _ = my_debug5 (pp_compilation_units c debug_str_section_body compilation_units) in*) - - -(* the DWARF4 spec doesn't seem to specify the address size used in the .debug_loc section, so we (hackishly) take it from the first compilation unit *) - let (cuh_default : compilation_unit_header) = (let cu = (myhead compilation_units1) in cu.cu_header) in - - let pc_loc = ({pc_bytes = debug_loc_section_body; pc_offset =(Nat_big_num.of_int 0) }) in - - let loc = - ((match parse_location_list_list c cuh_default pc_loc with - | PR_fail( s, pc_info') -> failwith ("parse_location_list: " ^ pp_parse_fail s pc_info') - | PR_success( loc, pc_loc') -> loc - )) in - - let pc_ranges = ({pc_bytes = debug_ranges_section_body; pc_offset =(Nat_big_num.of_int 0) }) in - - let ranges = - ((match parse_range_list_list c cuh_default pc_ranges with - | PR_fail( s, pc_info') -> failwith ("parse_range_list: " ^ pp_parse_fail s pc_info') - | PR_success( r, pc_loc') -> r - )) in - - let pc_frame = ({pc_bytes = debug_frame_section_body; pc_offset =(Nat_big_num.of_int 0) }) in - - let fi = - (let _ = (my_debug5 ("debug_frame_section_body:\n" ^ ppbytes2 - instance_Show_Show_Missing_pervasives_byte_dict(Nat_big_num.of_int 0) debug_frame_section_body)) in - - (match parse_frame_info c cuh_default pc_frame with - | PR_fail( s, pc_info') -> failwith ("parse_frame_info: " ^ pp_parse_fail s pc_info') - | PR_success( fi, pc_loc') -> fi - )) in - - let li = (parse_line_number_infos c debug_line_section_body compilation_units1) in - - { - d_endianness = (c.endianness); - d_str = debug_str_section_body; - d_compilation_units = compilation_units1; - d_type_units = ([]); - d_loc = loc; - d_ranges = ranges; - d_frame_info = fi; - d_line_info = li; - }) - -(*val extract_dwarf : elf_file -> maybe dwarf*) -let extract_dwarf f:(dwarf)option= - - (let (en: Endianness.endianness) = - ((match f with - | ELF_File_32 f32 -> Elf_header.get_elf32_header_endianness f32.Elf_file.elf32_file_header - | ELF_File_64 f64 -> Elf_header.get_elf64_header_endianness f64.Elf_file.elf64_file_header - )) in - let (c: p_context) = ({ endianness = en }) in - let extract_section_body section_name (strict: bool)= - ((match f with - | ELF_File_32 f32 -> - let sections = - (List.filter - (fun x -> - x.Elf_interpreted_section.elf32_section_name_as_string = section_name - ) f32.elf32_file_interpreted_sections) in - (match sections with - | [section] -> - let section_body = ((match section.Elf_interpreted_section.elf32_section_body with Sequence bs -> bs )) in - let _ = (my_debug4 (section_name ^ (": \n" ^ (Elf_interpreted_section.string_of_elf32_interpreted_section section ^ ("\n" - ^ (" body = " ^ (ppbytes2 - instance_Show_Show_Missing_pervasives_byte_dict(Nat_big_num.of_int 0) section_body ^ "\n"))))))) in - section_body - | [] -> - if strict then - failwith ("" ^ (section_name ^ " section not present")) - else - [] - | _ -> failwith ("multiple " ^ (section_name ^ " sections present")) - ) - - - | ELF_File_64 f64 -> - let sections = - (List.filter - (fun x -> - x.Elf_interpreted_section.elf64_section_name_as_string = section_name - ) f64.elf64_file_interpreted_sections) in - (match sections with - | [section] -> - let section_body = ((match section.Elf_interpreted_section.elf64_section_body with Sequence bs -> bs )) in - section_body - | [] -> - if strict then - failwith ("" ^ (section_name ^ " section not present")) - else - [] - | _ -> failwith ("multiple " ^ (section_name ^ " sections present")) - ) - )) in - - let debug_info_section_body = (extract_section_body ".debug_info" true) in - let debug_abbrev_section_body = (extract_section_body ".debug_abbrev" false) in - let debug_str_section_body = (extract_section_body ".debug_str" false) in - let debug_loc_section_body = (extract_section_body ".debug_loc" false) in - let debug_ranges_section_body = (extract_section_body ".debug_ranges" false) in - let debug_frame_section_body = (extract_section_body ".debug_frame" false) in - let debug_line_section_body = (extract_section_body ".debug_line" false) in - - let d = (parse_dwarf c debug_info_section_body debug_abbrev_section_body debug_str_section_body debug_loc_section_body debug_ranges_section_body debug_frame_section_body debug_line_section_body) in - - Some d) - - -(** ************************************************************ *) -(** ****** location evaluation ******************************** *) -(** ************************************************************ *) - - -(** pp of locations *) - -(*val pp_simple_location : simple_location -> string*) -let pp_simple_location sl:string= - ((match sl with - | SL_memory_address n -> pphex n - | SL_register n -> "reg" ^ Nat_big_num.to_string n - | SL_implicit bs -> "value: " ^ ppbytes - instance_Show_Show_Missing_pervasives_byte_dict bs - | SL_empty -> "<empty>" - )) - -(*val pp_composite_location_piece : composite_location_piece -> string*) -let pp_composite_location_piece clp:string= - ((match clp with - | CLP_piece( n, sl) -> "piece (" ^ (Nat_big_num.to_string n ^ (") " ^ pp_simple_location sl)) - | CLP_bit_piece( n1, n2, sl) -> "bit_piece (" ^ (Nat_big_num.to_string n1 ^ ("," ^ (Nat_big_num.to_string n2 ^ (") " ^ pp_simple_location sl)))) - )) - -(*val pp_single_location: single_location -> string*) -let pp_single_location sl:string= - ((match sl with - | SL_simple sl -> pp_simple_location sl - | SL_composite clps -> "composite: " ^ myconcat ", " (Lem_list.map pp_composite_location_piece clps) - )) - - -(** evaluation of location expressions *) - -(* cf dwarflist, btw: https://fedorahosted.org/elfutils/wiki/DwarfLint?format=txt *) - -(* - -location description ::= -| single location description -| location list - -single location description ::= -| simple location description -| composite location description - -simple location description ::= -| memory location description : non-empty dwarf expr, value is address of all or part of object in memory -| register location description : single DW_OP_regN or DW_OP_regx, naming a register in which all the object is -| implicit location description : single DW_OP_implicit_value or a non-empty dwarf expr ending in DW_OP_stack_value, giving the value of all/part of object -| empty location description : an empty dwarf expr, indicating a part or all of an object that is not represented - -composite location description : a list of simple location descriptions, each followed by a DW_OP_piece or DW_OP_bitpiece - -(the simple location description can be a register location description: https://www.mail-archive.com/dwarf-discuss@lists.dwarfstd.org/msg00271.html) -(contradicting "A register location description must stand alone as the entire description of an object or a piece of an object.") - -location list entry : a list of address ranges (possibly overlapping), each with a single location description - -Dwarf expressions can include data-dependent control flow choices -(though we don't see that in the examples?), so we can't statically -determine which kind of single location description or simple location -description we have. We can distinguish: - -- empty -> simple.empty -- DW_OP_regN/DW_OP_regx -> simple.register -- DW_OP_implicit_value -> simple.implicit -- any of those followed by DW_OP_piece or DW_OP_bitpiece, perhaps followed by more composite parts -> composite part :: composite - -otherwise run to the end, or a DW_OP_stack_value at the end, or to -anything (except a DO_OP_regN/DW_OP_regx) followed by a -DW_OP_piece/DW_OP_bitpiece. Pfeh. - - -actually used in our examples (ignoring GNU extentions): - -DW_OP_addr literal -DW_OP_lit1 literal -DW_OP_const4u literal - -DW_OP_breg3 (r3) read register value and add offset - -DW_OP_and bitwise and -DW_OP_plus addition (mod whatever) - -DW_OP_deref_size -DW_OP_fbreg evaluate location description from DW_AT_frame_base attribute of the current function (which is DW_OP_call_frame_cfa in our examples) and add offset - -DW_OP_implicit_value the argument block is the actual value (not location) of the entity in question -DW_OP_stack_value use the value at top of stack as the actual value (not location) of the entity in question - -DW_OP_reg0 (r0)) read register value - -DW_OP_call_frame_cfa go off to 6.4 and pull info out of .debug_frame (possibly involving other location expressions) - -*) - - - -let initial_state:state= - ({ - s_stack = ([]); - s_value = SL_empty; - s_location_pieces = ([]); -}) - -(* the main location expression evaluation function *) - -(* location expression evaluation is basically a recursive function -down a list of operations, maintaining an operation_stack (a list of -naturals representing machine-address-size words), the current -simple_location, and a list of any composite_location_piece's -accumulated so far *) - - - -let arithmetic_context_of_cuh cuh:arithmetic_context= - ( - if(Nat_big_num.equal cuh.cuh_address_size (Nat_big_num.of_int 8)) then - ({ ac_bitwidth =(Nat_big_num.of_int 64); - ac_half = (Nat_big_num.pow_int (Nat_big_num.of_int 2) ( 32)); - ac_all = (Nat_big_num.pow_int (Nat_big_num.of_int 2) ( 64)); - ac_max = (Nat_big_num.sub_nat - (Nat_big_num.pow_int (Nat_big_num.of_int 2) ( 64)) - (Nat_big_num.of_int 1)); }) else - ( - if(Nat_big_num.equal cuh.cuh_address_size (Nat_big_num.of_int 4)) then - ({ ac_bitwidth =(Nat_big_num.of_int 32); - ac_half = (Nat_big_num.pow_int (Nat_big_num.of_int 2) ( 16)); - ac_all = (Nat_big_num.pow_int (Nat_big_num.of_int 2) ( 32)); - ac_max = (Nat_big_num.sub_nat - (Nat_big_num.pow_int (Nat_big_num.of_int 2) ( 32)) - (Nat_big_num.of_int 1)); }) else - (failwith "arithmetic_context_of_cuh given non-4/8 size"))) - -let find_cfa_table_row_for_pc (evaluated_frame_info1: evaluated_frame_info) (pc: Nat_big_num.num) : cfa_table_row= - ((match - myfind - (fun (fde1,rows) -> Nat_big_num.greater_equal pc fde1.fde_initial_location_address && Nat_big_num.less pc (Nat_big_num.add fde1.fde_initial_location_address fde1.fde_address_range)) - evaluated_frame_info1 - with - | Some (fde1,rows) -> - (match myfind (fun row -> Nat_big_num.greater_equal pc row.ctr_loc) rows with - | Some row -> row - | None -> failwith "evaluate_cfa: no matchine row" - ) - | None -> failwith "evaluate_cfa: no fde encloding pc" - )) - - -let rec evaluate_operation_list (c:p_context) (dloc: location_list_list) (evaluated_frame_info1: evaluated_frame_info) (cuh: compilation_unit_header) (ac: arithmetic_context) (ev: evaluation_context) (mfbloc: attribute_value option) (pc: Nat_big_num.num) (s: state) (ops: operation list) : single_location error= - - (let push_memory_address v vs'= (Success { s with s_stack = (v :: vs'); s_value = (SL_memory_address v) }) in - - let push_memory_address_maybe (mv: Nat_big_num.num option) vs' (err:string) op= - ((match mv with - | Some v -> push_memory_address v vs' - | None -> Fail (err ^ pp_operation op) - )) in - - let bregxi r i= - ((match ev.read_register r with - | RRR_result v -> push_memory_address (partialNaturalFromInteger ( Nat_big_num.modulus(Nat_big_num.add( v)i) ( ac.ac_all))) s.s_stack - | RRR_not_currently_available -> Fail "RRR_not_currently_available" - | RRR_bad_register_number -> Fail ("RRR_bad_register_number " ^ Nat_big_num.to_string r) - )) in - - let deref_size n= - ((match s.s_stack with - | v::vs' -> - (match ev.read_memory v n with - | MRR_result v' -> push_memory_address v' vs' - | MRR_not_currently_available -> Fail "MRR_not_currently_available" - | MRR_bad_address -> Fail "MRR_bad_address" - ) - | _ -> Fail "OpSem unary not given an element on stack" - )) in - - (match ops with - | [] -> - if (listEqualBy (=) s.s_location_pieces []) then - Success (SL_simple s.s_value) - else if s.s_value = SL_empty then - Success (SL_composite s.s_location_pieces) - else - (* unclear what's supposed to happen in this case *) - Fail "unfinished part of composite expression" - - | op::ops' -> - let es' = - ((match (op.op_semantics, op.op_argument_values) with - | (OpSem_nop, []) -> - Success s - | (OpSem_lit, [OAV_natural n]) -> - push_memory_address n s.s_stack - | (OpSem_lit, [OAV_integer i]) -> - push_memory_address (partialTwosComplementNaturalFromInteger i ac.ac_half ( ac.ac_all)) s.s_stack - | (OpSem_stack f, []) -> - (match f ac s.s_stack op.op_argument_values with - | Some stack' -> - let value' : simple_location = ((match stack' with [] -> SL_empty | v'::_ -> SL_memory_address v' )) in - Success { s with s_stack = stack'; s_value = value' } - | None -> Fail "OpSem_stack failed" - ) - | (OpSem_not_supported, []) -> - Fail ("OpSem_not_supported: " ^ pp_operation op) - | (OpSem_binary f, []) -> - (match s.s_stack with - | v1::v2::vs' -> push_memory_address_maybe (f ac v1 v2) vs' "OpSem_binary error: " op - | _ -> Fail "OpSem binary not given two elements on stack" - ) - | (OpSem_unary f, []) -> - (match s.s_stack with - | v1::vs' -> push_memory_address_maybe (f ac v1) vs' "OpSem_unary error: " op - | _ -> Fail "OpSem unary not given an element on stack" - ) - | (OpSem_opcode_lit base, []) -> - if Nat_big_num.greater_equal op.op_code base && Nat_big_num.less op.op_code (Nat_big_num.add base(Nat_big_num.of_int 32)) then - push_memory_address ( Nat_big_num.sub_nat op.op_code base) s.s_stack - else - Fail "OpSem_opcode_lit opcode not within [base,base+32)" - | (OpSem_reg, []) -> - (* TODO: unclear whether this should push the register id or not *) - let r = (Nat_big_num.sub_nat op.op_code vDW_OP_reg0) in - Success { s with s_stack = (r :: s.s_stack); s_value = (SL_register r) } - | (OpSem_breg, [OAV_integer i]) -> - let r = (Nat_big_num.sub_nat op.op_code vDW_OP_breg0) in - bregxi r i - | (OpSem_bregx, [OAV_natural r; OAV_integer i]) -> - bregxi r i - | (OpSem_deref, []) -> - deref_size cuh.cuh_address_size - | (OpSem_deref_size, [OAV_natural n]) -> - deref_size n - | (OpSem_fbreg, [OAV_integer i]) -> - (match mfbloc with - | Some fbloc -> - (*let _ = my_debug5 ("OpSem_fbreg (" ^ show i ^ ")\n") in*) - (match evaluate_location_description c dloc evaluated_frame_info1 cuh ac ev (*mfbloc*)None pc fbloc with - (* what to do if the recursive call also uses fbreg? for now assume that's not allowed *) - | Success l -> - (match l with - | SL_simple (SL_memory_address a) -> - (*let _ = my_debug5 ("OpSem_fbreg: a = "^ pphex a ^ "\n") in*) - let vi = (Nat_big_num.modulus ( Nat_big_num.add( a) i) ( ac.ac_all)) in - (*let _ = my_debug5 ("OpSem_fbreg: v = "^ show vi ^ "\n") in*) - let v = (partialNaturalFromInteger vi) (*ac.ac_half (integerFromNatural ac.ac_all)*) in - push_memory_address v s.s_stack - | _ -> - Fail "OpSem_fbreg got a non-SL_simple (SL_memory_address _) result" - (* "The DW_OP_fbreg operation provides a signed LEB128 - offset from the address specified by the location - description in the DW_AT_frame_base attribute of the - current function. " - - so what to do if the location description returns a non-memory-address location? *) - ) - | Fail e -> - Fail ("OpSem_fbreg failure: " ^ e) - ) - | None -> - Fail "OpSem_fbreg: no frame base location description given" - ) - - | (OpSem_piece, [OAV_natural size_bytes]) -> - let piece = (CLP_piece( size_bytes, s.s_value)) in - (* we allow a piece (or bit_piece) to be any simple_location, including implicit and stack values. Unclear if this is intended, esp. the latter *) - let stack' = ([]) in - let value' = SL_empty in - Success { s_stack = stack'; s_value = value'; s_location_pieces = (List.rev_append (List.rev s.s_location_pieces) [piece]) } - | (OpSem_bit_piece, [OAV_natural size_bits; OAV_natural offset_bits]) -> - let piece = (CLP_bit_piece( size_bits, offset_bits, s.s_value)) in - let stack' = ([]) in - let value' = SL_empty in - Success { s_stack = stack'; s_value = value'; s_location_pieces = (List.rev_append (List.rev s.s_location_pieces) [piece]) } - | (OpSem_implicit_value, [OAV_block( size2, bs)]) -> - let stack' = ([]) in - let value' = (SL_implicit bs) in - Success { s with s_stack = stack'; s_value = value' } - | (OpSem_stack_value, []) -> - (* "The DW_OP_stack_value operation terminates the expression." - does - this refer to just the subexpression, ie allowing a stack value to be - a piece of a composite location, or necessarily the whole expression? - Why does DW_OP_stack_value have this clause while DW_OP_implicit_value - does not? *) - (* why doesn't DW_OP_stack_value have a size argument? *) - (match s.s_stack with - | v::vs' -> - let stack' = ([]) in - let value' = (SL_implicit (bytes_of_natural c.endianness cuh.cuh_address_size v)) in - Success { s with s_stack = stack'; s_value = value' } - - | _ -> Fail "OpSem_stack_value not given an element on stack" - ) - | (OpSem_call_frame_cfa, []) -> - let row = (find_cfa_table_row_for_pc evaluated_frame_info1 pc) in - (match row.ctr_cfa with - | CR_undefined -> - failwith "evaluate_cfa of CR_undefined" - | CR_register( r, i) -> - bregxi r i (* same behaviour as an OpSem_bregx *) - | CR_expression bs -> - failwith "CR_expression" - (*TODO: fix result type - not this evaluate_location_description_bytes c dloc evaluated_frame_info cuh ac ev mfbloc pc bs*) - (* TODO: restrict allowed OpSem_* in that recursive call *) - ) - | (_, _) -> - Fail ("bad OpSem invocation: op=" ^ (pp_operation op ^ (" arguments=" ^ myconcat "" (Lem_list.map pp_operation_argument_value op.op_argument_values)))) - )) - in - (match es' with - | Success s' -> - evaluate_operation_list c dloc evaluated_frame_info1 cuh ac ev mfbloc pc s' ops' - | Fail e -> - Fail e - ) - )) - -and evaluate_location_description_bytes (c:p_context) (dloc: location_list_list) (evaluated_frame_info1: evaluated_frame_info) (cuh: compilation_unit_header) (ac: arithmetic_context) (ev: evaluation_context) (mfbloc: attribute_value option) (pc: Nat_big_num.num) (bs: char list) : single_location error= - (let parse_context1 = ({pc_bytes = bs; pc_offset =(Nat_big_num.of_int 0) }) in - (match parse_operations c cuh parse_context1 with - | PR_fail( s, pc') -> Fail ("evaluate_location_description_bytes: parse_operations fail: " ^ pp_parse_fail s pc') - | PR_success( ops, pc') -> - if not ((listEqualBy (=) pc'.pc_bytes [])) then - Fail "evaluate_location_description_bytes: extra non-parsed bytes" - else - evaluate_operation_list c dloc evaluated_frame_info1 cuh ac ev mfbloc pc initial_state ops - )) - -and evaluate_location_description (c:p_context) (dloc: location_list_list) (evaluated_frame_info1: evaluated_frame_info) (cuh: compilation_unit_header) (ac: arithmetic_context) (ev: evaluation_context) (mfbloc: attribute_value option) (pc: Nat_big_num.num) (loc:attribute_value) : single_location error= - ((match loc with - | AV_exprloc( n, bs) -> - evaluate_location_description_bytes c dloc evaluated_frame_info1 cuh ac ev mfbloc pc bs - | AV_block( n, bs) -> - evaluate_location_description_bytes c dloc evaluated_frame_info1 cuh ac ev mfbloc pc bs - | AV_sec_offset n -> - let location_list1 = (find_location_list dloc n) in - let (offset,(llis: location_list_item list)) = location_list1 in - let f (lli:location_list_item) : single_location_description option= - ((match lli with - | LLI_lle lle -> - if Nat_big_num.greater_equal pc lle.lle_beginning_address_offset && Nat_big_num.less pc lle.lle_ending_address_offset then Some lle.lle_single_location_description else None - | LLI_base _ -> - None (* TODO: either refactor to do offset during parsing or update base offsets here. Should refactor to use "interpreted". *) - )) in - (match myfindmaybe f llis with - | Some bs -> - evaluate_location_description_bytes c dloc evaluated_frame_info1 cuh ac ev mfbloc pc bs - | None -> - Fail "evaluate_location_description didn't find pc in location list ranges" - ) - | _ -> Fail "evaluate_location_description av_location not understood" - )) - - - - - -(** ************************************************************ *) -(** **** evaluation of frame information ********************** *) -(** ************************************************************ *) - -(** register maps *) - -(*val rrp_update : register_rule_map -> cfa_register -> register_rule -> register_rule_map*) -let rrp_update rrp r rr:(Nat_big_num.num*register_rule)list= ((r,rr)::rrp) - -(*val rrp_lookup : cfa_register -> register_rule_map -> register_rule*) -let rrp_lookup r rrp:register_rule= - ((match (lookupBy Nat_big_num.equal r rrp) with - | Some rr -> rr - | None -> RR_undefined - )) - -(*val rrp_empty : register_rule_map*) -let rrp_empty:(cfa_register*register_rule)list= ([]) - - - -(** pp of evaluated cfa information from .debug_frame *) -(* readelf --debug-dump=frames-interp test/a.out - -Contents of the .eh_frame section: - -00000000 00000014 00000000 CIE "zR" cf=1 df=-8 ra=16 - LOC CFA ra -0000000000000000 rsp+8 c-8 - -00000018 00000024 0000001c FDE cie=00000000 pc=004003b0..004003d0 - LOC CFA ra -00000000004003b0 rsp+16 c-8 -00000000004003b6 rsp+24 c-8 -00000000004003c0 exp c-8 - -00000040 0000001c 00000044 FDE cie=00000000 pc=004004b4..004004ba - LOC CFA rbp ra -00000000004004b4 rsp+8 u c-8 -00000000004004b5 rsp+16 c-16 c-8 -00000000004004b8 rbp+16 c-16 c-8 -00000000004004b9 rsp+8 c-16 c-8 - -00000060 00000024 00000064 FDE cie=00000000 pc=004004c0..00400549 - LOC CFA rbx rbp r12 r13 r14 r15 ra -00000000004004c0 rsp+8 u u u u u u c-8 -00000000004004d1 rsp+8 u c-48 c-40 u u u c-8 -00000000004004f0 rsp+64 c-56 c-48 c-40 c-32 c-24 c-16 c-8 -0000000000400548 rsp+8 c-56 c-48 c-40 c-32 c-24 c-16 c-8 - -00000088 00000014 0000008c FDE cie=00000000 pc=00400550..00400552 - LOC CFA ra -0000000000400550 rsp+8 c-8 - -000000a0 ZERO terminator -*) - - - -(*val mytoList : forall 'a. SetType 'a => set 'a -> list 'a*) - -let register_footprint_rrp (rrp: register_rule_map) : cfa_register Pset.set= - (Pset.from_list Nat_big_num.compare (Lem_list.map fst rrp)) - -let register_footprint (rows: cfa_table_row list) : cfa_register list= - (Pset.elements (bigunionListMap - instance_Basic_classes_SetType_Num_natural_dict (fun row -> register_footprint_rrp row.ctr_regs) rows)) - - -(*val max_lengths : list (list string) -> list natural*) -let rec max_lengths xss:(Nat_big_num.num)list= - ((match xss with - | [] -> failwith "max_lengths" - | xs::xss' -> - let lens = (Lem_list.map (fun x -> Nat_big_num.of_int (String.length x)) xs) in - if (listEqualBy (listEqualBy (=)) xss' []) then lens - else - let lens' = (max_lengths xss') in - let z = (Lem_list.list_combine lens lens') in - let lens'' = (Lem_list.map (fun (l1,l2)-> Nat_big_num.max l1 l2) z) in - lens'' - )) - -let rec pad_row xs lens:(string)list= - ((match (xs,lens) with - | ([],[]) -> [] - | (x::xs', len::lens') -> right_space_padded_to len x :: pad_row xs' lens' - )) - -let pad_rows (xss : ( string list) list) : string= - (let lens = (max_lengths xss) in - myconcat "" (Lem_list.map (fun xs -> myconcat " " (pad_row xs lens) ^ "\n") xss)) - -let pp_evaluated_fde (fde1, (rows: cfa_table_row list)) : string= - (let regs = (register_footprint rows) in - let header : string list = ("LOC" :: ("CFA" :: Lem_list.map - (pp_cfa_register instance_Show_Show_Num_natural_dict) regs)) in - let ppd_rows : ( string list) list = - (Lem_list.map (fun row -> pphex row.ctr_loc :: (pp_cfa_rule row.ctr_cfa :: Lem_list.map (fun r -> pp_register_rule (rrp_lookup r row.ctr_regs)) regs)) rows) in - pad_rows (header :: ppd_rows)) - - - -(** evaluation of cfa information from .debug_frame *) - -let evaluate_call_frame_instruction (fi: frame_info) (cie1: cie) (state1: cfa_state) (cfi: call_frame_instruction) : cfa_state= - - (let create_row (loc: Nat_big_num.num)= - (let row = ({ state1.cs_current_row with ctr_loc = loc }) in - { state1 with cs_current_row = row; cs_previous_rows = (state1.cs_current_row::state1.cs_previous_rows) }) in - - let update_cfa (cr:cfa_rule)= - (let row = ({ state1.cs_current_row with ctr_cfa = cr }) in - { state1 with cs_current_row = row }) in - - let update_reg r rr= - (let row = ({ state1.cs_current_row with ctr_regs = (rrp_update state1.cs_current_row.ctr_regs r rr) }) in - { state1 with cs_current_row = row }) in - - (match cfi with - (* Row Creation Instructions *) - | DW_CFA_set_loc a -> - create_row a - | DW_CFA_advance_loc d -> - create_row ( Nat_big_num.add state1.cs_current_row.ctr_loc (Nat_big_num.mul d cie1.cie_code_alignment_factor)) - | DW_CFA_advance_loc1 d -> - create_row ( Nat_big_num.add state1.cs_current_row.ctr_loc (Nat_big_num.mul d cie1.cie_code_alignment_factor)) - | DW_CFA_advance_loc2 d -> - create_row ( Nat_big_num.add state1.cs_current_row.ctr_loc (Nat_big_num.mul d cie1.cie_code_alignment_factor)) - | DW_CFA_advance_loc4 d -> - create_row ( Nat_big_num.add state1.cs_current_row.ctr_loc (Nat_big_num.mul d cie1.cie_code_alignment_factor)) - - (* CFA Definition Instructions *) - | DW_CFA_def_cfa( r, n) -> - update_cfa (CR_register( r, ( n))) - | DW_CFA_def_cfa_sf( r, i) -> - update_cfa (CR_register( r, ( Nat_big_num.mul i cie1.cie_data_alignment_factor))) - | DW_CFA_def_cfa_register r -> - (match state1.cs_current_row.ctr_cfa with - | CR_register( r', i) -> - update_cfa (CR_register( r, i)) - | _ -> failwith "DW_CFA_def_cfa_register: current rule is not CR_register" - ) - | DW_CFA_def_cfa_offset n -> - (match state1.cs_current_row.ctr_cfa with - | CR_register( r, i) -> - update_cfa (CR_register( r, ( n))) - | _ -> failwith "DW_CFA_def_cfa_offset: current rule is not CR_register" - ) - | DW_CFA_def_cfa_offset_sf i -> - (match state1.cs_current_row.ctr_cfa with - | CR_register( r, i') -> - update_cfa (CR_register( r, ( Nat_big_num.mul i' cie1.cie_data_alignment_factor))) - | _ -> failwith "DW_CFA_def_cfa_offset_sf: current rule is not CR_register" - ) - | DW_CFA_def_cfa_expression b -> - update_cfa (CR_expression b) - - (* Register Rule Instrutions *) - | DW_CFA_undefined r -> - update_reg r (RR_undefined) - | DW_CFA_same_value r -> - update_reg r (RR_same_value) - | DW_CFA_offset( r, n) -> - update_reg r (RR_offset ( Nat_big_num.mul( n) cie1.cie_data_alignment_factor)) - | DW_CFA_offset_extended( r, n) -> - update_reg r (RR_offset ( Nat_big_num.mul( n) cie1.cie_data_alignment_factor)) - | DW_CFA_offset_extended_sf( r, i) -> - update_reg r (RR_offset ( Nat_big_num.mul i cie1.cie_data_alignment_factor)) - | DW_CFA_val_offset( r, n) -> - update_reg r (RR_val_offset ( Nat_big_num.mul( n) cie1.cie_data_alignment_factor)) - | DW_CFA_val_offset_sf( r, i) -> - update_reg r (RR_val_offset ( Nat_big_num.mul i cie1.cie_data_alignment_factor)) - | DW_CFA_register( r1, r2) -> - update_reg r1 (RR_register r2) - | DW_CFA_expression( r, b) -> - update_reg r (RR_expression b) - | DW_CFA_val_expression( r, b) -> - update_reg r (RR_val_expression b) - | DW_CFA_restore r -> - update_reg r (rrp_lookup r state1.cs_initial_instructions_row.ctr_regs) -(* RR_undefined if the lookup fails? *) - | DW_CFA_restore_extended r -> - update_reg r (rrp_lookup r state1.cs_initial_instructions_row.ctr_regs) - -(* Row State Instructions *) -(* do these also push and restore the CFA rule? *) - | DW_CFA_remember_state -> - { state1 with cs_row_stack = (state1.cs_current_row :: state1.cs_row_stack) } - | DW_CFA_restore_state -> - (match state1.cs_row_stack with - | r::rs -> { state1 with cs_current_row = r; cs_row_stack = rs } - | [] -> failwith "DW_CFA_restore_state: empty row stack" - ) -(* Padding Instruction *) - | DW_CFA_nop -> - state1 - -(* Unknown *) - | DW_CFA_unknown b -> - failwith ("evaluate_call_frame_instruction: DW_CFA_unknown " ^ hex_string_of_byte b) - - )) - - - -let rec evaluate_call_frame_instructions (fi: frame_info) (cie1: cie) (state1: cfa_state) (cfis: call_frame_instruction list) : cfa_state= - ((match cfis with - | [] -> state1 - | cfi::cfis' -> - let state' = (evaluate_call_frame_instruction fi cie1 state1 cfi) in - evaluate_call_frame_instructions fi cie1 state' cfis' - )) - - -let evaluate_fde (fi: frame_info) (fde1:fde) : cfa_table_row list= - (let cie1 = (find_cie fi fde1.fde_cie_pointer) in - let final_location = (Nat_big_num.add fde1.fde_initial_location_address fde1.fde_address_range) in - let initial_cfa_state = - (let initial_row = - ({ - ctr_loc = (fde1.fde_initial_location_address); - ctr_cfa = CR_undefined; - ctr_regs = rrp_empty; - }) in - { - cs_current_row = initial_row; - cs_previous_rows = ([]); - cs_initial_instructions_row = initial_row; - cs_row_stack = ([]); - }) - in - let state' = - (evaluate_call_frame_instructions fi cie1 initial_cfa_state cie1.cie_initial_instructions) in - let initial_row' = (state'.cs_current_row) in - let state'' = ({ initial_cfa_state with cs_current_row = initial_row'; cs_initial_instructions_row = initial_row' }) in - let state''' = - (evaluate_call_frame_instructions fi cie1 (*final_location*) state'' fde1.fde_instructions) in - List.rev (state'''.cs_current_row:: state'''.cs_previous_rows)) - - - -(*val evaluate_frame_info : dwarf -> evaluated_frame_info*) -let evaluate_frame_info (d: dwarf) : evaluated_frame_info= - (Lem_list.mapMaybe (fun fie -> (match fie with FIE_fde fde1 -> Some (fde1, (evaluate_fde d.d_frame_info fde1)) | FIE_cie _ -> None )) d.d_frame_info) - -let pp_evaluated_frame_info (efi: evaluated_frame_info):string= - (myconcat "\n" (Lem_list.map pp_evaluated_fde efi)) - - - -(** ************************************************************ *) -(** ** analysis of location and frame data for reverse mapping *) -(** ************************************************************ *) - -(** analysis *) - -(*val find_dies_in_die : (die->bool) -> compilation_unit -> list die -> die -> list (compilation_unit * (list die) * die)*) -let rec find_dies_in_die (p:die->bool) (cu:compilation_unit) (parents: die list) (d: die):(compilation_unit*(die)list*die)list= - (let ds = (List.concat (map (find_dies_in_die p cu (d::parents)) d.die_children)) in - if p d then (cu,parents,d)::ds else ds) - -let find_dies (p:die->bool) (d: dwarf) : (compilation_unit * ( die list) * die) list= - (List.concat (map (fun cu -> find_dies_in_die p cu [] cu.cu_die) d.d_compilation_units)) - - -(** simple-minded analysis of location *) - -let analyse_locations_raw c (d: dwarf):string= - - (let (cuh_default : compilation_unit_header) = (let cu = (myhead d.d_compilation_units) in cu.cu_header) in - - (* find all DW_TAG_variable and DW_TAG_formal_parameter dies with a DW_AT_name attribute *) - let tags = (Lem_list.map tag_encode ["DW_TAG_variable"; "DW_TAG_formal_parameter"]) in - let dies : (compilation_unit * ( die list) * die) list = - (find_dies - (fun die1 -> - Lem_list.elem - instance_Basic_classes_Eq_Num_natural_dict die1.die_abbreviation_declaration.ad_tag tags - && has_attribute "DW_AT_name" die1) - d) in - - myconcat "" - (Lem_list.map - (fun (cu,parents,die1) -> - - let ats = (Lem_list.list_combine - die1.die_abbreviation_declaration.ad_attribute_specifications - die1.die_attribute_values) in - - let find_ats (s:string)= (myfindNonPure (fun (((at: Nat_big_num.num), (af: Nat_big_num.num)), ((pos: Nat_big_num.num),(av:attribute_value))) -> Nat_big_num.equal (attribute_encode s) at) ats) in - - let ((_,_),(_,av_name)) = (find_ats "DW_AT_name") in - - let name1 = - ((match av_name with - | AV_string bs -> string_of_bytes bs - | AV_strp n -> pp_debug_str_entry d.d_str n - | _ -> "av_name AV not understood" - )) in - - - let ((_,_),(_,av_location)) = (find_ats "DW_AT_location") in - - let ppd_location = - ((match av_location with - | AV_exprloc( n, bs) -> " "^(parse_and_pp_operations c cuh_default bs^"\n") - | AV_block( n, bs) -> " "^(parse_and_pp_operations c cuh_default bs^"\n") - | AV_sec_offset n -> - let location_list1 = (myfindNonPure (fun (n',_)->Nat_big_num.equal n' n) d.d_loc) in - pp_location_list c cuh_default location_list1 - | _ -> "av_location AV not understood" - )) in - - pp_tag_encoding die1.die_abbreviation_declaration.ad_tag ^ (" " ^ (name1 ^ (":\n" ^ (ppd_location ^ "\n")))) ) - - dies)) - - -(** more proper analysis of locations *) - -(* TODO: handle this: -In a variable entry representing the definition of a variable (that is, with no -DW_AT_declaration attribute) if no location attribute is present, or if the location attribute is -present but has an empty location description (as described in Section 2.6), the variable is -assumed to exist in the source code but not in the executable program (but see number 10, -below). -In a variable entry representing a non-defining declaration of a variable, the location -specified modifies the location specified by the defining declaration and only applies for the -scope of the variable entry; if no location is specified, then the location specified in the -defining declaration applies. -The location of a variable may be further specified with a DW_AT_segment attribute, if -appropriate. -*) - - -(* -if there's a DW_AT_location that's a location list (DW_FORM_sec_offset/AV_sec_offset) : use that for both the range(s) and location; interpret the range(s) wrt the applicable base address of the compilation unit - -if there's a DW_AT_location that's a location expression (DW_FORM_exprloc/AV_exprloc or DW_block/AV_block), look for the closest enclosing range: - - DW_AT_low_pc (AV_addr) and no DW_AT_high_pc or DW_AT_ranges: just the singleton address - - DW_AT_low_pc (AV_addr) and DW_AT_high_pc (either an absolute AV_addr or an offset AV_constantN/AV_constant_SLEB128/AV_constantULEB128) : that range - - DW_AT_ranges (DW_FORM_sec_offset/AV_sec_offset) : get a range list from .debug_ranges; interpret wrt the applicable base address of the compilation unit - - for compilation units: a DW_AT_ranges together with a DW_AT_low_pc to specify the default base address to use in interpeting location and range lists - -DW_OP_fbreg in location expressions evaluate the DW_AT_frame_base of -the closest enclosing function - which is either a location expression -or a location list (what happens if the ranges of that location list -don't cover where we are?) - -For each variable and formal parameter that has a DW_AT_name, we'll calculate a list of pairs of a concrete (low,high) range and a location expression. -*) - -let rec closest_enclosing_range c (dranges: range_list_list) (cu_base_address1: Nat_big_num.num) (parents: die list) : ( (Nat_big_num.num * Nat_big_num.num)list)option= - ((match parents with - | [] -> None - | die1::parents' -> - (match (find_attribute_value "DW_AT_low_pc" die1, find_attribute_value "DW_AT_high_pc" die1, find_attribute_value "DW_AT_ranges" die1) with - | (Some (AV_addr n), None, None ) -> Some [(n,Nat_big_num.add n(Nat_big_num.of_int 1))] (* unclear if this case is used? *) - | (Some (AV_addr n1), Some (AV_addr n2), None ) -> Some [(n1,n2)] - | (Some (AV_addr n1), Some (AV_constant_ULEB128 n2), None ) -> Some [(n1,Nat_big_num.add n1 n2)] (* should be mod all? *) - | (Some (AV_addr n1), Some (AV_constant_SLEB128 i2), None ) -> Some [(n1, Nat_big_num.abs ( Nat_big_num.add( n1) i2))] (* should - be mod all? *) - | (Some (AV_addr n1), Some (AV_constantN( _, _)), None ) -> failwith "AV_constantN in closest_enclosing_range" - - | (Some (AV_addr n1), Some (AV_block( n, bs)), None ) -> let n2 = (natural_of_bytes c.endianness bs) in Some [(n1,Nat_big_num.add n1 n2)] (* should be mod all? *) (* signed or unsigned interp? *) - - | (_, None, Some (AV_sec_offset n)) -> - let rlis = (snd (find_range_list dranges n)) in - let nns = (interpret_range_list cu_base_address1 rlis) in - Some nns - | (None, None, None ) -> closest_enclosing_range c dranges cu_base_address1 parents' - | (_, _, _ ) -> Some [] (*Assert_extra.failwith "unexpected attribute values in closest_enclosing_range"*) - ) - )) - -(* -If one of the DW_FORM_data<n> forms is used to represent a signed or unsigned integer, it -can be hard for a consumer to discover the context necessary to determine which -interpretation is intended. Producers are therefore strongly encouraged to use -DW_FORM_sdata or DW_FORM_udata for signed and unsigned integers respectively, -rather than DW_FORM_data<n>. -no kidding - if we get an AV_constantN for DW_AT_high_pc, should it be interpreted as signed or unsigned? *) - - -let rec closest_enclosing_frame_base dloc (base_address1: Nat_big_num.num) (parents: die list) : attribute_value option= - ((match parents with - | [] -> None - | die1::parents' -> - (match find_attribute_value "DW_AT_frame_base" die1 with - | Some av -> Some av - | None -> closest_enclosing_frame_base dloc base_address1 parents' - ) - )) - - - - -let interpreted_location_of_die c cuh (dloc: location_list_list) (dranges: range_list_list) (base_address1: Nat_big_num.num) (parents: die list) (die1: die) : ( (Nat_big_num.num * Nat_big_num.num * single_location_description)list)option= -( - - (* for a simple location expression bs, we look in the enclosing die - tree to find the associated pc range *)let location bs= - ((match closest_enclosing_range c dranges base_address1 (die1::parents) with - | Some nns -> - Some (Lem_list.map (fun (n1,n2) -> (n1,n2,bs)) nns) - | None -> - (* if there is no such range, we take the full 0 - 0xfff.fff range*) - Some [(Nat_big_num.of_int 0,(arithmetic_context_of_cuh cuh).ac_max,bs)] - )) in - - (match find_attribute_value "DW_AT_location" die1 with - | Some (AV_exprloc( n, bs)) -> location bs - | Some (AV_block( n, bs)) -> location bs - (* while for a location list, we take the associated pc range from - each element of the list *) - | Some (AV_sec_offset n) -> - let (_,llis) = (find_location_list dloc n) in - Some (interpret_location_list base_address1 llis) - | None -> None - )) - - -let cu_base_address cu:Nat_big_num.num= - ((match find_attribute_value "DW_AT_low_pc" cu.cu_die with - | Some (AV_addr n) -> n - | _ ->Nat_big_num.of_int 0 (*Nothing*) (*Assert_extra.failwith "no cu DW_AT_low_pc"*) - )) - - -(*val analyse_locations : dwarf -> analysed_location_data*) -let analyse_locations (d: dwarf) : analysed_location_data= - - (let c : p_context = ({ endianness = (d.d_endianness) }) in - - let (cuh_default : compilation_unit_header) = (let cu = (myhead d.d_compilation_units) in cu.cu_header) in - - (* find all DW_TAG_variable and DW_TAG_formal_parameter dies with a DW_AT_name and DW_AT_location attribute *) - let tags = (Lem_list.map tag_encode ["DW_TAG_variable"; "DW_TAG_formal_parameter"]) in - let dies : (compilation_unit * ( die list) * die) list = - (find_dies - (fun die1 -> - Lem_list.elem - instance_Basic_classes_Eq_Num_natural_dict die1.die_abbreviation_declaration.ad_tag tags - && (has_attribute "DW_AT_name" die1 - && has_attribute "DW_AT_location" die1)) - d) in - - Lem_list.map - (fun ((((cu:compilation_unit), (parents: die list), (die1: die)) as x)) -> - let base_address1 = (cu_base_address cu) in - let interpreted_locations : ( (Nat_big_num.num * Nat_big_num.num * single_location_description)list)option = - (interpreted_location_of_die c cuh_default d.d_loc d.d_ranges base_address1 parents die1) in - (x,interpreted_locations) - ) - dies) - - - -let pp_analysed_locations1 c cuh (nnls: (Nat_big_num.num * Nat_big_num.num * single_location_description) list) : string= - (myconcat "" - (Lem_list.map - (fun (n1,n2,bs) -> " " ^ (pphex n1 ^ (" " ^ (pphex n2 ^ (" " ^ (parse_and_pp_operations c cuh bs ^ "\n")))))) - nnls)) - -let pp_analysed_locations2 c cuh mnnls:string= - ((match mnnls with - | Some nnls -> pp_analysed_locations1 c cuh nnls - | None -> " <no locations>\n" - )) - -let pp_analysed_locations3 c cuh str (als: analysed_location_data) : string= - (myconcat "\n" - (Lem_list.map - (fun ((cu,parents,die1),mnnls) -> - pp_die_abbrev c cuh str(Nat_big_num.of_int 0) false parents die1 - ^ pp_analysed_locations2 c cuh mnnls - ) - als - )) - -let pp_analysed_location_data (d: dwarf) (als: analysed_location_data) : string= - (let c : p_context = ({ endianness = (d.d_endianness) }) in - let (cuh_default : compilation_unit_header) = (let cu = (myhead d.d_compilation_units) in cu.cu_header) in - pp_analysed_locations3 c (*HACK*) cuh_default d.d_str als) - - - -let pp_analysed_location_data_at_pc (d: dwarf) (alspc: analysed_location_data_at_pc) : string= - (myconcat "" (Lem_list.map - (fun ((cu,parents,die1),(n1,n2,sld,esl)) -> - " " ^ - (let name1 = - ((match find_name_of_die d.d_str die1 with - | Some s -> s - | None -> "<no name>\n" - )) in - (match esl with - | Success sl -> - name1 ^ (" @ " ^ (pp_single_location sl ^"\n")) - - | Fail e -> name1 ^ (" @ " ^ ("<fail: " ^ (e ^ ">\n"))) - )) - ) - alspc)) - - -(*val analysed_locations_at_pc : evaluation_context -> dwarf_static -> natural -> analysed_location_data_at_pc*) -let analysed_locations_at_pc - (ev) - (ds: dwarf_static) - (pc: Nat_big_num.num) - : analysed_location_data_at_pc= - -(let c : p_context = ({ endianness = (ds.ds_dwarf.d_endianness) }) in - - let xs = - (Lem_list.mapMaybe - (fun (cupd,mnns) -> - (match mnns with - | None -> None - | Some nns -> - let nns' = (List.filter (fun (n1,n2,sld) -> Nat_big_num.greater_equal pc n1 && Nat_big_num.less pc n2) nns) in - (match nns' with - | [] -> None - | _ -> Some (cupd,nns') - ) - )) - ds.ds_analysed_location_data) -in - -List.concat - (Lem_list.map - (fun ((cu,parents,die1),nns) -> - let ac = (arithmetic_context_of_cuh cu.cu_header) in - let base_address1 = (cu_base_address cu) in - let mfbloc : attribute_value option = - (closest_enclosing_frame_base ds.ds_dwarf.d_loc base_address1 parents) in - Lem_list.map - (fun (n1,n2,sld) -> - let el : single_location error = - (evaluate_location_description_bytes c ds.ds_dwarf.d_loc ds.ds_evaluated_frame_info cu.cu_header ac ev mfbloc pc sld) in - ((cu,parents,die1),(n1,n2,sld,el)) - ) - nns - ) - xs)) - -(*val names_of_address : dwarf -> analysed_location_data_at_pc -> natural -> list string*) -let names_of_address - (d: dwarf) - (alspc: analysed_location_data_at_pc) - (address: Nat_big_num.num) - : string list= - -(Lem_list.mapMaybe - (fun ((cu,parents,die1),(n1,n2,sld,esl)) -> - (match esl with - | Success (SL_simple (SL_memory_address a)) -> - if Nat_big_num.equal a address then - (match find_name_of_die d.d_str die1 with - | Some s -> Some s - | None -> None - ) - else - None - | Success _ -> None (* just suppress? *) - | Fail e -> None (* just suppress? *) - ) - ) - alspc) - - -(** ************************************************************ *) -(** ** evaluation of line-number info *) -(** ************************************************************ *) - -let initial_line_number_registers (lnh: line_number_header) : line_number_registers= - ({ - lnr_address =(Nat_big_num.of_int 0); - lnr_op_index =(Nat_big_num.of_int 0); - lnr_file =(Nat_big_num.of_int 1); - lnr_line =(Nat_big_num.of_int 1); - lnr_column =(Nat_big_num.of_int 0); - lnr_is_stmt = (lnh.lnh_default_is_stmt); - lnr_basic_block = false; - lnr_end_sequence = false; - lnr_prologue_end = false; - lnr_epilogue_begin = false; - lnr_isa =(Nat_big_num.of_int 0); - lnr_discriminator =(Nat_big_num.of_int 0); - }) - -let evaluate_line_number_operation - (lnh: line_number_header) - ((s: line_number_registers), (lnrs: line_number_registers list)) - (lno: line_number_operation) - : line_number_registers * line_number_registers list= - - (let new_address s operation_advance= (Nat_big_num.add s.lnr_address (Nat_big_num.mul - lnh.lnh_minimum_instruction_length - (Nat_big_num.div( Nat_big_num.add s.lnr_op_index operation_advance)lnh.lnh_maximum_operations_per_instruction))) in - let new_op_index s operation_advance= (Nat_big_num.modulus - ( Nat_big_num.add s.lnr_op_index operation_advance) lnh.lnh_maximum_operations_per_instruction) in - - (match lno with - | DW_LN_special adjusted_opcode -> - let operation_advance = (Nat_big_num.div adjusted_opcode lnh.lnh_line_range) in - let line_increment = (Nat_big_num.add lnh.lnh_line_base (( Nat_big_num.modulus adjusted_opcode lnh.lnh_line_range))) in - let s' = - ({ s with - lnr_line = (partialNaturalFromInteger ( Nat_big_num.add( s.lnr_line) line_increment)); - lnr_address = (new_address s operation_advance); - lnr_op_index = (new_op_index s operation_advance); - }) in - let lnrs' = (s'::lnrs) in - let s'' = -({ s' with - lnr_basic_block = false; - lnr_prologue_end = false; - lnr_epilogue_begin = false; - lnr_discriminator =(Nat_big_num.of_int 0); - }) in - (s'', lnrs') - | DW_LNS_copy -> - let lnrs' = (s::lnrs) in - let s' = -({ s with - lnr_basic_block = false; - lnr_prologue_end = false; - lnr_epilogue_begin = false; - lnr_discriminator =(Nat_big_num.of_int 0); - }) in - (s', lnrs') - | DW_LNS_advance_pc operation_advance -> - let s' = - ({ s with - lnr_address = (new_address s operation_advance); - lnr_op_index = (new_op_index s operation_advance); - }) in - (s', lnrs) - | DW_LNS_advance_line line_increment -> - let s' = ({ s with lnr_line = (partialNaturalFromInteger ( Nat_big_num.add( s.lnr_line) line_increment)) }) in (s', lnrs) - | DW_LNS_set_file n -> - let s' = ({ s with lnr_file = n }) in (s', lnrs) - | DW_LNS_set_column n -> - let s' = ({ s with lnr_column = n }) in (s', lnrs) - | DW_LNS_negate_stmt -> - let s' = ({ s with lnr_is_stmt = (not s.lnr_is_stmt) }) in (s', lnrs) - | DW_LNS_set_basic_block -> - let s' = ({ s with lnr_basic_block = true }) in (s', lnrs) - | DW_LNS_const_add_pc -> - let opcode =(Nat_big_num.of_int 255) in - let adjusted_opcode = (Nat_big_num.sub_nat opcode lnh.lnh_opcode_base) in - let operation_advance = (Nat_big_num.div adjusted_opcode lnh.lnh_line_range) in - let s' = - ({ s with - lnr_address = (new_address s operation_advance); - lnr_op_index = (new_op_index s operation_advance); - }) in - (s', lnrs) - | DW_LNS_fixed_advance_pc n -> - let s' = - ({ s with - lnr_address = (Nat_big_num.add s.lnr_address n); - lnr_op_index =(Nat_big_num.of_int 0); - }) in - (s', lnrs) - | DW_LNS_set_prologue_end -> - let s' = ({ s with lnr_prologue_end = true }) in (s', lnrs) - | DW_LNS_set_epilogue_begin -> - let s' = ({ s with lnr_epilogue_begin = true }) in (s', lnrs) - | DW_LNS_set_isa n -> - let s' = ({ s with lnr_isa = n }) in (s', lnrs) - | DW_LNE_end_sequence -> - let s' = ({ s with lnr_end_sequence = true }) in - let lnrs' = (s' :: lnrs) in - let s'' = (initial_line_number_registers lnh) in - (s'', lnrs') - | DW_LNE_set_address n -> - let s' = - ({ s with - lnr_address = n; - lnr_op_index =(Nat_big_num.of_int 0); - }) in - (s', lnrs) - | DW_LNE_define_file( s, n1, n2, n3) -> - failwith "DW_LNE_define_file not implemented" (*TODO: add to file list in header - but why is this in the spec? *) - | DW_LNE_set_discriminator n -> - let s' = ({ s with lnr_discriminator = n }) in (s', lnrs) - )) - -let rec evaluate_line_number_operations - (lnh: line_number_header) - ((s: line_number_registers), (lnrs: line_number_registers list)) - (lnos: line_number_operation list) - : line_number_registers * line_number_registers list= - ((match lnos with - | [] -> (s,lnrs) - | lno :: lnos' -> - let (s',lnrs') = - (evaluate_line_number_operation lnh (s,lnrs) lno) in - evaluate_line_number_operations lnh (s',lnrs') lnos' - )) - -let evaluate_line_number_program - (lnp:line_number_program) - : line_number_registers list= - (List.rev (snd (evaluate_line_number_operations lnp.lnp_header ((initial_line_number_registers lnp.lnp_header),[]) lnp.lnp_operations))) - - -let pp_line_number_registers lnr:string= - ("" - ^ ("address = " ^ (pphex lnr.lnr_address ^ ("\n" - ^ ("op_index = " ^ (Nat_big_num.to_string lnr.lnr_op_index ^ ("\n" - ^ ("file = " ^ (Nat_big_num.to_string lnr.lnr_file ^ ("\n" - ^ ("line = " ^ (Nat_big_num.to_string lnr.lnr_line ^ ("\n" - ^ ("column = " ^ (Nat_big_num.to_string lnr.lnr_column ^ ("\n" - ^ ("is_stmt = " ^ (string_of_bool lnr.lnr_is_stmt ^ ("\n" - ^ ("basic_block = " ^ (string_of_bool lnr.lnr_basic_block ^ ("\n" - ^ ("end_sequence = " ^ (string_of_bool lnr.lnr_end_sequence ^ ("\n" - ^ ("prologue_end = " ^ (string_of_bool lnr.lnr_prologue_end ^ ("\n" - ^ ("epilogue_begin = " ^ (string_of_bool lnr.lnr_epilogue_begin ^ ("\n" - ^ ("isa = " ^ (Nat_big_num.to_string lnr.lnr_isa ^ ("\n" - ^ ("discriminator = " ^ (pphex lnr.lnr_discriminator ^ "\n")))))))))))))))))))))))))))))))))))) - -let pp_line_number_registers_tight lnr : string list= - ([ - pphex lnr.lnr_address ; - Nat_big_num.to_string lnr.lnr_op_index ; - Nat_big_num.to_string lnr.lnr_file ; - Nat_big_num.to_string lnr.lnr_line ; - Nat_big_num.to_string lnr.lnr_column ; - string_of_bool lnr.lnr_is_stmt ; - string_of_bool lnr.lnr_basic_block ; - string_of_bool lnr.lnr_end_sequence ; - string_of_bool lnr.lnr_prologue_end ; - string_of_bool lnr.lnr_epilogue_begin ; - Nat_big_num.to_string lnr.lnr_isa ; - pphex lnr.lnr_discriminator - ]) - -let pp_line_number_registerss lnrs:string= - (pad_rows - ( - ["address"; "op_index"; "file"; "line"; "column"; "is_stmt"; "basic_block"; "end_sequence"; "prologue_end"; "epilogue_begin"; "isa"; "discriminator"] - :: - (Lem_list.map pp_line_number_registers_tight lnrs) - )) - -let pp_evaluated_line_info (eli: evaluated_line_info) : string= - (myconcat "\n" (Lem_list.map (fun (lnh,lnrs) -> pp_line_number_header lnh ^ ("\n" ^ pp_line_number_registerss lnrs)) eli)) - -(* readef example: -Decoded dump of debug contents of section .debug_line: - -CU: /var/local/stephen/work/devel/rsem/ppcmem2/system/tests-adhoc/simple-malloc/test-concurrent.c: -File name Line number Starting address -test-concurrent.c 11 0x400144 - -test-concurrent.c 12 0x40014c -test-concurrent.c 13 0x400154 -test-concurrent.c 14 0x400158 -test-concurrent.c 17 0x400160 - -/var/local/stephen/work/devel/rsem/ppcmem2/system/tests-adhoc/simple-malloc/../thread_start_aarch64.h: -thread_start_aarch64.h 34 0x400168 -thread_start_aarch64.h 36 0x400174 - -/var/local/stephen/work/devel/rsem/ppcmem2/system/tests-adhoc/simple-malloc/test-concurrent.c: -test-concurrent.c 19 0x400174 - -test-concurrent.c 20 0x40017c -test-concurrent.c 22 0x400180 - -CU: /var/local/stephen/work/devel/rsem/ppcmem2/system/tests-adhoc/simple-malloc/malloc.c: -... -*) - - -let source_lines_of_address (ds:dwarf_static) (a: Nat_big_num.num) : (string * Nat_big_num.num * line_number_registers) list= - (List.concat - (Lem_list.map - (fun (lnh, lnrs) -> - myfiltermaybe - (fun lnr -> - if Nat_big_num.equal a lnr.lnr_address && not lnr.lnr_end_sequence then - (match mynth ( Nat_big_num.sub_nat lnr.lnr_file(Nat_big_num.of_int 1)) lnh.lnh_file_names with - | Some lnfe -> - Some (string_of_bytes lnfe.lnfe_path, lnr.lnr_line, lnr) - | None -> - Some ("<source_lines_of_address: file entry not found>",Nat_big_num.of_int 0, lnr) - ) - else - None) - lnrs - ) - ds.ds_evaluated_line_info - )) - - -(** ************************************************************ *) -(** ** collecting all the statically calculated analysis info *) -(** ************************************************************ *) - -(*val extract_dwarf_static : elf_file -> maybe dwarf_static*) -let extract_dwarf_static f1:(dwarf_static)option= - ((match extract_dwarf f1 with - | None -> None - | Some dwarf1 -> - let _ = (my_debug5 (pp_dwarf dwarf1)) in - - let ald : analysed_location_data = - (analyse_locations dwarf1) in - let efi : evaluated_frame_info = - (evaluate_frame_info dwarf1) in - let eli : evaluated_line_info = - (Lem_list.map (fun lnp -> (lnp.lnp_header, evaluate_line_number_program lnp)) dwarf1.d_line_info) in - let ds = - ({ - ds_dwarf = dwarf1; - ds_analysed_location_data = ald; - ds_evaluated_frame_info = efi; - ds_evaluated_line_info = eli; - }) in - Some ds - )) - - - - -(** ************************************************************ *) -(** ** top level for main_elf ******************************** *) -(** ************************************************************ *) - -(*val harness_string_of_elf : elf_file -> byte_sequence -> string*) -let harness_string_of_elf f1 bs:string= - (let mds = (extract_dwarf_static f1) in - (match mds with - | None -> "<no dwarf information extracted>" - | Some ds -> - pp_dwarf ds.ds_dwarf - (* ^ analyse_locations_raw c d *) - ^ ("************** evaluation of frame data *************************\n" - ^ (pp_evaluated_frame_info ds.ds_evaluated_frame_info - ^ ("************** analysis of location data *************************\n" - ^ (pp_analysed_location_data ds.ds_dwarf ds.ds_analysed_location_data - ^ ("************** line info *************************\n" - ^ pp_evaluated_line_info ds.ds_evaluated_line_info))))) - )) - - -(*val harness_string_of_elf64_debug_info_section : elf64_file -> byte_sequence -> (*(natural -> string) -> (natural -> string) -> (natural -> string) -> elf64_header -> elf64_section_header_table -> string_table -> *) string*) -let harness_string_of_elf64_debug_info_section f1 bs0:string= - ( (*os proc usr hdr sht stbl*)harness_string_of_elf (ELF_File_64 f1) bs0) - -(*val harness_string_of_elf32_debug_info_section : elf32_file -> byte_sequence -> (* (natural -> string) -> (natural -> string) -> (natural -> string) -> elf32_header -> elf32_section_header_table -> string_table ->*) string*) -let harness_string_of_elf32_debug_info_section f1 bs0:string= - ( (*os proc usr hdr sht stbl*)harness_string_of_elf (ELF_File_32 f1) bs0) - diff --git a/lib/ocaml_rts/linksem/elf64_file_of_elf_memory_image.ml b/lib/ocaml_rts/linksem/elf64_file_of_elf_memory_image.ml deleted file mode 100644 index b9366d2c..00000000 --- a/lib/ocaml_rts/linksem/elf64_file_of_elf_memory_image.ml +++ /dev/null @@ -1,491 +0,0 @@ -(*Generated by Lem from elf64_file_of_elf_memory_image.lem.*) -open Lem_basic_classes -open Lem_function -open Lem_string -open Lem_tuple -open Lem_bool -open Lem_list -open Lem_sorting -open Lem_map -(*import Set*) -open Lem_num -open Lem_maybe -open Lem_assert_extra - -open Byte_sequence -open Default_printing -open Error -open Missing_pervasives -open Show -open Endianness - -open Elf_header -open Elf_file -open Elf_interpreted_section -open Elf_interpreted_segment -open Elf_section_header_table -open Elf_program_header_table -open Elf_symbol_table -open Elf_types_native_uint -open Elf_relocation -open String_table - -open Memory_image -open Memory_image_orderings - -open Elf_memory_image -open Elf_memory_image_of_elf64_file -open Abis - -(* Things the caller should do first: *) -(* - create segment annotations *) -(* - create .dynamic-equivalent metadata (but not the section) *) -(* - concretise symbolic elements? actually they pass a function to do this. *) - -type make_concrete_fn = Memory_image.element -> Memory_image.element - -(* Things we do, at the caller's direction:*) -(* - create SHT *) -(* - create symtabs, strtabs, symbol hash tables (the ABI helps us) *) -(* - create shstrtab (if we're creating a SHT) *) -(* - actually create the dynamic section (and its PHDR) *) -(* - create any other PHDRs (the ABI tells us, mostly) and PT_PHDR (the user tells us) *) - -(*val elf64_file_of_elf_memory_image : abi any_abi_feature -> make_concrete_fn -> string -> elf_memory_image -> elf64_file*) -let elf64_file_of_elf_memory_image a make_concrete fname1 img2:elf64_file= -( - (* Generate an ELF header, (optionally) SHT and (optionally) PHT, - * based on metadata in the image. - * - * How do we decide what kind of ELF file to generate? see whether we have segment annotations? - what architecture/osabi to give? the ABI tells us - - *)let (section_tags, section_ranges) = (elf_memory_image_section_ranges img2) - in - let section_tags_bare = (Lem_list.map (fun tag -> - (match tag with - | FileFeature(ElfSection(idx1, isec1)) -> (idx1, isec1) - | _ -> failwith "not section tag" - )) section_tags) - in - let section_tags_bare_noidx = (Lem_list.map (fun (idx1, isec1) -> isec1) section_tags_bare) - in - let basic_shstrtab = (List.fold_left (fun table -> (fun str -> - let (_, t) = (String_table.insert_string str table) in t - )) String_table.empty0 [".shstrtab"; ".symtab"; ".strtab"]) - in - let shstrtab = (List.fold_left (fun table -> fun (idx1, isec1) -> - let (_, t) = (String_table.insert_string isec1.elf64_section_name_as_string table) in - (* let _ = errln ("Adding section name `" ^ isec.elf64_section_name_as_string ^ "' to shstrtab; now has size " - ^ (show (String_table.size t))) - in *) t - ) basic_shstrtab section_tags_bare) - in - let phoff =(Nat_big_num.of_int 64) - in - let max_phnum1 = ( (* length phdrs *)a.max_phnum) - in - (* what do we generate? - * .eh_frame? no, *should* come from the script - * .got, .got.plt? HMM. These should have been created, - * as ABI features, by the time we get here. - * .comment -- maybe - * .shstrtab -- YES - * .symtab -- YES - * .strtab -- YES. - * - * Do we generate them as elements in the image, or just - * use them to write the ELF file? The latter. - *) - let (symbol_tags, symbol_ranges) = (elf_memory_image_symbol_def_ranges img2) - in - let all_sym_names = (Lem_list.map (fun tag -> - (match tag with - SymbolDef(sd) -> sd.def_symname - | _ -> "not symbol tag, in symbol tags" - ) - ) symbol_tags) - in - (*let _ = errln ("All symbol names: " ^ (show all_sym_names)) - in*) - let strtab = (List.fold_left (fun table -> fun str -> - let (_, t) = (String_table.insert_string str table) in t - ) String_table.empty0 all_sym_names) - in - (* If the same address starts >1 section, all but one of those sections - * must have size zero. These need to come *first* to avoid screwing up - * the offset calculation. So also sort by size, so that the zero-sizers - * come first. *) - let element_section_tag_pairs_sorted_by_address = ( (* List.stable_sort *)List.sort - (fun (isec1, (el1, range1)) -> (fun (isec2, (el2, range2)) -> ( - let (addr1, sz1) = ((match Pmap.lookup el1 img2.elements with - Some(e) -> - (*let _ = errln ("Size of element " ^ el1 ^ " is " ^ (show e.length)) - in*) - (e.startpos, e.length1) - | None -> failwith "internal error: element does not exist" - )) - in - let (addr2, sz2) = ((match Pmap.lookup el2 img2.elements with - Some(e) -> (e.startpos, e.length1) - | None -> failwith "internal error: element does not exist" - )) - in -(pairCompare (maybeCompare Nat_big_num.compare) (maybeCompare Nat_big_num.compare) (addr1, sz1) (addr2, sz2)) - ))) - (list_combine section_tags_bare_noidx section_ranges)) - in - let sorted_sections = (Lem_list.map (fun (isec1, (el, range1)) -> isec1) - element_section_tag_pairs_sorted_by_address) - in - let filesz = (fun el -> fun isec1 -> - (* How can we distinguish progbits from nobits? - * A section can be nobits if its representation - * is all zero or don't-care. But in practice we - * don't make a section nobits unless its name is .bss. *) - let sz = (if (* is_all_zeroes_or_dont_care *) true && -(isec1.elf64_section_name_as_string = ".bss") then Nat_big_num.of_int 0 - else (match el.length1 with - None -> failwith "error: concrete section element has no length" - | Some len -> len - )) - in - (*let _ = errln ("Filesz of " ^ isec.elf64_section_name_as_string ^ " is 0x" ^ (hex_string_of_natural sz)) - in*) - sz - ) - in - let (last_off, section_file_offsets) = (List.fold_left (fun (current_off, offs_so_far) -> (fun (isec1, (el_name, el_range)) -> - (* where can we place this in the file? - * it's the next offset that's congruent to the section addr, - * modulo the biggest page size. *) - let el = ((match Pmap.lookup el_name img2.elements with - Some e -> e - | None -> failwith "nonexistent element" - )) - in - let (start_off : Nat_big_num.num) = ((match el.startpos with - Some addr -> let this_remainder = (Nat_big_num.modulus current_off a.maxpagesize) - in - let target_remainder = (Nat_big_num.modulus addr a.maxpagesize) - in - let bump = ( - if Nat_big_num.greater_equal target_remainder this_remainder - then Nat_big_num.sub_nat target_remainder this_remainder - else ( Nat_big_num.sub_nat (Nat_big_num.add a.maxpagesize target_remainder) this_remainder) - ) - in Nat_big_num.add - (*let _ = errln ("For section " ^ isec.elf64_section_name_as_string ^ ", bumping offset by " ^ - (hex_string_of_natural bump) ^ "(remainder " ^ (hex_string_of_natural this_remainder) ^ - ", target remainder " ^ (hex_string_of_natural target_remainder) ^ ") to 0x" ^ - (hex_string_of_natural (current_off + bump))) - in*) - current_off bump - | None -> - (* It has no assigned address. That's okay if it's not allocatable. - * If it's not allocatable, it has no alignment. *) - if flag_is_set shf_alloc isec1.elf64_section_flags then (failwith "allocatable section with no address") - else current_off (* FIXME: is alignment important in file-offset-space? *) - )) - in - let end_off = (Nat_big_num.add start_off (filesz el isec1)) - in - (end_off, List.rev_append (List.rev offs_so_far) [start_off]) - )) (( Nat_big_num.add phoff ( Nat_big_num.mul max_phnum1(Nat_big_num.of_int 56))), []) element_section_tag_pairs_sorted_by_address) - in - let user_sections_sorted_with_offsets = (let x2 = - ([]) in List.fold_right - (fun(off, (isec1, (el_name, el_range))) x2 -> - if true then - (let el = ((match Pmap.lookup el_name img2.elements with - Some x -> x - | None -> failwith "internal error: section not found" - )) in - { elf64_section_name = (isec1.elf64_section_name) (* ignored *) - ; elf64_section_type = (isec1.elf64_section_type) - ; elf64_section_flags = (isec1.elf64_section_flags) - ; elf64_section_addr = ((match el.startpos with - Some addr -> addr - | None ->Nat_big_num.of_int 0 - )) ; elf64_section_offset = - (*let _ = errln ("Assigning offset 0x" ^ (hex_string_of_natural off) ^ " to section " ^ - isec.elf64_section_name_as_string) - in*) - off - ; elf64_section_size = ((match el.length1 with - Some len -> len - | None -> length el.contents - )) - ; elf64_section_link = (isec1.elf64_section_link) - ; elf64_section_info = (isec1.elf64_section_info) - ; elf64_section_align = (isec1.elf64_section_align) - ; elf64_section_entsize = (isec1.elf64_section_entsize) - ; elf64_section_body = - (let pad_fn1 = ( - if flag_is_set shf_execinstr isec1.elf64_section_flags then - a.pad_data else a.pad_code) in - Sequence - (concretise_byte_pattern [] (Nat_big_num.of_int 0) - (make_concrete el).contents pad_fn1)) - ; elf64_section_name_as_string = (isec1.elf64_section_name_as_string) - }) :: x2 else x2) - (list_combine section_file_offsets - element_section_tag_pairs_sorted_by_address) x2) - in - let symtab = -( - (* Get all the symbols *)elf64_null_symbol_table_entry :: (let x2 = - ([]) in List.fold_right - (fun(maybe_range, tag) x2 -> - if true then - (match tag with - SymbolDef (d) -> - let nameidx = ((match String_table.find_string d.def_symname strtab with - Some idx1 -> let v = (Uint32.of_string - (Nat_big_num.to_string idx1)) - in - (* let _ = errln ("strtab: found `" ^ d.def_symname ^ "' at index " ^ (show v)) - in *) - v - | None -> failwith - "impossible: symbol name not in strtab we just created" - )) in - let (shndx1, svalue, sz) = ( - if d.def_syment.elf64_st_shndx = - Uint32.of_string - (Nat_big_num.to_string shn_abs) then - (d.def_syment.elf64_st_shndx, d.def_syment.elf64_st_value, d.def_syment.elf64_st_size) - else - let (el_name, (start, len)) = ((match maybe_range with - Some(el_name, (start, len)) -> - (el_name, - (start, len)) - | None -> - failwith - "impossible: non-ABS symbol with no range" - )) in - (Uint32.of_string - (Nat_big_num.to_string - ( (* what's the section index of this element? *) - let maybe_found = (mapMaybei - (fun i -> fun isec1 -> - if isec1.elf64_section_name_as_string - = - el_name then - Some i - else - None) - sorted_sections) - in - (match maybe_found with - [i] -> Nat_big_num.add - (Nat_big_num.of_int 1) - i - | [] ->Nat_big_num.of_int - (* HMM *) (*let _ = errln ("Couldn't compute section index of symbol " ^ d.def_symname) - in*) 0 - | _ -> failwith - ("internal error: multiple sections named " - ^ el_name) - ) )), - Uint64.of_string - (Nat_big_num.to_string - ( Nat_big_num.add start - (match Pmap.lookup el_name - img2.elements with - Some x -> (match x.startpos with - Some addr -> - addr - | None -> - failwith - "internal error: symbol defined in section with no address" - ) - | None -> failwith - "internal error: section (of symbol) not found" - ))), - Uint64.of_string - (Nat_big_num.to_string len) )) in - (* CHECK: can we expect these to be these usable, the way we generated them? *) - { elf64_st_name = nameidx - ; elf64_st_info = (d.def_syment.elf64_st_info) (* type, binding, visibility *) - ; elf64_st_other = (d.def_syment.elf64_st_other) - ; elf64_st_shndx = shndx1 ; elf64_st_value = svalue - ; elf64_st_size = sz } - (* FIXME: do we ever get symbolrefs? *) - | _ -> failwith "not a symbol tag, in symbol_tags" - ) :: x2 else x2) (list_combine symbol_ranges symbol_tags) x2)) - in - (*let _ = errln ("Building an ELF file from" ^ (show (length element_section_tag_pairs_sorted_by_address)) ^ " sections") - in*) - (* PROBLEM: - * sections' offset assignments depend on phnum. - * BUT - * phnum depends on sections' offset assignments! - * How do we break this cycle? - * We can get an upper bound on the number of phdrs, then - * fill them in later. - *) - (* How does the GNU BFD output a statically linked executable? - * First the ELF header, - * then program headers, - * then sections in order of address: - * .interp, these are all allocatable sections! with addresses! - * then .note.ABI-tag, - * then .note.gnu.build-id, - * then .gnu.hash, - * then .dynsym, - * then .dynstr, - * then .gnu.version, - * then .gnu.version_r, - * then ... - * - * ... and so on ... - * - * then .gnu.debuglink (the only non-allocatable section) - * then .shstrtab, then SHT. - * - * So how can we calculate the offset of the SHT? We have to place - * all the other sections first. - *) - let shstrndx = (Nat_big_num.add(Nat_big_num.of_int 1) (length section_tags)) - in - let shstroff = last_off - in - let shstrsz = (String_table.size0 shstrtab) - in - let symoff = (align_up_to(Nat_big_num.of_int 8) ( Nat_big_num.add shstroff shstrsz)) - in - let symsz = (Nat_big_num.mul(Nat_big_num.of_int 24) (length symtab)) - in - let stroff = (Nat_big_num.add symoff symsz) - in - let strsz = (String_table.size0 strtab) - in - let shoff = (align_up_to(Nat_big_num.of_int 64) ( Nat_big_num.add stroff strsz)) - in - let shnum = (Nat_big_num.add(Nat_big_num.of_int 4) (length sorted_sections)) (* null, shstrtab, symtab, strtab *) - in - let (entry : Nat_big_num.num) = ((match Multimap.lookupBy0 - (instance_Basic_classes_Ord_Memory_image_range_tag_dict - instance_Basic_classes_Ord_Abis_any_abi_feature_dict) (instance_Basic_classes_Ord_Maybe_maybe_dict - (instance_Basic_classes_Ord_tup2_dict - Lem_string_extra.instance_Basic_classes_Ord_string_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_Num_natural_dict - instance_Basic_classes_Ord_Num_natural_dict))) instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) (Memory_image_orderings.tagEquiv - instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict) (EntryPoint) img2.by_tag with - [(_, maybe_el_range)] -> - (match maybe_el_range with - Some (el_name, (start, len)) -> - address_of_range (el_name, (start, len)) img2 - | None -> failwith "entry point defined without a range" - ) - | [] -> failwith "no entry point defined" - | _ -> failwith "multiple entry points defined" - )) - in - let hdr = (a.make_elf_header elf_ft_exec entry shoff phoff max_phnum1 shnum shstrndx) - in - let endian = (if (Lem.option_equal (=) (Ml_bindings.list_index_big_int elf_ii_data hdr.elf64_ident) (Some(Uint32.of_string (Nat_big_num.to_string elf_data_2lsb)))) then Little else Big) - in - let all_sections_sorted_with_offsets = (List.rev_append (List.rev user_sections_sorted_with_offsets) [ - { elf64_section_name = ((match String_table.find_string ".shstrtab" shstrtab with - Some n -> n - | None -> failwith "internal error: `.shstrtab' not in shstrtab" - )) - ; elf64_section_type = sht_strtab - ; elf64_section_flags =(Nat_big_num.of_int 0) - ; elf64_section_addr =(Nat_big_num.of_int 0) - ; elf64_section_offset = shstroff - ; elf64_section_size = shstrsz - ; elf64_section_link =(Nat_big_num.of_int 0) - ; elf64_section_info =(Nat_big_num.of_int 0) - ; elf64_section_align =(Nat_big_num.of_int 0) - ; elf64_section_entsize =(Nat_big_num.of_int 0) - ; elf64_section_body = (Sequence(Lem_list.map (fun x-> x) (Xstring.explode (String_table.get_base_string shstrtab)))) - ; elf64_section_name_as_string = ".shstrtab" - }; - { elf64_section_name = ((match String_table.find_string ".symtab" shstrtab with - Some n -> n - | None -> failwith "internal error: `.symtab' not in shstrtab" - )) - ; elf64_section_type = sht_symtab - ; elf64_section_flags =(Nat_big_num.of_int 0) - ; elf64_section_addr =(Nat_big_num.of_int 0) - ; elf64_section_offset = symoff - ; elf64_section_size = symsz - ; elf64_section_link = (Nat_big_num.add (Nat_big_num.add(Nat_big_num.of_int 1) (length user_sections_sorted_with_offsets))(Nat_big_num.of_int 2)) - ; elf64_section_info =(Nat_big_num.of_int 0) - ; elf64_section_align =(Nat_big_num.of_int 8) - ; elf64_section_entsize =(Nat_big_num.of_int 24) - ; elf64_section_body = (Byte_sequence.concat0 (Lem_list.map (bytes_of_elf64_symbol_table_entry endian) symtab)) - ; elf64_section_name_as_string = ".symtab" - }; - (* strtab *) - { elf64_section_name = ((match String_table.find_string ".strtab" shstrtab with - Some n -> n - | None -> failwith "internal error: `.strtab' not in shstrtab" - )) - ; elf64_section_type = sht_strtab - ; elf64_section_flags =(Nat_big_num.of_int 0) - ; elf64_section_addr =(Nat_big_num.of_int 0) - ; elf64_section_offset = stroff - ; elf64_section_size = strsz - ; elf64_section_link =(Nat_big_num.of_int 0) - ; elf64_section_info =(Nat_big_num.of_int 0) - ; elf64_section_align =(Nat_big_num.of_int 1) - ; elf64_section_entsize =(Nat_big_num.of_int 0) - ; elf64_section_body = (Sequence(Lem_list.map (fun x-> x) (Xstring.explode (String_table.get_base_string strtab)))) - ; elf64_section_name_as_string = ".strtab" - } - ]) - in - let phdrs = (a.make_phdrs a.maxpagesize a.commonpagesize elf_ft_exec img2 all_sections_sorted_with_offsets) - in - { elf64_file_header = ({ (* fix up hdr with the precise phnum *) - elf64_ident = (hdr.elf64_ident) - ; elf64_type = (hdr.elf64_type) - ; elf64_machine = (hdr.elf64_machine) - ; elf64_version = (hdr.elf64_version) - ; elf64_entry = (hdr.elf64_entry) - ; elf64_phoff = (hdr.elf64_phoff) - ; elf64_shoff = (hdr.elf64_shoff) - ; elf64_flags = (hdr.elf64_flags) - ; elf64_ehsize = (hdr.elf64_ehsize) - ; elf64_phentsize = (hdr.elf64_phentsize) - ; elf64_phnum = (Uint32.of_string (Nat_big_num.to_string (length phdrs))) - ; elf64_shentsize = (hdr.elf64_shentsize) - ; elf64_shnum = (hdr.elf64_shnum) - ; elf64_shstrndx = (hdr.elf64_shstrndx) - }) - ; elf64_file_program_header_table = phdrs - ; elf64_file_section_header_table = (elf64_null_section_header :: ((Lem_list.mapi (fun i -> fun isec1 -> - { elf64_sh_name = (let s = (isec1.elf64_section_name_as_string) in - (match String_table.find_string s shstrtab with - Some n -> Uint32.of_string (Nat_big_num.to_string n) - | None -> failwith ("internal error: section name `" ^ (s ^ "' not in shstrtab")) - )) - ; elf64_sh_type = (Uint32.of_string (Nat_big_num.to_string isec1.elf64_section_type)) - ; elf64_sh_flags = (Uint64.of_string (Nat_big_num.to_string isec1.elf64_section_flags)) - ; elf64_sh_addr = (Uint64.of_string (Nat_big_num.to_string isec1.elf64_section_addr)) - ; elf64_sh_offset = (Uint64.of_string (Nat_big_num.to_string isec1.elf64_section_offset)) - ; elf64_sh_size = (Uint64.of_string (Nat_big_num.to_string isec1.elf64_section_size)) - ; elf64_sh_link = (Uint32.of_string (Nat_big_num.to_string isec1.elf64_section_link)) - ; elf64_sh_info = (Uint32.of_string (Nat_big_num.to_string isec1.elf64_section_info)) - ; elf64_sh_addralign = (Uint64.of_string (Nat_big_num.to_string isec1.elf64_section_align)) - ; elf64_sh_entsize = (Uint64.of_string (Nat_big_num.to_string isec1.elf64_section_entsize)) - } - )) (* (zip section_tags_bare section_file_offsets) *) all_sections_sorted_with_offsets)) - ; elf64_file_interpreted_segments = ([ - (* do we need to build this? I have HACKed elf_file so that we don't; - we assume that all the relevant payload is in the section bodies, - as it should be. *) - ]) - ; elf64_file_interpreted_sections = (null_elf64_interpreted_section :: all_sections_sorted_with_offsets) - ; elf64_file_bits_and_bobs = ([]) - }) diff --git a/lib/ocaml_rts/linksem/elf_dynamic.ml b/lib/ocaml_rts/linksem/elf_dynamic.ml deleted file mode 100644 index 0355337e..00000000 --- a/lib/ocaml_rts/linksem/elf_dynamic.ml +++ /dev/null @@ -1,1202 +0,0 @@ -(*Generated by Lem from elf_dynamic.lem.*) -(** [elf_dynamic] module exports types and definitions relating to the dynamic - * section and dynamic linking functionality of an ELF file. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_list -open Lem_num -open Lem_string - -open Byte_sequence -open Endianness -open Error -open Show -open String_table - -open Elf_file -open Elf_header -open Elf_relocation -open Elf_section_header_table -open Elf_program_header_table -open Elf_types_native_uint - -(** Validity checks *) - -(** [is_elf32_valid_program_header_table_for_dynamic_linking pht] checks whether - * a program header table [pht] is a valid program header table for an ELF file - * that will be potentially dynamically linked. Returns true if there is exactly - * one segment header of type [elf_pt_interp], i.e. contains a string pointing - * to the requested dynamic interpreter. - *) -(*val is_elf32_valid_program_header_table_for_dynamic_linking : elf32_program_header_table -> - bool*) -let is_elf32_valid_program_header_table_for_dynamic_linking pht:bool= - (List.length (List.filter (fun x -> Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string x.elf32_p_type)) elf_pt_interp) pht) = 1) - -(** [is_elf64_valid_program_header_table_for_dynamic_linking pht] checks whether - * a program header table [pht] is a valid program header table for an ELF file - * that will be potentially dynamically linked. Returns true if there is exactly - * one segment header of type [elf_pt_interp], i.e. contains a string pointing - * to the requested dynamic interpreter. - *) -(*val is_elf64_valid_program_header_table_for_dynamic_linking : elf64_program_header_table -> - bool*) -let is_elf64_valid_program_header_table_for_dynamic_linking pht:bool= - (List.length (List.filter (fun x -> Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string x.elf64_p_type)) elf_pt_interp) pht) = 1) - -(** Dynamic section entry *) - -(** [dyn_union] represents the C-union type used in the definition of [elf32_dyn] - * and [elf64_dyn] types below. Some section tags correspond to entries where - * the fields are either unspecified or ignored, hence the presence of the - * [D_Ignored] constructor. - *) -type( 'a, 'b) dyn_union - = D_Val of 'a - | D_Ptr of 'b - | D_Ignored of byte_sequence - -(** [elf32_dyn] captures the notion of an ELF32 dynamic section entry. - * Specialises the [dyn_union] type above to using [elf32_word] values and - * [elf32_addr] pointers. - *) -type elf32_dyn = - { elf32_dyn_tag : Int32.t (** The type of the entry. *) - ; elf32_dyn_d_un : (Uint32.uint32, Uint32.uint32) dyn_union (** The value of the entry, stored as a union. *) - } - -(** [elf64_dyn] captures the notion of an ELF32 dynamic section entry. - * Specialises the [dyn_union] type above to using [elf64_xword] values and - * [elf64_addr] pointers. - *) -type elf64_dyn = - { elf64_dyn_tag : Int64.t (** The type of the entry. *) - ; elf64_dyn_d_un : (Uint64.uint64, Uint64.uint64) dyn_union (** The value of the entry, stored as a union. *) - } - -(** Dynamic section tags *) - -(** [dt_null] marks the end of the dynamic array *) -let dt_null : Nat_big_num.num= (Nat_big_num.of_int 0) -(** [dt_needed] holds the string table offset of a string containing the name of - * a needed library. - *) -let dt_needed : Nat_big_num.num= (Nat_big_num.of_int 1) -(** [dt_pltrelsz] holds the size in bytes of relocation entries associated with - * the PLT. - *) -let dt_pltrelsz : Nat_big_num.num= (Nat_big_num.of_int 2) -(** [dt_pltgot] holds an address associated with the PLT or GOT. *) -let dt_pltgot : Nat_big_num.num= (Nat_big_num.of_int 3) -(** [dt_hash] holds the address of a symbol-table hash. *) -let dt_hash : Nat_big_num.num= (Nat_big_num.of_int 4) -(** [dt_strtab] holds the address of the string table. *) -let dt_strtab : Nat_big_num.num= (Nat_big_num.of_int 5) -(** [dt_symtab] holds the address of a symbol table. *) -let dt_symtab : Nat_big_num.num= (Nat_big_num.of_int 6) -(** [dt_rela] holds the address of a relocation table. *) -let dt_rela : Nat_big_num.num= (Nat_big_num.of_int 7) -(** [dt_relasz] holds the size in bytes of the relocation table. *) -let dt_relasz : Nat_big_num.num= (Nat_big_num.of_int 8) -(** [dt_relaent] holds the size in bytes of a relocation table entry. *) -let dt_relaent : Nat_big_num.num= (Nat_big_num.of_int 9) -(** [dt_strsz] holds the size in bytes of the string table. *) -let dt_strsz : Nat_big_num.num= (Nat_big_num.of_int 10) -(** [dt_syment] holds the size in bytes of a symbol table entry. *) -let dt_syment : Nat_big_num.num= (Nat_big_num.of_int 11) -(** [dt_init] holds the address of the initialisation function. *) -let dt_init : Nat_big_num.num= (Nat_big_num.of_int 12) -(** [dt_fini] holds the address of the finalisation function. *) -let dt_fini : Nat_big_num.num= (Nat_big_num.of_int 13) -(** [dt_soname] holds the string table offset of a string containing the shared- - * object name. - *) -let dt_soname : Nat_big_num.num= (Nat_big_num.of_int 14) -(** [dt_rpath] holds the string table offset of a string containing the library - * search path. - *) -let dt_rpath : Nat_big_num.num= (Nat_big_num.of_int 15) -(** [dt_symbolic] alters the linker's symbol resolution algorithm so that names - * are resolved first from the shared object file itself, rather than the - * executable file. - *) -let dt_symbolic : Nat_big_num.num= (Nat_big_num.of_int 16) -(** [dt_rel] is similar to [dt_rela] except its table has implicit addends. *) -let dt_rel : Nat_big_num.num= (Nat_big_num.of_int 17) -(** [dt_relsz] holds the size in bytes of the [dt_rel] relocation table. *) -let dt_relsz : Nat_big_num.num= (Nat_big_num.of_int 18) -(** [dt_relent] holds the size in bytes of a [dt_rel] relocation entry. *) -let dt_relent : Nat_big_num.num= (Nat_big_num.of_int 19) -(** [dt_pltrel] specifies the type of relocation entry to which the PLT refers. *) -let dt_pltrel : Nat_big_num.num= (Nat_big_num.of_int 20) -(** [dt_debug] is used for debugging and its purpose is not specified in the ABI. - * Programs using this entry are not ABI-conformant. - *) -let dt_debug : Nat_big_num.num= (Nat_big_num.of_int 21) -(** [dt_textrel] absence of this entry indicates that no relocation entry should - * cause a modification to a non-writable segment. Otherwise, if present, one - * or more relocation entries may request modifications to a non-writable - * segment. - *) -let dt_textrel : Nat_big_num.num= (Nat_big_num.of_int 22) -(** [dt_jmprel]'s member holds the address of relocation entries associated with - * the PLT. - *) -let dt_jmprel : Nat_big_num.num= (Nat_big_num.of_int 23) -(** [dt_bindnow] instructs the linker to process all relocations for the object - * containing the entry before transferring control to the program. - *) -let dt_bindnow : Nat_big_num.num= (Nat_big_num.of_int 24) -(** [dt_init_array] holds the address to the array of pointers to initialisation - * functions. - *) -let dt_init_array : Nat_big_num.num= (Nat_big_num.of_int 25) -(** [dt_fini_array] holds the address to the array of pointers to finalisation - * functions. - *) -let dt_fini_array : Nat_big_num.num= (Nat_big_num.of_int 26) -(** [dt_init_arraysz] holds the size in bytes of the array of pointers to - * initialisation functions. - *) -let dt_init_arraysz : Nat_big_num.num= (Nat_big_num.of_int 27) -(** [dt_fini_arraysz] holds the size in bytes of the array of pointers to - * finalisation functions. - *) -let dt_fini_arraysz : Nat_big_num.num= (Nat_big_num.of_int 28) -(** [dt_runpath] holds an offset into the string table holding a string containing - * the library search path. - *) -let dt_runpath : Nat_big_num.num= (Nat_big_num.of_int 29) -(** [dt_flags] holds flag values specific to the object being loaded. *) -let dt_flags : Nat_big_num.num= (Nat_big_num.of_int 30) -let dt_encoding : Nat_big_num.num= (Nat_big_num.of_int 32) -(** [dt_preinit_array] holds the address to the array of pointers of pre- - * initialisation functions. - *) -let dt_preinit_array : Nat_big_num.num= (Nat_big_num.of_int 32) -(** [dt_preinit_arraysz] holds the size in bytes of the array of pointers of - * pre-initialisation functions. - *) -let dt_preinit_arraysz : Nat_big_num.num= (Nat_big_num.of_int 33) -(** [dt_loos] and [dt_hios]: this inclusive range is reserved for OS-specific - * semantics. - *) -let dt_loos : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 805306374))(Nat_big_num.of_int 1)) (* 0x6000000D *) -let dt_hios : Nat_big_num.num= ( Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 939522048)) (* 0x6ffff000 *) -(** [dt_loproc] and [dt_hiproc]: this inclusive range is reserved for processor - * specific semantics. - *) -let dt_loproc : Nat_big_num.num= ( Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 939524096)) (* 0x70000000 *) -let dt_hiproc : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 1073741823))(Nat_big_num.of_int 1)) (* 0x7fffffff *) - -(** [string_of_dynamic_tag so t os proc] produces a string-based representation of - * dynamic section tag [t]. For tag values between LO_OS and HI_OS [os] is - * used to produce the resulting value. For tag values between LO_PROC and - * HI_PROC [proc] is used to produce the resulting value. Boolean flag [so] - * indicates whether the flag in question is derived from a shared object file, - * which alters the printing of ENCODING and PRE_INITARRAY flags. - *) -(*val string_of_dynamic_tag : bool -> natural -> (natural -> bool) -> (natural -> string) -> (natural -> string) - -> string*) -let string_of_dynamic_tag shared_object tag os_additional_ranges os proc:string= - (if Nat_big_num.equal tag dt_null then - "NULL" - else if Nat_big_num.equal tag dt_needed then - "NEEDED" - else if Nat_big_num.equal tag dt_pltrelsz then - "PLTRELSZ" - else if Nat_big_num.equal tag dt_pltgot then - "PLTGOT" - else if Nat_big_num.equal tag dt_hash then - "HASH" - else if Nat_big_num.equal tag dt_strtab then - "STRTAB" - else if Nat_big_num.equal tag dt_symtab then - "SYMTAB" - else if Nat_big_num.equal tag dt_rela then - "RELA" - else if Nat_big_num.equal tag dt_relasz then - "RELASZ" - else if Nat_big_num.equal tag dt_relaent then - "RELAENT" - else if Nat_big_num.equal tag dt_strsz then - "STRSZ" - else if Nat_big_num.equal tag dt_syment then - "SYMENT" - else if Nat_big_num.equal tag dt_init then - "INIT" - else if Nat_big_num.equal tag dt_fini then - "FINI" - else if Nat_big_num.equal tag dt_soname then - "SONAME" - else if Nat_big_num.equal tag dt_rpath then - "RPATH" - else if Nat_big_num.equal tag dt_symbolic then - "SYMBOLIC" - else if Nat_big_num.equal tag dt_rel then - "REL" - else if Nat_big_num.equal tag dt_relsz then - "RELSZ" - else if Nat_big_num.equal tag dt_relent then - "RELENT" - else if Nat_big_num.equal tag dt_pltrel then - "PLTREL" - else if Nat_big_num.equal tag dt_debug then - "DEBUG" - else if Nat_big_num.equal tag dt_textrel then - "TEXTREL" - else if Nat_big_num.equal tag dt_jmprel then - "JMPREL" - else if Nat_big_num.equal tag dt_bindnow then - "BIND_NOW" - else if Nat_big_num.equal tag dt_init_array then - "INIT_ARRAY" - else if Nat_big_num.equal tag dt_fini_array then - "FINI_ARRAY" - else if Nat_big_num.equal tag dt_init_arraysz then - "INIT_ARRAYSZ" - else if Nat_big_num.equal tag dt_fini_arraysz then - "FINI_ARRAYSZ" - else if Nat_big_num.equal tag dt_runpath then - "RUNPATH" - else if Nat_big_num.equal tag dt_flags then - "FLAGS" - else if Nat_big_num.equal tag dt_encoding then - if not shared_object then - "ENCODING" - else - "PREINIT_ARRAY" - else if Nat_big_num.equal tag dt_preinit_arraysz then - "PREINIT_ARRAYSZ" - else if Nat_big_num.greater_equal tag dt_loproc && Nat_big_num.less_equal tag dt_hiproc then - proc tag - else if Nat_big_num.greater_equal tag dt_loos && Nat_big_num.less_equal tag dt_hios then - os tag - else if os_additional_ranges tag then - os tag - else - "Invalid dynamic section tag") - -(** [tag_correspondence] is a type used to emulate the functionality of a C-union - * in Lem. The type records whether the union should be interpreted as a value, - * a pointer, or a "do not care" value. An accompanying function will map a - * dynamic section tag to a [tag_correspondence], so that transcription functions - * know how to properly use the [dyn_union] value in a dynamic section entry. - *) -type tag_correspondence - = C_Val (** [dyn_union] should be interpreted as a value. *) - | C_Ptr (** [dyn_union] should be interpreted as a pointer. *) - | C_Ignored (** [dyn_union] is irrelevant, so we do not care. *) - -(** [tag_correspondence_of_tag tag os_additional_ranges os proc] produces a - * [tag_correspondence] value for a given dynamic tag, [tag]. Some tag values - * are reserved for interpretation by the OS or processor supplement (i.e. the - * ABI). We therefore also take in a predicate, [os_additional_ranges], that - * recognises when a tag is "special" for a given ABI, and a means of interpreting - * that tag, using [os] and [proc] functions. - *) -(*val tag_correspondence_of_tag : bool -> natural -> (natural -> bool) -> (natural -> error tag_correspondence) -> - (natural -> error tag_correspondence) -> error tag_correspondence*) -let tag_correspondence_of_tag shared_object tag os_additional_ranges os proc:(tag_correspondence)error= - (if Nat_big_num.equal tag dt_null then - return C_Ignored - else if Nat_big_num.equal tag dt_needed then - return C_Val - else if Nat_big_num.equal tag dt_pltrelsz then - return C_Val - else if Nat_big_num.equal tag dt_pltgot then - return C_Ptr - else if Nat_big_num.equal tag dt_hash then - return C_Ptr - else if Nat_big_num.equal tag dt_strtab then - return C_Ptr - else if Nat_big_num.equal tag dt_symtab then - return C_Ptr - else if Nat_big_num.equal tag dt_rela then - return C_Ptr - else if Nat_big_num.equal tag dt_relasz then - return C_Val - else if Nat_big_num.equal tag dt_relaent then - return C_Val - else if Nat_big_num.equal tag dt_strsz then - return C_Val - else if Nat_big_num.equal tag dt_syment then - return C_Val - else if Nat_big_num.equal tag dt_init then - return C_Ptr - else if Nat_big_num.equal tag dt_fini then - return C_Ptr - else if Nat_big_num.equal tag dt_soname then - return C_Val - else if Nat_big_num.equal tag dt_rpath then - return C_Val - else if Nat_big_num.equal tag dt_symbolic then - return C_Ignored - else if Nat_big_num.equal tag dt_rel then - return C_Ptr - else if Nat_big_num.equal tag dt_relsz then - return C_Val - else if Nat_big_num.equal tag dt_relent then - return C_Val - else if Nat_big_num.equal tag dt_pltrel then - return C_Val - else if Nat_big_num.equal tag dt_debug then - return C_Ptr - else if Nat_big_num.equal tag dt_textrel then - return C_Ignored - else if Nat_big_num.equal tag dt_jmprel then - return C_Ptr - else if Nat_big_num.equal tag dt_bindnow then - return C_Ignored - else if Nat_big_num.equal tag dt_init_array then - return C_Ptr - else if Nat_big_num.equal tag dt_fini_array then - return C_Ptr - else if Nat_big_num.equal tag dt_init_arraysz then - return C_Val - else if Nat_big_num.equal tag dt_fini_arraysz then - return C_Val - else if Nat_big_num.equal tag dt_runpath then - return C_Val - else if Nat_big_num.equal tag dt_flags then - return C_Val - else if Nat_big_num.equal tag dt_encoding then - if not shared_object then - return C_Ignored - else - return C_Ptr - else if Nat_big_num.equal tag dt_preinit_arraysz then - return C_Val - else if Nat_big_num.greater_equal tag dt_loproc && Nat_big_num.less_equal tag dt_hiproc then - proc tag - else if Nat_big_num.greater_equal tag dt_loos && Nat_big_num.less_equal tag dt_hios then - os tag - else if os_additional_ranges tag then - os tag - else - fail ("tag_correspondence_of_tag: invalid dynamic section tag")) - -(** [read_elf32_dyn endian bs0 so os_additional_ranges os proc] reads an [elf32_dyn] - * record from byte sequence [bs0], assuming endianness [endian]. As mentioned - * above some ABIs reserve additional tag values for their own purposes. These - * are recognised by the predicate [os_additional_ranges] and interpreted by - * the functions [os] and [proc]. Fails if the transcription of the record from - * [bs0] fails, or if [os] or [proc] fail. - *) -(*val read_elf32_dyn : endianness -> byte_sequence -> bool -> (natural -> bool) -> (natural -> error tag_correspondence) -> - (natural -> error tag_correspondence) -> error (elf32_dyn * byte_sequence)*) -let read_elf32_dyn endian bs0 shared_object os_additional_ranges os proc:(elf32_dyn*byte_sequence)error= - (read_elf32_sword endian bs0 >>= (fun (tag0, bs1) -> - let tag = (Nat_big_num.abs (Nat_big_num.of_int32 tag0)) in - tag_correspondence_of_tag shared_object tag os_additional_ranges os proc >>= (fun corr -> - (match corr with - | C_Ptr -> - read_elf32_addr endian bs1 >>= (fun (ptr, bs2) -> - return ({ elf32_dyn_tag = tag0 ; elf32_dyn_d_un = (D_Ptr ptr) }, bs2)) - | C_Val -> - read_elf32_word endian bs1 >>= (fun (vl, bs2) -> - return ({ elf32_dyn_tag = tag0 ; elf32_dyn_d_un = (D_Val vl) }, bs2)) - | C_Ignored -> - (match endian with - | Big -> - read_4_bytes_be bs1 >>= (fun ((b1, b2, b3, b4), bs2) -> - let cut = (Byte_sequence.from_byte_lists [[b1; b2; b3; b4]]) in - return ({ elf32_dyn_tag = tag0 ; elf32_dyn_d_un = (D_Ignored cut) }, bs2)) - | Little -> - read_4_bytes_le bs1 >>= (fun ((b1, b2, b3, b4), bs2) -> - let cut = (Byte_sequence.from_byte_lists [[b1; b2; b3; b4]]) in - return ({ elf32_dyn_tag = tag0 ; elf32_dyn_d_un = (D_Ignored cut) }, bs2)) - ) - )))) - -(** [read_elf64_dyn endian bs0 os_additional_ranges os proc] reads an [elf64_dyn] - * record from byte sequence [bs0], assuming endianness [endian]. As mentioned - * above some ABIs reserve additional tag values for their own purposes. These - * are recognised by the predicate [os_additional_ranges] and interpreted by - * the functions [os] and [proc]. Fails if the transcription of the record from - * [bs0] fails, or if [os] or [proc] fail. - *) -(*val read_elf64_dyn : endianness -> byte_sequence -> bool -> (natural -> bool) -> - (natural -> error tag_correspondence) -> (natural -> error tag_correspondence) -> - error (elf64_dyn * byte_sequence)*) -let read_elf64_dyn endian bs0 shared_object os_additional_ranges os proc:(elf64_dyn*byte_sequence)error= - (read_elf64_sxword endian bs0 >>= (fun (tag0, bs1) -> - let tag = (Nat_big_num.abs (Nat_big_num.of_int64 tag0)) in - tag_correspondence_of_tag shared_object tag os_additional_ranges os proc >>= (fun corr -> - (match corr with - | C_Ptr -> - read_elf64_addr endian bs1 >>= (fun (ptr, bs2) -> - return ({ elf64_dyn_tag = tag0 ; elf64_dyn_d_un = (D_Ptr ptr) }, bs2)) - | C_Val -> - read_elf64_xword endian bs1 >>= (fun (vl, bs2) -> - return ({ elf64_dyn_tag = tag0 ; elf64_dyn_d_un = (D_Val vl) }, bs2)) - | C_Ignored -> - (match endian with - | Big -> - read_8_bytes_be bs1 >>= (fun ((b1, b2, b3, b4, b5, b6, b7, b8), bs2) -> - let cut = (Byte_sequence.from_byte_lists [[b1; b2; b3; b4; b5; b6; b7; b8]]) in - return ({ elf64_dyn_tag = tag0 ; elf64_dyn_d_un = (D_Ignored cut) }, bs2)) - | Little -> - read_8_bytes_le bs1 >>= (fun ((b1, b2, b3, b4, b5, b6, b7, b8), bs2) -> - let cut = (Byte_sequence.from_byte_lists [[b1; b2; b3; b4; b5; b6; b7; b8]]) in - return ({ elf64_dyn_tag = tag0 ; elf64_dyn_d_un = (D_Ignored cut) }, bs2)) - ) - )))) - -(** [obtain_elf32_dynamic_section_contents' endian bs0 os_additional_ranges os - * proc] exhaustively reads in [elf32_dyn] values from byte sequence [bs0], - * interpreting ABI-specific dynamic tags with [os_additional_ranges], [os], and - * [proc] as mentioned above. Fails if [bs0]'s length modulo the size of an - * [elf32_dyn] entry is not 0. - *) -(*val obtain_elf32_dynamic_section_contents' : endianness -> byte_sequence -> - bool -> (natural -> bool) -> (natural -> error tag_correspondence) -> - (natural -> error tag_correspondence) -> error (list elf32_dyn)*) -let rec obtain_elf32_dynamic_section_contents' endian bs0 shared_object os_additional_ranges os proc:((elf32_dyn)list)error= - (if Nat_big_num.equal (Byte_sequence.length0 bs0)(Nat_big_num.of_int 0) then - return [] - else - read_elf32_dyn endian bs0 shared_object os_additional_ranges os proc >>= (fun (head, bs0) -> - if Nat_big_num.equal (Nat_big_num.of_int32 head.elf32_dyn_tag) ( dt_null) then (* DT_NULL marks end of array *) - return [head] - else - obtain_elf32_dynamic_section_contents' endian bs0 shared_object os_additional_ranges os proc >>= (fun tail -> - return (head::tail)))) - -(** [obtain_elf64_dynamic_section_contents' endian bs0 os_additional_ranges os - * proc] exhaustively reads in [elf64_dyn] values from byte sequence [bs0], - * interpreting ABI-specific dynamic tags with [os_additional_ranges], [os], and - * [proc] as mentioned above. Fails if [bs0]'s length modulo the size of an - * [elf64_dyn] entry is not 0. - *) -(*val obtain_elf64_dynamic_section_contents' : endianness -> byte_sequence -> - bool -> (natural -> bool) -> (natural -> error tag_correspondence) -> - (natural -> error tag_correspondence) -> error (list elf64_dyn)*) -let rec obtain_elf64_dynamic_section_contents' endian bs0 shared_object os_additional_ranges os proc:((elf64_dyn)list)error= - (if Nat_big_num.equal (Byte_sequence.length0 bs0)(Nat_big_num.of_int 0) then - return [] - else - read_elf64_dyn endian bs0 shared_object os_additional_ranges os proc >>= (fun (head, bs0) -> - if Nat_big_num.equal (Nat_big_num.of_int64 head.elf64_dyn_tag) ( dt_null) then (* DT_NULL marks end of array *) - return [head] - else - obtain_elf64_dynamic_section_contents' endian bs0 shared_object os_additional_ranges os proc >>= (fun tail -> - return (head::tail)))) - -(** [obtain_elf32_dynamic_section_contents' f1 os_additional_ranges os - * proc bs0] exhaustively reads in [elf32_dyn] values from byte sequence [bs0], - * obtaining endianness and the section header table from [elf32_file] f1, - * interpreting ABI-specific dynamic tags with [os_additional_ranges], [os], and - * [proc] as mentioned above. Fails if [bs0]'s length modulo the size of an - * [elf32_dyn] entry is not 0. - *) -(*val obtain_elf32_dynamic_section_contents : elf32_file -> - (natural -> bool) -> (natural -> error tag_correspondence) -> - (natural -> error tag_correspondence) -> byte_sequence -> error (list elf32_dyn)*) -let obtain_elf32_dynamic_section_contents f1 os_additional_ranges os proc bs0:((elf32_dyn)list)error= - (let endian = (get_elf32_header_endianness f1.elf32_file_header) in - let sht = (f1.elf32_file_section_header_table) in - let shared_object = (is_elf32_shared_object_file f1.elf32_file_header) in - (match List.filter (fun ent -> Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string ent.elf32_sh_type)) sht_dynamic) sht with - | [] -> fail "obtain_elf32_dynamic_section_contents: no SHT_DYNAMIC section header entries" - | [dyn] -> - let off = (Nat_big_num.of_string (Uint32.to_string dyn.elf32_sh_offset)) in - let siz = (Nat_big_num.of_string (Uint32.to_string dyn.elf32_sh_size)) in - Byte_sequence.offset_and_cut off siz bs0 >>= (fun rel -> - obtain_elf32_dynamic_section_contents' endian rel shared_object os_additional_ranges os proc) - | _ -> fail "obtain_elf32_dynamic_section_contents: multiple SHT_DYNAMIC section header entries" - )) - -(** [obtain_elf64_dynamic_section_contents' f1 os_additional_ranges os - * proc bs0] exhaustively reads in [elf64_dyn] values from byte sequence [bs0], - * obtaining endianness and the section header table from [elf64_file] f1, - * interpreting ABI-specific dynamic tags with [os_additional_ranges], [os], and - * [proc] as mentioned above. Fails if [bs0]'s length modulo the size of an - * [elf64_dyn] entry is not 0. - *) -(*val obtain_elf64_dynamic_section_contents : elf64_file -> - (natural -> bool) -> (natural -> error tag_correspondence) -> - (natural -> error tag_correspondence) -> byte_sequence -> error (list elf64_dyn)*) -let obtain_elf64_dynamic_section_contents f1 os_additional_ranges os proc bs0:((elf64_dyn)list)error= - (let endian = (get_elf64_header_endianness f1.elf64_file_header) in - let sht = (f1.elf64_file_section_header_table) in - let shared_object = (is_elf64_shared_object_file f1.elf64_file_header) in - (match List.filter (fun ent -> Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string ent.elf64_sh_type)) sht_dynamic) sht with - | [] -> fail "obtain_elf64_dynamic_section_contents: no SHT_DYNAMIC section header entries" - | [dyn] -> - let off = (Nat_big_num.of_string (Uint64.to_string dyn.elf64_sh_offset)) in - let siz = (Ml_bindings.nat_big_num_of_uint64 dyn.elf64_sh_size) in - Byte_sequence.offset_and_cut off siz bs0 >>= (fun rel -> - obtain_elf64_dynamic_section_contents' endian rel shared_object os_additional_ranges os proc) - | _ -> fail "obtain_elf64_dynamic_section_contents: multiple SHT_DYNAMIC section header entries" - )) - -(** DT Flags values *) - -(** [df_origin] specific that the object being loaded may make reference to the - * $(ORIGIN) substitution string. - *) -let df_origin : Nat_big_num.num= (Nat_big_num.of_int 1) (* 0x1 *) -(** [df_symbolic] changes the linker's symbol resolution algorithm, resolving - * symbols first from the shared object file rather than the executable file. - *) -let df_symbolic : Nat_big_num.num= (Nat_big_num.of_int 2) (* 0x2 *) -(** [df_textrel] if this flag is not set then no relocation entry should cause - * modification to a non-writable segment. - *) -let df_textrel : Nat_big_num.num= (Nat_big_num.of_int 4) (* 0x4 *) -(** [df_bindnow] if set this instructs the linker to process all relocation entries - * of the containing object before transferring control to the program. - *) -let df_bindnow : Nat_big_num.num= (Nat_big_num.of_int 8) (* 0x8 *) -(** [df_static_tls] if set instructs the linker to reject all attempts to load - * the containing file dynamically. - *) -let df_static_tls : Nat_big_num.num= (Nat_big_num.of_int 16) (* 0x10 *) - -(** [check_flag] is a utility function for testing whether a flag is set. - * TODO: so simple it is probably unneccessary now. - *) -(*val check_flag : natural -> natural -> bool*) -let check_flag m pos:bool= ( Nat_big_num.equal m pos) - -(** [string_of_dt_flag f] produces a string-based representation of dynamic - * section flag [f]. - *) -(*val string_of_dt_flag : natural -> string*) -let string_of_dt_flag flag:string= - (if check_flag flag(Nat_big_num.of_int 0) then - "None" - else if check_flag flag df_origin then - "ORIGIN" - else if check_flag flag df_bindnow then - "BIND_NOW" - else if check_flag flag df_symbolic then - "SYMBOLIC" - else if check_flag flag df_textrel then - "TEXTREL" - else if check_flag flag df_static_tls then - "STATIC_TLS" - else if check_flag flag ( Nat_big_num.add df_bindnow df_static_tls) then - "BIND_NOW STATIC_TLS" - else if check_flag flag ( Nat_big_num.add df_static_tls df_symbolic) then - "SYMBOLIC STATIC_TLS" - else (* XXX: add more as needed *) - "Invalid dynamic section flag") - -(** [rel_type] represents the two types of relocation records potentially present - * in an ELF file: relocation, and relocation with addends. - *) -type rel_type - = Rel (** Plain relocation type. *) - | RelA (** Relocation with addends type. *) - -(** [string_of_rel_type r] produces a string-based representation of [rel_type], - * [r]. - *) -(*val string_of_rel_type : rel_type -> string*) -let string_of_rel_type r:string= - ((match r with - | Rel -> "REL" - | RelA -> "RELA" - )) - -(** Type [dyn_value] represents the value of an ELF dynamic section entry. Values - * can represent various different types of objects (e.g. paths to libraries, or - * flags, or sizes of other entries in a file), and this type collates them all. - * Parameterised over two type variables so the type can be shared between ELF32 - * and ELF64. - *) -type( 'addr, 'size) dyn_value - = Address of 'addr (** An address. *) - | Size of 'size (** A size (in bytes). *) - | FName of string (** A filename. *) - | SOName of string (** A shared object name. *) - | Path of string (** A path to some directory. *) - | RPath of string (** A "run path". *) - | RunPath of string (** A "run path". *) - | Library of string (** A library path. *) - | Flags1 of Nat_big_num.num (** Flags. *) - | Flags of Nat_big_num.num (** Flags. *) - | Numeric of Nat_big_num.num (** An uninterpreted numeric value. *) - | Checksum of Nat_big_num.num (** A checksum value *) - | RelType of rel_type (** A relocation entry type. *) - | Timestamp of Nat_big_num.num (** A timestamp value. *) - | Null (** A null (0) value. *) - | Ignored (** An ignored value. *) - -(** [elf32_dyn_value] and [elf64_dyn_value] are specialisations of [dyn_value] - * fixing the correct types for the ['addr] and ['size] type variables. - *) -type elf32_dyn_value = (Uint32.uint32, Uint32.uint32) dyn_value -type elf64_dyn_value = (Uint64.uint64, Uint64.uint64) dyn_value - -(** [get_string_table_of_elf32_dyn_section endian dyns sht bs0] searches through - * dynamic section entries [dyns] looking for one pointing to a string table, looks - * up the corresponding section header [sht] pointed to by that dynamic - * section entry, finds the section in [bs0] and decodes a string table from that - * section assuming endianness [endian]. May fail. - *) -(*val get_string_table_of_elf32_dyn_section : endianness -> list elf32_dyn -> - elf32_section_header_table -> byte_sequence -> error string_table*) -let get_string_table_of_elf32_dyn_section endian dyns sht bs0:(string_table)error= - (let strtabs = -(List.filter (fun x -> Nat_big_num.equal -(Nat_big_num.of_int32 x.elf32_dyn_tag) ( dt_strtab) - ) dyns) - in - (match strtabs with - | [strtab] -> - (match strtab.elf32_dyn_d_un with - | D_Val v -> fail "get_string_table_of_elf32_dyn_section: STRTAB must be a PTR" - | D_Ptr p -> - let sect = -(List.filter (fun s -> -(s.elf32_sh_addr = p) && -(s.elf32_sh_type = Uint32.of_string (Nat_big_num.to_string sht_strtab)) - ) sht) - in - (match sect with - | [] -> fail "get_string_table_of_elf32_dyn_section: no section entry with same address as STRTAB" - | [s] -> - let off = (Nat_big_num.of_string (Uint32.to_string s.elf32_sh_offset)) in - let siz = (Nat_big_num.of_string (Uint32.to_string s.elf32_sh_size)) in - Byte_sequence.offset_and_cut off siz bs0 >>= (fun rel -> - let strings = (Byte_sequence.string_of_byte_sequence rel) in - return (String_table.mk_string_table strings (Missing_pervasives.null_char))) - | _ -> fail "get_string_table_of_elf32_dyn_section: multiple section entries with same address as STRTAB" - ) - | D_Ignored i -> fail "get_string_table_of_elf32_dyn_section: STRTAB must be a PTR" - ) - | [] -> fail "get_string_table_of_elf32_dyn_section: no string table entry" - | _ -> fail "get_string_table_of_elf32_dyn_section: multiple string table entries" - )) - -(** [get_string_table_of_elf64_dyn_section endian dyns sht bs0] searches through - * dynamic section entries [dyns] looking for one pointing to a string table, looks - * up the corresponding section header [sht] pointed to by that dynamic - * section entry, finds the section in [bs0] and decodes a string table from that - * section assuming endianness [endian]. May fail. - *) -(*val get_string_table_of_elf64_dyn_section : endianness -> list elf64_dyn -> - elf64_section_header_table -> byte_sequence -> error string_table*) -let get_string_table_of_elf64_dyn_section endian dyns sht bs0:(string_table)error= - (let strtabs = -(List.filter (fun x -> Nat_big_num.equal -(Nat_big_num.of_int64 x.elf64_dyn_tag) ( dt_strtab) - ) dyns) - in - (match strtabs with - | [strtab] -> - (match strtab.elf64_dyn_d_un with - | D_Val v -> fail "get_string_table_of_elf64_dyn_section: STRTAB must be a PTR" - | D_Ptr p -> - let sect = -(List.filter (fun s -> -(s.elf64_sh_addr = p) && -(s.elf64_sh_type = Uint32.of_string (Nat_big_num.to_string sht_strtab)) - ) sht) - in - (match sect with - | [] -> fail "get_string_table_of_elf64_dyn_section: no section entry with same address as STRTAB" - | [s] -> - let off = (Nat_big_num.of_string (Uint64.to_string s.elf64_sh_offset)) in - let siz = (Ml_bindings.nat_big_num_of_uint64 s.elf64_sh_size) in - Byte_sequence.offset_and_cut off siz bs0 >>= (fun rel -> - let strings = (Byte_sequence.string_of_byte_sequence rel) in - return (String_table.mk_string_table strings Missing_pervasives.null_char)) - | _ -> fail "get_string_table_of_elf64_dyn_section: multiple section entries with same address as STRTAB" - ) - | D_Ignored i -> fail "get_string_table_of_elf64_dyn_section: STRTAB must be a PTR" - ) - | [] -> fail "get_string_table_of_elf64_dyn_section: no string table entry" - | _ -> fail "get_string_table_of_elf64_dyn_section: multiple string table entries" - )) - -(** [get_value_of_elf32_dyn so dyn os_additional_ranges os proc stab] returns the value - * stored in a dynamic section entry [dyn], using [os_additional_ranges] and - * [os] to decode ABI-reserved tags. String table [stab] is used to correctly - * decode library and run paths, etc. - * May fail. - *) -(*val get_value_of_elf32_dyn : bool -> elf32_dyn -> (natural -> bool) -> - (elf32_dyn -> string_table -> error elf32_dyn_value) -> - (elf32_dyn -> string_table -> error elf32_dyn_value) -> - string_table -> error elf32_dyn_value*) -let get_value_of_elf32_dyn shared_object dyn os_additional_ranges os proc stab:(((Uint32.uint32),(Uint32.uint32))dyn_value)error= - (let tag = (Nat_big_num.abs (Nat_big_num.of_int32 dyn.elf32_dyn_tag)) in - if Nat_big_num.equal tag dt_null then - return Null - else if Nat_big_num.equal tag dt_needed then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf32_dyn_entry: NEEDED must be a Val" - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: NEEDED must be a Val" - ) >>= (fun off -> - let off = (Nat_big_num.of_string (Uint32.to_string off)) in - String_table.get_string_at off stab >>= (fun str -> - return (Library str))) - else if Nat_big_num.equal tag dt_pltrelsz then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf32_dyn_entry: PLTRELSZ must be a Val" - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: PLTRELSZ must be a Val" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_pltgot then - (match dyn.elf32_dyn_d_un with - | D_Val v -> fail "get_value_of_elf32_dyn_entry: PLTGOT must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: PLTGOT must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_hash then - (match dyn.elf32_dyn_d_un with - | D_Val v -> fail "get_value_of_elf32_dyn_entry: HASH must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: HASH must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_strtab then - (match dyn.elf32_dyn_d_un with - | D_Val v -> fail "get_value_of_elf32_dyn_entry: STRTAB must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: STRTAB must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_symtab then - (match dyn.elf32_dyn_d_un with - | D_Val v -> fail "get_value_of_elf32_dyn_entry: SYMTAB must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: SYMTAB must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_rela then - (match dyn.elf32_dyn_d_un with - | D_Val v -> fail "get_value_of_elf32_dyn_entry: RELA must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: RELA must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_relasz then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf32_dyn_entry: RELASZ must be a VAL" - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: RELASZ must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_relaent then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf32_dyn_entry: RELAENT must be a VAL" - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: RELAENT must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_strsz then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf32_dyn_entry: STRSZ must be a VAL" - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: STRSZ must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_syment then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf32_dyn_entry: SYMENT must be a VAL" - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: SYMENT must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_init then - (match dyn.elf32_dyn_d_un with - | D_Val v -> fail "get_value_of_elf32_dyn_entry: INIT must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: INIT must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_fini then - (match dyn.elf32_dyn_d_un with - | D_Val v -> fail "get_value_of_elf32_dyn_entry: FINI must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: FINI must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_soname then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf32_dyn_entry: SONAME must be a Val" - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: SONAME must be a Val" - ) >>= (fun off -> - let off = (Nat_big_num.of_string (Uint32.to_string off)) in - String_table.get_string_at off stab >>= (fun str -> - return (SOName str))) - else if Nat_big_num.equal tag dt_rpath then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf32_dyn_entry: RPATH must be a Val" - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: RPATH must be a Val" - ) >>= (fun off -> - let off = (Nat_big_num.of_string (Uint32.to_string off)) in - String_table.get_string_at off stab >>= (fun str -> - return (RPath str))) - else if Nat_big_num.equal tag dt_symbolic then - return Null - else if Nat_big_num.equal tag dt_rel then - (match dyn.elf32_dyn_d_un with - | D_Val v -> fail "get_value_of_elf32_dyn_entry: REL must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: REL must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_relsz then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf32_dyn_entry: RELSZ must be a VAL" - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: RELSZ must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_relent then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf32_dyn_entry: RELENT must be a VAL" - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: RELENT must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_pltrel then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf32_dyn_entry: PLTREL must be a VAL" - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: PLTREL must be a VAL" - ) >>= (fun r -> - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string r)) dt_rel then - return (RelType Rel) - else if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string r)) dt_rela then - return (RelType RelA) - else - fail "get_value_of_elf32_dyn_entry: PLTREL neither REL nor RELA") - else if Nat_big_num.equal tag dt_debug then - return Null - else if Nat_big_num.equal tag dt_textrel then - return Null - else if Nat_big_num.equal tag dt_jmprel then - (match dyn.elf32_dyn_d_un with - | D_Val v -> fail "get_value_of_elf32_dyn_entry: JMPREL must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: JMPREL must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_bindnow then - return Ignored - else if Nat_big_num.equal tag dt_init_array then - (match dyn.elf32_dyn_d_un with - | D_Val v -> fail "get_value_of_elf32_dyn_entry: INIT_ARRAY must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: INIT_ARRAY must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_fini_array then - (match dyn.elf32_dyn_d_un with - | D_Val v -> fail "get_value_of_elf32_dyn_entry: FINI_ARRAY must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: FINI_ARRAY must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_init_arraysz then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf32_dyn_entry: INIT_ARRAYSZ must be a VAL" - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: INIT_ARRAYSZ must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_fini_arraysz then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf32_dyn_entry: FINI_ARRAYSZ must be a VAL" - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: FINI_ARRAYSZ must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_runpath then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf32_dyn_entry: RUNPATH must be a Val" - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: RUNPATH must be a Val" - ) >>= (fun off -> - let off = (Nat_big_num.of_string (Uint32.to_string off)) in - String_table.get_string_at off stab >>= (fun str -> - return (RunPath str))) - else if Nat_big_num.equal tag dt_flags then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf32_dyn_entry: FLAGS must be a Val" - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: FLAGS must be a Val" - ) >>= (fun flags -> - return (Flags (Nat_big_num.of_string (Uint32.to_string flags)))) - else if Nat_big_num.equal tag dt_encoding then - if not shared_object then - return Ignored - else - (match dyn.elf32_dyn_d_un with - | D_Val v -> fail "get_value_of_elf32_dyn_entry: PREINIT_ARRAY must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: PREINIT_ARRAY must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_preinit_arraysz then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf32_dyn_entry: PREINIT_ARRAYSZ must be a VAL" - | D_Ignored i -> fail "get_value_of_elf32_dyn_entry: PREINIT_ARRAYSZ must be a VAL" - ) >>= (fun sz -> - return (Checksum (Nat_big_num.of_string (Uint32.to_string sz)))) (** XXX: bug in readelf does not print this as a size! *) - else if Nat_big_num.greater_equal tag dt_loproc && Nat_big_num.less_equal tag dt_hiproc then - proc dyn stab - else if Nat_big_num.greater_equal tag dt_loos && Nat_big_num.less_equal tag dt_hios then - os dyn stab - else if os_additional_ranges tag then - os dyn stab - else - fail "get_value_of_elf32_dyn: unrecognised tag type") - -(** [get_value_of_elf64_dyn dyn os_additional_ranges os proc stab] returns the value - * stored in a dynamic section entry [dyn], using [os_additional_ranges] and - * [os] to decode ABI-reserved tags. String table [stab] is used to correctly - * decode library and run paths, etc. - * May fail. - *) -(*val get_value_of_elf64_dyn : bool -> elf64_dyn -> (natural -> bool) -> - (elf64_dyn -> string_table -> error elf64_dyn_value) -> - (elf64_dyn -> string_table -> error elf64_dyn_value) -> - string_table -> error elf64_dyn_value*) -let get_value_of_elf64_dyn shared_object dyn os_additional_ranges os_dyn proc_dyn stab:(((Uint64.uint64),(Uint64.uint64))dyn_value)error= - (let tag = (Nat_big_num.abs (Nat_big_num.of_int64 dyn.elf64_dyn_tag)) in - if Nat_big_num.equal tag dt_null then - return Null - else if Nat_big_num.equal tag dt_needed then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf64_dyn_entry: NEEDED must be a Val" - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: NEEDED must be a Val" - ) >>= (fun off -> - let off = (Ml_bindings.nat_big_num_of_uint64 off) in - String_table.get_string_at off stab >>= (fun str -> - return (Library str))) - else if Nat_big_num.equal tag dt_pltrelsz then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf64_dyn_entry: PLTRELSZ must be a Val" - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: PLTRELSZ must be a Val" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_pltgot then - (match dyn.elf64_dyn_d_un with - | D_Val v -> fail "get_value_of_elf64_dyn_entry: PLTGOT must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: PLTGOT must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_hash then - (match dyn.elf64_dyn_d_un with - | D_Val v -> fail "get_value_of_elf64_dyn_entry: HASH must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: HASH must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_strtab then - (match dyn.elf64_dyn_d_un with - | D_Val v -> fail "get_value_of_elf64_dyn_entry: STRTAB must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: STRTAB must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_symtab then - (match dyn.elf64_dyn_d_un with - | D_Val v -> fail "get_value_of_elf64_dyn_entry: SYMTAB must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: SYMTAB must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_rela then - (match dyn.elf64_dyn_d_un with - | D_Val v -> fail "get_value_of_elf64_dyn_entry: RELA must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: RELA must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_relasz then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf64_dyn_entry: RELASZ must be a VAL" - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: RELASZ must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_relaent then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf64_dyn_entry: RELAENT must be a VAL" - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: RELAENT must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_strsz then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf64_dyn_entry: STRSZ must be a VAL" - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: STRSZ must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_syment then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf64_dyn_entry: SYMENT must be a VAL" - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: SYMENT must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_init then - (match dyn.elf64_dyn_d_un with - | D_Val v -> fail "get_value_of_elf64_dyn_entry: INIT must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: INIT must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_fini then - (match dyn.elf64_dyn_d_un with - | D_Val v -> fail "get_value_of_elf64_dyn_entry: FINI must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: FINI must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_soname then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf64_dyn_entry: SONAME must be a Val" - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: SONAME must be a Val" - ) >>= (fun off -> - let off = (Ml_bindings.nat_big_num_of_uint64 off) in - String_table.get_string_at off stab >>= (fun str -> - return (SOName str))) - else if Nat_big_num.equal tag dt_rpath then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf64_dyn_entry: RPATH must be a Val" - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: RPATH must be a Val" - ) >>= (fun off -> - let off = (Ml_bindings.nat_big_num_of_uint64 off) in - String_table.get_string_at off stab >>= (fun str -> - return (RPath str))) - else if Nat_big_num.equal tag dt_symbolic then - return Null - else if Nat_big_num.equal tag dt_rel then - (match dyn.elf64_dyn_d_un with - | D_Val v -> fail "get_value_of_elf64_dyn_entry: REL must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: REL must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_relsz then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf64_dyn_entry: RELSZ must be a VAL" - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: RELSZ must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_relent then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf64_dyn_entry: RELENT must be a VAL" - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: RELENT must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_pltrel then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf64_dyn_entry: PLTREL must be a VAL" - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: PLTREL must be a VAL" - ) >>= (fun r -> - if Nat_big_num.equal (Ml_bindings.nat_big_num_of_uint64 r) dt_rel then - return (RelType Rel) - else if Nat_big_num.equal (Ml_bindings.nat_big_num_of_uint64 r) dt_rela then - return (RelType RelA) - else - fail "get_value_of_elf64_dyn_entry: PLTREL neither REL nor RELA") - else if Nat_big_num.equal tag dt_debug then - return Null - else if Nat_big_num.equal tag dt_textrel then - return Null - else if Nat_big_num.equal tag dt_jmprel then - (match dyn.elf64_dyn_d_un with - | D_Val v -> fail "get_value_of_elf64_dyn_entry: JMPREL must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: JMPREL must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_bindnow then - return Ignored - else if Nat_big_num.equal tag dt_init_array then - (match dyn.elf64_dyn_d_un with - | D_Val v -> fail "get_value_of_elf64_dyn_entry: INIT_ARRAY must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: INIT_ARRAY must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_fini_array then - (match dyn.elf64_dyn_d_un with - | D_Val v -> fail "get_value_of_elf64_dyn_entry: FINI_ARRAY must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: FINI_ARRAY must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_init_arraysz then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf64_dyn_entry: INIT_ARRAYSZ must be a VAL" - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: INIT_ARRAYSZ must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_fini_arraysz then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf64_dyn_entry: FINI_ARRAYSZ must be a VAL" - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: FINI_ARRAYSZ must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag dt_runpath then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf64_dyn_entry: RUNPATH must be a Val" - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: RUNPATH must be a Val" - ) >>= (fun off -> - let off = (Ml_bindings.nat_big_num_of_uint64 off) in - String_table.get_string_at off stab >>= (fun str -> - return (RunPath str))) - else if Nat_big_num.equal tag dt_flags then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf64_dyn_entry: FLAGS must be a Val" - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: FLAGS must be a Val" - ) >>= (fun flags -> - return (Flags (Ml_bindings.nat_big_num_of_uint64 flags))) - else if Nat_big_num.equal tag dt_encoding then - if not shared_object then - return Ignored - else - (match dyn.elf64_dyn_d_un with - | D_Val v -> fail "get_value_of_elf64_dyn_entry: PREINIT_ARRAY must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: PREINIT_ARRAY must be a PTR" - ) >>= (fun ptr -> - return (Address ptr)) - else if Nat_big_num.equal tag dt_preinit_arraysz then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "get_value_of_elf64_dyn_entry: PREINIT_ARRAYSZ must be a VAL" - | D_Ignored i -> fail "get_value_of_elf64_dyn_entry: PREINIT_ARRAYSZ must be a VAL" - ) >>= (fun sz -> - return (Checksum (Ml_bindings.nat_big_num_of_uint64 sz))) (** XXX: bug in readelf does not print this as a size! *) - else if Nat_big_num.greater_equal tag dt_loproc && Nat_big_num.less_equal tag dt_hiproc then - proc_dyn dyn stab - else if Nat_big_num.greater_equal tag dt_loos && Nat_big_num.less_equal tag dt_hios then - os_dyn dyn stab - else if os_additional_ranges tag then - os_dyn dyn stab - else - fail "get_value_of_elf64_dyn: unrecognised tag type") diff --git a/lib/ocaml_rts/linksem/elf_file.ml b/lib/ocaml_rts/linksem/elf_file.ml deleted file mode 100644 index fda353f8..00000000 --- a/lib/ocaml_rts/linksem/elf_file.ml +++ /dev/null @@ -1,1198 +0,0 @@ -(*Generated by Lem from elf_file.lem.*) -(** Module [elf_file] packages all components of an ELF file up into a single - * record, provides I/O routines for this record, as well as other utility - * functions that operate on an entire ELF file. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_list -open Lem_num -open Lem_maybe -open Lem_string - -open Elf_header -open Elf_interpreted_section -open Elf_interpreted_segment -open Elf_types_native_uint -open Elf_section_header_table -open Elf_symbol_table -open Elf_program_header_table - -open String_table - -open Byte_sequence -open Error -open Missing_pervasives -open Show - -(** [elf32_file] record captures the internal structure of an ELF32 file. - * Invariant: length of the program header and section header tables should match - * the length of their interpreted counterparts, and the nth element of the - * (program/section) header table must correspond to the nth element of the - * interpreted (segments/sections), respectively. - *) -type elf32_file = - { elf32_file_header : elf32_header (** The file header. *) - ; elf32_file_program_header_table : elf32_program_header_table (** The program header table. *) - ; elf32_file_section_header_table : elf32_section_header_table (** The section header table. *) - ; elf32_file_interpreted_segments : elf32_interpreted_segments (** A more usable interpretation of the file's segments. *) - ; elf32_file_interpreted_sections : elf32_interpreted_sections (** A more usable interpretation of the file's sections. *) - ; elf32_file_bits_and_bobs : (Nat_big_num.num * byte_sequence) list (** The uninterpreted "rubbish" that may appear in gaps in the binary file. *) - } - -(** [bytes_of_elf32_file f1] blits ELF file [f1] to a byte sequence, ready for - * writing to a binary file. Fails if the invariant on [elf32_file] mentioned - * above is not respected. - *) -(*val bytes_of_elf32_file : elf32_file -> error byte_sequence*) -let bytes_of_elf32_file ef:(byte_sequence)error= - (let endian = (get_elf32_header_endianness ef.elf32_file_header) in - let hdr_bytes = (bytes_of_elf32_header ef.elf32_file_header) in - let hdr_layout = (Nat_big_num.of_int 0, hdr_bytes) in - let pht_bytes = (bytes_of_elf32_program_header_table endian ef.elf32_file_program_header_table) in - let sht_bytes = (bytes_of_elf32_section_header_table endian ef.elf32_file_section_header_table) in - let pht_off = (Nat_big_num.of_string (Uint32.to_string ef.elf32_file_header.elf32_phoff)) in - let sht_off = (Nat_big_num.of_string (Uint32.to_string ef.elf32_file_header.elf32_shoff)) in - let pht_layout = (pht_off, pht_bytes) in - let sht_layout = (sht_off, sht_bytes) in - let bab_layout = (ef.elf32_file_bits_and_bobs) in - if List.length ef.elf32_file_program_header_table = - List.length ef.elf32_file_interpreted_segments then - if List.length ef.elf32_file_section_header_table = - List.length ef.elf32_file_interpreted_sections then - let segs_zip = (Lem_list.list_combine ef.elf32_file_program_header_table ef.elf32_file_interpreted_segments) in - let sects_zip = (Lem_list.list_combine ef.elf32_file_section_header_table ef.elf32_file_interpreted_sections) in - let segs_layout = -(Lem_list.map (fun (seg, interp_seg) -> - (Nat_big_num.of_string (Uint32.to_string seg.elf32_p_offset), interp_seg.elf32_segment_body) - ) (List.filter (fun (x, _) -> not (x.elf32_p_filesz = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))))) segs_zip)) - in - let sects_layout = -(Lem_list.map (fun (sect, interp_sect) -> - (Nat_big_num.of_string (Uint32.to_string sect.elf32_sh_offset), interp_sect.elf32_section_body) - ) (List.filter (fun (x, _) -> not (x.elf32_sh_type = (Uint32.of_string (Nat_big_num.to_string sht_nobits)))) sects_zip)) - in - let pre_layout = (List.rev_append (List.rev (List.rev_append (List.rev (List.rev_append (List.rev [hdr_layout; pht_layout; sht_layout]) sects_layout)) segs_layout)) bab_layout) in - let final_layout = -(List.sort (fun (off_x, _) (off_y, _) -> Nat_big_num.compare off_x off_y) - pre_layout) - in - let concats = -(foldM (fun x y -> - let (current_offset, so_far) = x in - let (point_to_add, body) = y in - if Nat_big_num.less point_to_add current_offset then - let diff = (Nat_big_num.sub_nat current_offset point_to_add) in - (* Completely contained inside other segment *) - if Nat_big_num.less (Byte_sequence.length0 body) diff then - return (current_offset, so_far) - else - Byte_sequence.partition0 diff body >>= (fun (_, cut) -> - let concat3 = (Byte_sequence.concat0 [so_far; cut]) in - let delta = (Nat_big_num.add current_offset (Byte_sequence.length0 cut)) in - return (delta, concat3)) - else - let diff = (Nat_big_num.sub_nat point_to_add current_offset) in - let reps = (Byte_sequence.create diff '\000') in - let concat3 = (Byte_sequence.concat0 [so_far; reps; body]) in - let delta = (Nat_big_num.add point_to_add (Byte_sequence.length0 body)) in - return (delta, concat3) - ) (Nat_big_num.of_int 0, Byte_sequence.empty) final_layout) - in - concats >>= (fun (offset, body) -> - return body) - else - fail "bytes_of_elf32_file: interpreted sections and section header table must have same length" - else - fail "bytes_of_elf32_file: interpreted segments and program header table must have same length") - -(** [elf64_file] record captures the internal structure of an ELF32 file. - * Invariant: length of the program header and section header tables should match - * the length of their interpreted counterparts, and the nth element of the - * (program/section) header table must correspond to the nth element of the - * interpreted (segments/sections), respectively. - *) -type elf64_file = - { elf64_file_header : elf64_header (** The file header. *) - ; elf64_file_program_header_table : elf64_program_header_table (** The program header table. *) - ; elf64_file_section_header_table : elf64_section_header_table (** The section header table. *) - ; elf64_file_interpreted_segments : elf64_interpreted_segments (** A more usable interpretation of the file's segments. *) - ; elf64_file_interpreted_sections : elf64_interpreted_sections (** A more usable interpretation of the file's sections. *) - ; elf64_file_bits_and_bobs : (Nat_big_num.num * byte_sequence) list (** The uninterpreted "rubbish" that may appear in gaps in the binary file. *) - } - - -type elf_file = - | ELF_File_32 of elf32_file - | ELF_File_64 of elf64_file - - - - -(** [bytes_of_elf64_file f1] blits ELF file [f1] to a byte sequence, ready for - * writing to a binary file. Fails if the invariant on [elf64_file] mentioned - * above is not respected. - *) -(*val bytes_of_elf64_file : elf64_file -> error byte_sequence*) -let bytes_of_elf64_file ef:(byte_sequence)error= - (let endian = (get_elf64_header_endianness ef.elf64_file_header) in - let hdr_bytes = (bytes_of_elf64_header ef.elf64_file_header) in - let hdr_layout = (Nat_big_num.of_int 0, hdr_bytes) in - let pht_bytes = (bytes_of_elf64_program_header_table endian ef.elf64_file_program_header_table) in - let sht_bytes = (bytes_of_elf64_section_header_table endian ef.elf64_file_section_header_table) in - let pht_off = (Nat_big_num.of_string (Uint64.to_string ef.elf64_file_header.elf64_phoff)) in - let sht_off = (Nat_big_num.of_string (Uint64.to_string ef.elf64_file_header.elf64_shoff)) in - let pht_layout = (pht_off, pht_bytes) in - let sht_layout = (sht_off, sht_bytes) in - let bab_layout = (ef.elf64_file_bits_and_bobs) in - if (* List.length ef.elf64_file_program_header_table = - List.length ef.elf64_file_interpreted_segments *) true then - if List.length ef.elf64_file_section_header_table = - List.length ef.elf64_file_interpreted_sections then - let segs_zip = (Lem_list.list_combine ef.elf64_file_program_header_table ef.elf64_file_interpreted_segments) in - let sects_zip = (Lem_list.list_combine ef.elf64_file_section_header_table ef.elf64_file_interpreted_sections) in - let segs_layout = ([]) (* - List.map (fun (seg, interp_seg) -> - (natural_of_elf64_off seg.elf64_p_offset, interp_seg.elf64_segment_body) - ) (List.filter (fun (x, _) -> x.elf64_p_filesz <> elf64_xword_of_natural 0) segs_zip) *) - in - let sects_layout = -(Lem_list.map (fun (sect, interp_sect) -> - (Nat_big_num.of_string (Uint64.to_string sect.elf64_sh_offset), interp_sect.elf64_section_body) - ) (List.filter (fun (x, _) -> not (x.elf64_sh_type = (Uint32.of_string (Nat_big_num.to_string sht_nobits)))) sects_zip)) - in - let pre_layout = (List.rev_append (List.rev (List.rev_append (List.rev (List.rev_append (List.rev [hdr_layout; pht_layout; sht_layout]) sects_layout)) segs_layout)) bab_layout) in - let final_layout = -(List.sort (fun (off_x, _) (off_y, _) -> Nat_big_num.compare off_x off_y) - pre_layout) - in - let concats = -(foldM (fun x y -> - let (current_offset, so_far) = x in - let (point_to_add, body) = y in - if Nat_big_num.less point_to_add current_offset then - let diff = (Nat_big_num.sub_nat current_offset point_to_add) in - (* Completely contained inside other segment *) - if Nat_big_num.less (Byte_sequence.length0 body) diff then - return (current_offset, so_far) - else - Byte_sequence.partition0 diff body >>= (fun (_, cut) -> - let concat3 = (Byte_sequence.concat0 [so_far; cut]) in - let delta = (Nat_big_num.add current_offset (Byte_sequence.length0 cut)) in - return (delta, concat3)) - else - let diff = (Nat_big_num.sub_nat point_to_add current_offset) in - let reps = (Byte_sequence.create diff '\000') in - let concat3 = (Byte_sequence.concat0 [so_far; reps; body]) in - let delta = (Nat_big_num.add point_to_add (Byte_sequence.length0 body)) in - return (delta, concat3) - ) (Nat_big_num.of_int 0, Byte_sequence.empty) final_layout) - in - concats >>= (fun (offset, body) -> - return body) - else - fail "bytes_of_elf64_file: interpreted sections and section header table must have same length" - else - fail "bytes_of_elf64_file: interpreted segments and program header table must have same length") - -(** [obtain_elf32_program_header_table hdr bs0] reads a file's program header table - * from byte sequence [bs0] using information gleaned from the file header [hdr]. - * Fails if transcription fails. - *) -(*val obtain_elf32_program_header_table : elf32_header -> byte_sequence - -> error elf32_program_header_table*) -let obtain_elf32_program_header_table hdr bs0:((elf32_program_header_table_entry)list)error= - (let endian = (get_elf32_header_endianness hdr) in - let pentries = (Nat_big_num.of_string (Uint32.to_string hdr.elf32_phnum)) in - let pentry_size = (Nat_big_num.of_string (Uint32.to_string hdr.elf32_phentsize)) in - let psize = (Nat_big_num.mul pentries pentry_size) in - if Nat_big_num.equal psize(Nat_big_num.of_int 0) then - return [] - else - let poffset = (Nat_big_num.of_string (Uint32.to_string hdr.elf32_phoff)) in - Byte_sequence.offset_and_cut poffset psize bs0 >>= (fun pexact -> - (* Byte sequence irrelevant below as exact size used... *) - read_elf32_program_header_table psize endian pexact >>= (fun (pht, _) -> - return pht))) - -(** [obtain_elf64_program_header_table hdr bs0] reads a file's program header table - * from byte sequence [bs0] using information gleaned from the file header [hdr]. - * Fails if transcription fails. - *) -(*val obtain_elf64_program_header_table : elf64_header -> byte_sequence - -> error elf64_program_header_table*) -let obtain_elf64_program_header_table hdr bs0:((elf64_program_header_table_entry)list)error= - (let endian = (get_elf64_header_endianness hdr) in - let pentries = (Nat_big_num.of_string (Uint32.to_string hdr.elf64_phnum)) in - let pentry_size = (Nat_big_num.of_string (Uint32.to_string hdr.elf64_phentsize)) in - let psize = (Nat_big_num.mul pentries pentry_size) in - if Nat_big_num.equal psize(Nat_big_num.of_int 0) then - return [] - else - let poffset = (Nat_big_num.of_string (Uint64.to_string hdr.elf64_phoff)) in - Byte_sequence.offset_and_cut poffset psize bs0 >>= (fun pexact -> - (* Byte sequence irrelevant below as exact size used... *) - read_elf64_program_header_table psize endian pexact >>= (fun (pht, _) -> - return pht))) - -(** [obtain_elf32_section_header_table hdr bs0] reads a file's section header table - * from byte sequence [bs0] using information gleaned from the file header [hdr]. - * Fails if transcription fails. - *) -(*val obtain_elf32_section_header_table : elf32_header -> byte_sequence - -> error elf32_section_header_table*) -let obtain_elf32_section_header_table hdr bs0:((elf32_section_header_table_entry)list)error= - (let endian = (get_elf32_header_endianness hdr) in - let sentries = (Nat_big_num.of_string (Uint32.to_string hdr.elf32_shnum)) in - let sentry_size = (Nat_big_num.of_string (Uint32.to_string hdr.elf32_shentsize)) in - let ssize = (Nat_big_num.mul sentries sentry_size) in - if Nat_big_num.equal ssize(Nat_big_num.of_int 0) then - return [] - else - let soffset = (Nat_big_num.of_string (Uint32.to_string hdr.elf32_shoff)) in - Byte_sequence.offset_and_cut soffset ssize bs0 >>= (fun sexact -> - (* Byte sequence irrelevant below as exact size used... *) - read_elf32_section_header_table ssize endian sexact >>= (fun (sht, _) -> - return sht))) - -(** [obtain_elf64_section_header_table hdr bs0] reads a file's section header table - * from byte sequence [bs0] using information gleaned from the file header [hdr]. - * Fails if transcription fails. - *) -(*val obtain_elf64_section_header_table : elf64_header -> byte_sequence -> error elf64_section_header_table*) -let obtain_elf64_section_header_table hdr bs0:((elf64_section_header_table_entry)list)error= - (let endian = (get_elf64_header_endianness hdr) in - let sentries = (Nat_big_num.of_string (Uint32.to_string hdr.elf64_shnum)) in - let sentry_size = (Nat_big_num.of_string (Uint32.to_string hdr.elf64_shentsize)) in - let ssize = (Nat_big_num.mul sentries sentry_size) in - if Nat_big_num.equal ssize(Nat_big_num.of_int 0) then - return [] - else - let soffset = (Nat_big_num.of_string (Uint64.to_string hdr.elf64_shoff)) in - Byte_sequence.offset_and_cut soffset ssize bs0 >>= (fun sexact -> - (* Byte sequence irrelevant below as exact size used... *) - read_elf64_section_header_table ssize endian sexact >>= (fun (sht, _) -> - return sht))) - -(** [obtain_elf32_section_header_string_table hdr sht bs0] reads a file's section - * header string table from byte sequence [bs0] using information gleaned from - * the file header [hdr] and section header table [sht]. - * Fails if transcription fails. - *) -(*val obtain_elf32_section_header_string_table : elf32_header -> - elf32_section_header_table -> byte_sequence -> error (maybe string_table)*) -let obtain_elf32_section_header_string_table hdr sht bs0:((string_table)option)error= - (if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string hdr.elf32_shstrndx)) shn_undef then - return None - else - (match Ml_bindings.list_index_big_int (Nat_big_num.of_string (Uint32.to_string hdr.elf32_shstrndx)) sht with - None -> fail "no section header string table" - | Some x -> return x - ) >>= (fun sh -> - Byte_sequence.offset_and_cut (Nat_big_num.of_string (Uint32.to_string sh.elf32_sh_offset)) (Nat_big_num.of_string (Uint32.to_string sh.elf32_sh_size)) bs0 >>= (fun sexact -> - return (Some (string_table_of_byte_sequence sexact))))) - -(** [obtain_elf64_section_header_string_table hdr sht bs0] reads a file's section - * header string table from byte sequence [bs0] using information gleaned from - * the file header [hdr] and section header table [sht]. - * Fails if transcription fails. - *) -(*val obtain_elf64_section_header_string_table : elf64_header -> - elf64_section_header_table -> byte_sequence -> error (maybe string_table)*) -let obtain_elf64_section_header_string_table hdr sht bs0:((string_table)option)error= - (if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string hdr.elf64_shstrndx)) shn_undef then - return None - else - (match Ml_bindings.list_index_big_int (Nat_big_num.of_string (Uint32.to_string hdr.elf64_shstrndx)) sht with - None -> fail "no section header string table" - | Some x -> return x - ) >>= (fun sh -> - Byte_sequence.offset_and_cut (Nat_big_num.of_string (Uint64.to_string sh.elf64_sh_offset)) (Ml_bindings.nat_big_num_of_uint64 sh.elf64_sh_size) bs0 >>= (fun sexact -> - return (Some (string_table_of_byte_sequence sexact))))) - -(** [obtain_elf32_interpreted_segments pht bs0] generates the interpreted segments - * of an ELF file from the uninterpreted program header table entries in [pht], - * read from byte sequence [bs0]. Makes working with segments easier. - * May fail if transcription of any segment fails. - *) -(*val obtain_elf32_interpreted_segments : elf32_program_header_table -> byte_sequence - -> error elf32_interpreted_segments*) -let obtain_elf32_interpreted_segments pht bdy:((elf32_interpreted_segment)list)error= - (mapM (fun ph -> - let offset = (Nat_big_num.of_string (Uint32.to_string ph.elf32_p_offset)) in - let size2 = (Nat_big_num.of_string (Uint32.to_string ph.elf32_p_filesz)) in - (if Nat_big_num.equal size2(Nat_big_num.of_int 0) then - return Byte_sequence.empty - else - Byte_sequence.offset_and_cut offset size2 bdy) >>= (fun relevant -> - let vaddr = (Nat_big_num.of_string (Uint32.to_string ph.elf32_p_vaddr)) in - let paddr = (Nat_big_num.of_string (Uint32.to_string ph.elf32_p_paddr)) in - let memsz = (Nat_big_num.of_string (Uint32.to_string ph.elf32_p_memsz)) in - let typ = (Nat_big_num.of_string (Uint32.to_string ph.elf32_p_type)) in - let align = (Nat_big_num.of_string (Uint32.to_string ph.elf32_p_align)) in - let flags = (elf32_interpret_program_header_flags ph.elf32_p_flags) in - if Nat_big_num.less memsz size2 then - fail "obtain_elf32_interpreted_segments: memory size of segment cannot be less than file size" - else - return { elf32_segment_body = relevant; elf32_segment_type = typ; - elf32_segment_size = size2; elf32_segment_memsz = memsz; - elf32_segment_base = vaddr; elf32_segment_flags = flags; - elf32_segment_paddr = paddr; elf32_segment_align = align; - elf32_segment_offset = offset }) - ) pht) - -(** [obtain_elf64_interpreted_segments pht bs0] generates the interpreted segments - * of an ELF file from the uninterpreted program header table entries in [pht], - * read from byte sequence [bs0]. Makes working with segments easier. - * May fail if transcription of any segment fails. - *) -(*val obtain_elf64_interpreted_segments : elf64_program_header_table -> byte_sequence - -> error elf64_interpreted_segments*) -let obtain_elf64_interpreted_segments pht bdy:((elf64_interpreted_segment)list)error= - (mapM (fun ph -> - let offset = (Nat_big_num.of_string (Uint64.to_string ph.elf64_p_offset)) in - let size2 = (Ml_bindings.nat_big_num_of_uint64 ph.elf64_p_filesz) in - (if Nat_big_num.equal size2(Nat_big_num.of_int 0) then - return Byte_sequence.empty - else - Byte_sequence.offset_and_cut offset size2 bdy) >>= (fun relevant -> - let vaddr = (Ml_bindings.nat_big_num_of_uint64 ph.elf64_p_vaddr) in - let paddr = (Ml_bindings.nat_big_num_of_uint64 ph.elf64_p_paddr) in - let memsz = (Ml_bindings.nat_big_num_of_uint64 ph.elf64_p_memsz) in - let typ = (Nat_big_num.of_string (Uint32.to_string ph.elf64_p_type)) in - let align = (Ml_bindings.nat_big_num_of_uint64 ph.elf64_p_align) in - let flags = (elf64_interpret_program_header_flags ph.elf64_p_flags) in - if Nat_big_num.less memsz size2 then - fail "obtain_elf64_interpreted_segments: memory size of segment cannot be less than file size" - else - return { elf64_segment_body = relevant; elf64_segment_type = typ; - elf64_segment_size = size2; elf64_segment_memsz = memsz; - elf64_segment_base = vaddr; elf64_segment_flags = flags; - elf64_segment_align = align; elf64_segment_paddr = paddr; - elf64_segment_offset = offset }) - ) pht) - -(** [obtain_elf32_interpreted_section sht bs0] generates the interpreted sections - * of an ELF file from the uninterpreted section header table entries in [sht], - * read from byte sequence [bs0]. Makes working with sections easier. - * May fail if transcription of any section fails. - *) -(*val obtain_elf32_interpreted_sections : maybe string_table -> elf32_section_header_table - -> byte_sequence -> error elf32_interpreted_sections*) -let obtain_elf32_interpreted_sections shstrtab sht bs0:((elf32_interpreted_section)list)error= - (mapM (fun sh -> - let offset = (Nat_big_num.of_string (Uint32.to_string sh.elf32_sh_offset)) in - let size2 = (Nat_big_num.of_string (Uint32.to_string sh.elf32_sh_size)) in - let name1 = (Nat_big_num.of_string (Uint32.to_string sh.elf32_sh_name)) in - let typ = (Nat_big_num.of_string (Uint32.to_string sh.elf32_sh_type)) in - let filesz = (if Nat_big_num.equal typ sht_nobits then Nat_big_num.of_int 0 else size2) in - let flags = (Nat_big_num.of_string (Uint32.to_string sh.elf32_sh_flags)) in - let base = (Nat_big_num.of_string (Uint32.to_string sh.elf32_sh_addr)) in - let link1 = (Nat_big_num.of_string (Uint32.to_string sh.elf32_sh_link)) in - let info = (Nat_big_num.of_string (Uint32.to_string sh.elf32_sh_info)) in - let align = (Nat_big_num.of_string (Uint32.to_string sh.elf32_sh_addralign)) in - let entry_size = (Nat_big_num.of_string (Uint32.to_string sh.elf32_sh_entsize)) in - let name_string = -((match shstrtab with - None -> "" - | Some shstrtab -> - (match (get_string_at name1 shstrtab) with - | Success n -> n - | Fail _ -> "" - ) - )) - in - (if Nat_big_num.equal filesz(Nat_big_num.of_int 0) then - return Byte_sequence.empty - else - Byte_sequence.offset_and_cut offset filesz bs0) >>= (fun relevant -> - return { elf32_section_name = name1; elf32_section_type = typ; - elf32_section_size = size2; elf32_section_offset = offset; - elf32_section_flags = flags; elf32_section_addr = base; - elf32_section_link = link1; elf32_section_info = info; - elf32_section_align = align; elf32_section_body = relevant; - elf32_section_entsize = entry_size; - elf32_section_name_as_string = name_string }) - ) sht) - -(** [obtain_elf64_interpreted_section sht bs0] generates the interpreted sections - * of an ELF file from the uninterpreted section header table entries in [sht], - * read from byte sequence [bs0]. Makes working with sections easier. - * May fail if transcription of any section fails. - *) -(*val obtain_elf64_interpreted_sections : maybe string_table -> elf64_section_header_table - -> byte_sequence -> error elf64_interpreted_sections*) -let obtain_elf64_interpreted_sections shstrtab sht bs0:((elf64_interpreted_section)list)error= - (mapM (fun sh -> - let offset = (Nat_big_num.of_string (Uint64.to_string sh.elf64_sh_offset)) in - let size2 = (Ml_bindings.nat_big_num_of_uint64 sh.elf64_sh_size) in - let name1 = (Nat_big_num.of_string (Uint32.to_string sh.elf64_sh_name)) in - let typ = (Nat_big_num.of_string (Uint32.to_string sh.elf64_sh_type)) in - let filesz = (if Nat_big_num.equal typ sht_nobits then Nat_big_num.of_int 0 else size2) in - let flags = (Ml_bindings.nat_big_num_of_uint64 sh.elf64_sh_flags) in - let base = (Ml_bindings.nat_big_num_of_uint64 sh.elf64_sh_addr) in - let link1 = (Nat_big_num.of_string (Uint32.to_string sh.elf64_sh_link)) in - let info = (Nat_big_num.of_string (Uint32.to_string sh.elf64_sh_info)) in - let align = (Ml_bindings.nat_big_num_of_uint64 sh.elf64_sh_addralign) in - let entry_size = (Ml_bindings.nat_big_num_of_uint64 sh.elf64_sh_entsize) in - let name_string = -((match shstrtab with - None -> "" - | Some shstrtab -> - (match (get_string_at name1 shstrtab) with - | Success n -> n - | Fail _ -> "" - ) - )) - in - (if Nat_big_num.equal filesz(Nat_big_num.of_int 0) then - return Byte_sequence.empty - else - Byte_sequence.offset_and_cut offset filesz bs0) >>= (fun relevant -> - return { elf64_section_name = name1; elf64_section_type = typ; - elf64_section_size = size2; elf64_section_offset = offset; - elf64_section_flags = flags; elf64_section_addr = base; - elf64_section_link = link1; elf64_section_info = info; - elf64_section_align = align; elf64_section_body = relevant; - elf64_section_entsize = entry_size; - elf64_section_name_as_string = name_string }) - ) sht) - -(** [find_first_not_in_range e rngs] for every pair (start, end) in [rngs], finds - * the first element, beginning counting from [e], that does not lie between - * a start and end value. - *) -(*val find_first_not_in_range : natural -> list (natural * natural) -> natural*) -let rec find_first_not_in_range start ranges:Nat_big_num.num= - ((match List.filter (fun (x, y) -> Nat_big_num.greater_equal start x && Nat_big_num.less_equal start y) ranges with - | [] -> start - | _ -> find_first_not_in_range ( Nat_big_num.add start(Nat_big_num.of_int 1)) ranges - )) - -(** [find_first_in_range e rngs] for every pair (start, end) in [rngs], finds - * the first element, beginning counting from [e], that lies between - * a start and end value. - *) -(*val find_first_in_range : natural -> list (natural * natural) -> natural*) -let rec find_first_in_range start ranges:Nat_big_num.num= - ((match List.filter (fun (x, y) -> Nat_big_num.greater_equal start x && Nat_big_num.less_equal start y) ranges with - | [] -> find_first_in_range ( Nat_big_num.add start(Nat_big_num.of_int 1)) ranges - | _ -> start - )) - -(** [compute_differences start max ranges] is a utility function used for calculating - * "dead" spots in an ELF file not covered by any of the interpreted structure - * that nevertheless need recording in the bits_and_bobs field of each ELF record - * in order to maintain in-out roundtripping up to exact binary equivalence. - *) -(*val compute_differences : natural -> natural -> list (natural * natural) -> error (list (natural * natural))*) -let rec compute_differences start max ranges:((Nat_big_num.num*Nat_big_num.num)list)error= - (if Nat_big_num.equal start max then - return [] - else if Nat_big_num.greater start max then - fail "compute_differences: passed maximum" - else - let first = (find_first_not_in_range start ranges) in - if Nat_big_num.greater_equal first max then - return [] - else - let last1 = (find_first_in_range first ranges) in - if Nat_big_num.greater last1 max then - return [(first, max)] - else - compute_differences last1 max ranges >>= (fun tail -> - return ((first, last1)::tail))) - -(** [obtain_elf32_bits_and_bobs hdr pht segs sht sects bs0] identifies and records - * the "dead" spots of an ELF file not covered by any meaningful structure of the - * ELF file format. - *) -(*val obtain_elf32_bits_and_bobs : elf32_header -> elf32_program_header_table -> elf32_interpreted_segments - -> elf32_section_header_table -> elf32_interpreted_sections -> byte_sequence -> error (list (natural * byte_sequence))*) -let obtain_elf32_bits_and_bobs hdr segs interp_segs sects interp_sects bs0:((Nat_big_num.num*byte_sequence)list)error= - (let hdr_off_len = (Nat_big_num.of_int 0, Nat_big_num.of_string (Uint32.to_string hdr.elf32_ehsize)) in - let pht_off = (Nat_big_num.of_string (Uint32.to_string hdr.elf32_phoff)) in - let pht_len = (Nat_big_num.mul (Nat_big_num.of_string (Uint32.to_string hdr.elf32_phentsize)) (Nat_big_num.of_string (Uint32.to_string hdr.elf32_phnum))) in - let pht_off_len = (pht_off, Nat_big_num.add pht_off pht_len) in - let sht_off = (Nat_big_num.of_string (Uint32.to_string hdr.elf32_shoff)) in - let sht_len = (Nat_big_num.mul (Nat_big_num.of_string (Uint32.to_string hdr.elf32_shentsize)) (Nat_big_num.of_string (Uint32.to_string hdr.elf32_shnum))) in - let sht_off_len = (sht_off, Nat_big_num.add sht_off sht_len) in - if List.length interp_segs = List.length segs then - let seg_zip = (Lem_list.list_combine segs interp_segs) in - if List.length interp_sects = List.length sects then - let sect_zip = (Lem_list.list_combine sects interp_sects) in - let seg_off_len = -(Lem_list.map (fun (seg, interp_seg) -> - let start = (Nat_big_num.of_string (Uint32.to_string seg.elf32_p_offset)) in - let len = (interp_seg.elf32_segment_size) in - (start, Nat_big_num.add start len)) seg_zip) - in - let sect_off_len = -(Lem_list.map (fun (sect, interp_sect) -> - let start = (Nat_big_num.of_string (Uint32.to_string sect.elf32_sh_offset)) in - let len = (interp_sect.elf32_section_size) in - (start, Nat_big_num.add start len)) sect_zip) - in - let pre_layout = (hdr_off_len :: (pht_off_len :: (sht_off_len :: List.rev_append (List.rev seg_off_len) sect_off_len))) in - let layout = -(List.sort (fun (off_x, _) (off_y, _) -> - Nat_big_num.compare off_x off_y - ) pre_layout) - in - compute_differences(Nat_big_num.of_int 0) (Byte_sequence.length0 bs0) layout >>= (fun diffs -> - mapM (fun (start, len) -> - Byte_sequence.offset_and_cut start ( Nat_big_num.sub_nat len start) bs0 >>= (fun rel -> - return (start, rel)) - ) diffs) - else - fail "obtain_elf32_bits_and_bobs: section header table and interpreted section differ in length" - else - fail "obtain_elf32_bits_and_bobs: program header table and interpreted segments differ in length") - -(** [obtain_elf64_bits_and_bobs hdr pht segs sht sects bs0] identifies and records - * the "dead" spots of an ELF file not covered by any meaningful structure of the - * ELF file format. - *) -(*val obtain_elf64_bits_and_bobs : elf64_header -> elf64_program_header_table -> elf64_interpreted_segments - -> elf64_section_header_table -> elf64_interpreted_sections -> byte_sequence -> error (list (natural * byte_sequence))*) -let obtain_elf64_bits_and_bobs hdr segs interp_segs sects interp_sects bs0:((Nat_big_num.num*byte_sequence)list)error= - (let hdr_off_len = (Nat_big_num.of_int 0, Nat_big_num.of_string (Uint32.to_string hdr.elf64_ehsize)) in - - let pht_off = (Nat_big_num.of_string (Uint64.to_string hdr.elf64_phoff)) in - let pht_len = (Nat_big_num.mul (Nat_big_num.of_string (Uint32.to_string hdr.elf64_phentsize)) (Nat_big_num.of_string (Uint32.to_string hdr.elf64_phnum))) in - let pht_off_len = (pht_off, Nat_big_num.add pht_off pht_len) in - let sht_off = (Nat_big_num.of_string (Uint64.to_string hdr.elf64_shoff)) in - let sht_len = (Nat_big_num.mul (Nat_big_num.of_string (Uint32.to_string hdr.elf64_shentsize)) (Nat_big_num.of_string (Uint32.to_string hdr.elf64_shnum))) in - let sht_off_len = (sht_off, Nat_big_num.add sht_off sht_len) in - if List.length interp_segs = List.length segs then - let seg_zip = (Lem_list.list_combine segs interp_segs) in - if List.length interp_sects = List.length sects then - let sect_zip = (Lem_list.list_combine sects interp_sects) in - let seg_off_len = -(Lem_list.map (fun (seg, interp_seg) -> - let start = (Nat_big_num.of_string (Uint64.to_string seg.elf64_p_offset)) in - let len = (interp_seg.elf64_segment_size) in - (start, Nat_big_num.add start len)) seg_zip) - in - let sect_off_len = -(Lem_list.map (fun (sect, interp_sect) -> - let start = (Nat_big_num.of_string (Uint64.to_string sect.elf64_sh_offset)) in - let len = (interp_sect.elf64_section_size) in - (start, Nat_big_num.add start len)) sect_zip) - in - let pre_layout = (hdr_off_len :: (pht_off_len :: (sht_off_len :: List.rev_append (List.rev seg_off_len) sect_off_len))) in - let layout = -(List.sort (fun (off_x, _) (off_y, _) -> - Nat_big_num.compare off_x off_y - ) pre_layout) - in - compute_differences(Nat_big_num.of_int 0) (Byte_sequence.length0 bs0) layout >>= (fun diffs -> - mapM (fun (start, finish) -> - Byte_sequence.offset_and_cut start ( Nat_big_num.sub_nat finish start) bs0 >>= (fun rel -> - return (start, rel)) - ) diffs) - else - fail "obtain_elf64_bits_and_bobs: section header table and interpreted section differ in length" - else - fail "obtain_elf64_bits_and_bobs: program header table and interpreted segments differ in length") - -(** [read_elf32_file bs0] reads an ELF32 file from byte sequence [bs0]. Fails if - * transcription fails. - *) -(*val read_elf32_file : byte_sequence -> error elf32_file*) -let read_elf32_file bs0:(elf32_file)error= - (read_elf32_header bs0 >>= (fun (hdr, bs1) -> - obtain_elf32_program_header_table hdr bs0 >>= (fun pht -> - obtain_elf32_section_header_table hdr bs0 >>= (fun sht -> - obtain_elf32_section_header_string_table hdr sht bs0 >>= (fun shstrtab -> - obtain_elf32_interpreted_segments pht bs0 >>= (fun segs -> - obtain_elf32_interpreted_sections shstrtab sht bs0 >>= (fun sects -> - obtain_elf32_bits_and_bobs hdr pht segs sht sects bs0 >>= (fun bits_and_bobs -> - return { elf32_file_header = hdr; - elf32_file_program_header_table = pht; - elf32_file_section_header_table = sht; - elf32_file_interpreted_segments = segs; - elf32_file_interpreted_sections = sects; - elf32_file_bits_and_bobs = bits_and_bobs })))))))) - -(** [read_elf64_file bs0] reads an ELF64 file from byte sequence [bs0]. Fails if - * transcription fails. - *) -(*val read_elf64_file : byte_sequence -> error elf64_file*) -let read_elf64_file bs0:(elf64_file)error= - (read_elf64_header bs0 >>= (fun (hdr, bs1) -> - obtain_elf64_program_header_table hdr bs0 >>= (fun pht -> - obtain_elf64_section_header_table hdr bs0 >>= (fun sht -> - obtain_elf64_section_header_string_table hdr sht bs0 >>= (fun shstrtab -> - obtain_elf64_interpreted_segments pht bs0 >>= (fun segs -> - obtain_elf64_interpreted_sections shstrtab sht bs0 >>= (fun sects -> - obtain_elf64_bits_and_bobs hdr pht segs sht sects bs0 >>= (fun bits_and_bobs -> - return { elf64_file_header = hdr; - elf64_file_program_header_table = pht; - elf64_file_section_header_table = sht; - elf64_file_interpreted_segments = segs; - elf64_file_interpreted_sections = sects; - elf64_file_bits_and_bobs = bits_and_bobs })))))))) - -(** [get_elf32_file_secton_header_string_table f1] returns the ELF file, [f1], - * section header string table. - * TODO: why is this not using obtain_elf32_section_header_string_table above? - *) -(*val get_elf32_file_section_header_string_table : elf32_file -> error string_table*) -let get_elf32_file_section_header_string_table f3:(string_table)error= - (let hdr = (f3.elf32_file_header) in - let sht = (f3.elf32_file_section_header_table) in - let segs = (f3.elf32_file_interpreted_segments) in - let idx1 = (Nat_big_num.of_string (Uint32.to_string hdr.elf32_shstrndx)) in - bytes_of_elf32_file f3 >>= (fun bs0 -> - (match Ml_bindings.list_index_big_int idx1 sht with - | None -> fail "obtain_elf32_string_table: invalid offset into section header table" - | Some sect -> - let offset = (Nat_big_num.of_string (Uint32.to_string sect.elf32_sh_offset)) in - let size2 = (Nat_big_num.of_string (Uint32.to_string sect.elf32_sh_size)) in - Byte_sequence.offset_and_cut offset size2 bs0 >>= (fun rel -> - let strings = (Byte_sequence.string_of_byte_sequence rel) in - return (String_table.mk_string_table strings Missing_pervasives.null_char)) - ))) - -(** [get_elf64_file_secton_header_string_table f1] returns the ELF file, [f1], - * section header string table. - * TODO: why is this not using obtain_elf64_section_header_string_table above? - *) -(*val get_elf64_file_section_header_string_table : elf64_file -> error string_table*) -let get_elf64_file_section_header_string_table f3:(string_table)error= - (let hdr = (f3.elf64_file_header) in - let sht = (f3.elf64_file_section_header_table) in - let segs = (f3.elf64_file_interpreted_segments) in - let idx1 = (Nat_big_num.of_string (Uint32.to_string hdr.elf64_shstrndx)) in - bytes_of_elf64_file f3 >>= (fun bs0 -> - (match Ml_bindings.list_index_big_int idx1 sht with - | None -> fail "obtain_elf64_string_table: invalid offset into section header table" - | Some sect -> - let offset = (Nat_big_num.of_string (Uint64.to_string sect.elf64_sh_offset)) in - let size2 = (Ml_bindings.nat_big_num_of_uint64 sect.elf64_sh_size) in - Byte_sequence.offset_and_cut offset size2 bs0 >>= (fun rel -> - let strings = (Byte_sequence.string_of_byte_sequence rel) in - return (String_table.mk_string_table strings Missing_pervasives.null_char)) - ))) - -(*val find_elf32_symbols_by_symtab_idx : natural -> elf32_file -> error (elf32_symbol_table * string_table * natural)*) -let find_elf32_symbols_by_symtab_idx sec_idx f:((elf32_symbol_table_entry)list*string_table*Nat_big_num.num)error= - ((match Lem_list.list_index f.elf32_file_interpreted_sections (Nat_big_num.to_int sec_idx) with - None -> fail "impossible: interpreted section found but not indexable" - | Some sec -> return sec - ) >>= (fun sec -> - (match Lem_list.list_index f.elf32_file_interpreted_sections (Nat_big_num.to_int sec.elf32_section_link) with - None -> fail "no associated strtab" - | Some strs -> return strs - ) >>= (fun strs -> - let strings = (Byte_sequence.string_of_byte_sequence strs.elf32_section_body) in - let strtab = (String_table.mk_string_table strings null_char) in - let endian = (get_elf32_header_endianness f.elf32_file_header) in - read_elf32_symbol_table endian sec.elf32_section_body >>= (fun symtab -> - return (symtab, strtab, sec_idx))))) - -(*val find_elf32_symtab_by_type : natural -> elf32_file -> error (elf32_symbol_table * string_table * natural)*) -let find_elf32_symtab_by_type t f:(elf32_symbol_table*string_table*Nat_big_num.num)error= - (let found_symtab_index = (find_index0 (fun sh -> Nat_big_num.equal sh.elf32_section_type t) f.elf32_file_interpreted_sections) in - (match found_symtab_index with - None -> fail "no such symtab" - | Some sec_idx -> return sec_idx - ) >>= (fun sec_idx -> find_elf32_symbols_by_symtab_idx sec_idx f)) - -(*val find_elf64_symbols_by_symtab_idx : natural -> elf64_file -> error (elf64_symbol_table * string_table * natural)*) -let find_elf64_symbols_by_symtab_idx sec_idx f:((elf64_symbol_table_entry)list*string_table*Nat_big_num.num)error= - ((match Lem_list.list_index f.elf64_file_interpreted_sections (Nat_big_num.to_int sec_idx) with - None -> fail "impossible: interpreted section found but not indexable" - | Some sec -> return sec - ) >>= (fun sec -> - (match Lem_list.list_index f.elf64_file_interpreted_sections (Nat_big_num.to_int sec.elf64_section_link) with - None -> fail "no associated strtab" - | Some strs -> return strs - ) >>= (fun strs -> - let strings = (Byte_sequence.string_of_byte_sequence strs.elf64_section_body) in - let strtab = (String_table.mk_string_table strings null_char) in - let endian = (get_elf64_header_endianness f.elf64_file_header) in - read_elf64_symbol_table endian sec.elf64_section_body >>= (fun symtab -> - return (symtab, strtab, sec_idx))))) - -(*val find_elf64_symtab_by_type : natural -> elf64_file -> error (elf64_symbol_table * string_table * natural)*) -let find_elf64_symtab_by_type t f:(elf64_symbol_table*string_table*Nat_big_num.num)error= - (let found_symtab_index = (find_index0 (fun sh -> Nat_big_num.equal sh.elf64_section_type t) f.elf64_file_interpreted_sections) in - (match found_symtab_index with - None -> fail "no such symtab" - | Some sec_idx -> return sec_idx - ) >>= (fun sec_idx -> find_elf64_symbols_by_symtab_idx sec_idx f)) - -(** [get_elf32_file_symbol_string_table f1] returns the ELF file [f1] symbol - * string table. May fail. - *) -(*val get_elf32_file_symbol_string_table : elf32_file -> error string_table*) -let get_elf32_file_symbol_string_table f3:(string_table)error= - (let hdr = (f3.elf32_file_header) in - let sht = (f3.elf32_file_section_header_table) in - let segs = (f3.elf32_file_interpreted_segments) in - let strtabs = (Missing_pervasives.mapMaybei (fun index sect -> - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string sect.elf32_sh_type)) sht_strtab then - if Nat_big_num.equal index (Nat_big_num.of_string (Uint32.to_string hdr.elf32_shstrndx)) then - None - else - Some sect - else - None) sht) - in - bytes_of_elf32_file f3 >>= (fun bs0 -> - mapM (fun sect -> - let offset = (Nat_big_num.of_string (Uint32.to_string sect.elf32_sh_offset)) in - let size2 = (Nat_big_num.of_string (Uint32.to_string sect.elf32_sh_size)) in - Byte_sequence.offset_and_cut offset size2 bs0 >>= (fun bs1 -> - let strings = (Byte_sequence.string_of_byte_sequence bs1) in - return (String_table.mk_string_table strings Missing_pervasives.null_char))) strtabs - >>= (fun strings -> - String_table.concat1 strings))) - -(** [get_elf64_file_symbol_string_table f1] returns the ELF file [f1] symbol - * string table. May fail. - *) -(*val get_elf64_file_symbol_string_table : elf64_file -> error string_table*) -let get_elf64_file_symbol_string_table f3:(string_table)error= - (let hdr = (f3.elf64_file_header) in - let sht = (f3.elf64_file_section_header_table) in - let segs = (f3.elf64_file_interpreted_segments) in - let strtabs = (Missing_pervasives.mapMaybei (fun index sect -> - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string sect.elf64_sh_type)) sht_strtab then - if Nat_big_num.equal index (Nat_big_num.of_string (Uint32.to_string hdr.elf64_shstrndx)) then - None - else - Some sect - else - None) sht) - in - bytes_of_elf64_file f3 >>= (fun bs0 -> - mapM (fun sect -> - let offset = (Nat_big_num.of_string (Uint64.to_string sect.elf64_sh_offset)) in - let size2 = (Ml_bindings.nat_big_num_of_uint64 sect.elf64_sh_size) in - Byte_sequence.offset_and_cut offset size2 bs0 >>= (fun bs1 -> - let strings = (Byte_sequence.string_of_byte_sequence bs1) in - return (String_table.mk_string_table strings Missing_pervasives.null_char))) strtabs - >>= (fun strings -> - String_table.concat1 strings))) - -(** [get_elf32_file_symbol_table f1] returns the ELF file [f1] symbol - * table. May fail. - *) -(*val get_elf32_file_symbol_table : elf32_file -> error elf32_symbol_table*) -let get_elf32_file_symbol_table f3:((elf32_symbol_table_entry)list)error= - (let hdr = (f3.elf32_file_header) in - let sht = (f3.elf32_file_section_header_table) in - let segs = (f3.elf32_file_interpreted_segments) in - let endian = (get_elf32_header_endianness hdr) in - let symtabs = (List.filter (fun sect -> Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string sect.elf32_sh_type)) sht_symtab - ) sht) - in - (match symtabs with - | [] -> return [] - | [symtab] -> - let offset = (Nat_big_num.of_string (Uint32.to_string symtab.elf32_sh_offset)) in - let size2 = (Nat_big_num.of_string (Uint32.to_string symtab.elf32_sh_size)) in - bytes_of_elf32_file f3 >>= (fun bs0 -> - Byte_sequence.offset_and_cut offset size2 bs0 >>= (fun relevant -> - read_elf32_symbol_table endian relevant)) - | _ -> - fail "obtain_elf32_symbol_table: an ELF file may only have one symbol table of type SHT_SYMTAB" - )) - -(** [get_elf64_file_symbol_table f1] returns the ELF file [f1] symbol - * table. May fail. - *) -(*val get_elf64_file_symbol_table : elf64_file -> error elf64_symbol_table*) -let get_elf64_file_symbol_table f3:((elf64_symbol_table_entry)list)error= - (let hdr = (f3.elf64_file_header) in - let sht = (f3.elf64_file_section_header_table) in - let segs = (f3.elf64_file_interpreted_segments) in - let endian = (get_elf64_header_endianness hdr) in - let symtabs = (List.filter (fun sect -> Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string sect.elf64_sh_type)) sht_symtab - ) sht) - in - (match symtabs with - | [] -> return [] - | [symtab] -> - let offset = (Nat_big_num.of_string (Uint64.to_string symtab.elf64_sh_offset)) in - let size2 = (Ml_bindings.nat_big_num_of_uint64 symtab.elf64_sh_size) in - bytes_of_elf64_file f3 >>= (fun bs0 -> - Byte_sequence.offset_and_cut offset size2 bs0 >>= (fun relevant -> - read_elf64_symbol_table endian relevant)) - | _ -> - fail "obtain_elf64_symbol_table: an ELF file may only have one symbol table of type SHT_SYMTAB" - )) - -(** [get_elf32_file_dynamic_symbol_table f1] returns the ELF file [f1] dynamic - * symbol table. May fail. - *) -(*val get_elf32_file_dynamic_symbol_table : elf32_file -> error elf32_symbol_table*) -let get_elf32_file_dynamic_symbol_table ef:((elf32_symbol_table_entry)list)error= - (let hdr = (ef.elf32_file_header) in - let sht = (ef.elf32_file_section_header_table) in - let segs = (ef.elf32_file_interpreted_segments) in - let endian = (get_elf32_header_endianness hdr) in - let symtabs = (List.filter (fun sect -> Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string sect.elf32_sh_type)) sht_dynsym - ) sht) - in - (match symtabs with - | [] -> return [] - | [symtab] -> - let offset = (Nat_big_num.of_string (Uint32.to_string symtab.elf32_sh_offset)) in - let size2 = (Nat_big_num.of_string (Uint32.to_string symtab.elf32_sh_size)) in - bytes_of_elf32_file ef >>= (fun bs0 -> - Byte_sequence.offset_and_cut offset size2 bs0 >>= (fun relevant -> - read_elf32_symbol_table endian relevant)) - | _ -> - fail "obtain_elf32_dynamic_symbol_table: an ELF file may only have one symbol table of type SHT_DYNSYM" - )) - -(** [get_elf64_file_dynamic_symbol_table f1] returns the ELF file [f1] dynamic - * symbol table. May fail. - *) -(*val get_elf64_file_dynamic_symbol_table : elf64_file -> error elf64_symbol_table*) -let get_elf64_file_dynamic_symbol_table ef:((elf64_symbol_table_entry)list)error= - (let hdr = (ef.elf64_file_header) in - let sht = (ef.elf64_file_section_header_table) in - let segs = (ef.elf64_file_interpreted_segments) in - let endian = (get_elf64_header_endianness hdr) in - let symtabs = (List.filter (fun sect -> Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string sect.elf64_sh_type)) sht_dynsym - ) sht) - in - (match symtabs with - | [] -> return [] - | [symtab] -> - let offset = (Nat_big_num.of_string (Uint64.to_string symtab.elf64_sh_offset)) in - let size2 = (Ml_bindings.nat_big_num_of_uint64 symtab.elf64_sh_size) in - bytes_of_elf64_file ef >>= (fun bs0 -> - Byte_sequence.offset_and_cut offset size2 bs0 >>= (fun relevant -> - read_elf64_symbol_table endian relevant)) - | _ -> - fail "obtain_elf64_dynamic_symbol_table: an ELF file may only have one symbol table of type SHT_DYNSYM" - )) - -(** [get_elf32_file_symbol_table_by_index f1 index] returns the ELF file [f1] - * symbol table that is pointed to by the section header table entry at index - * [index]. May fail if index is out of range, or otherwise. - *) -(*val get_elf32_symbol_table_by_index : elf32_file -> natural -> error elf32_symbol_table*) -let get_elf32_symbol_table_by_index ef link1:(elf32_symbol_table)error= - (let hdr = (ef.elf32_file_header) in - let sht = (ef.elf32_file_section_header_table) in - let sects = (ef.elf32_file_interpreted_sections) in - let endian = (get_elf32_header_endianness hdr) in - (match Lem_list.list_index sects (Nat_big_num.to_int link1) with - | None -> fail "get_elf32_symbol_table_by_index: invalid index" - | Some sym -> - read_elf32_symbol_table endian sym.elf32_section_body - )) - -(** [get_elf32_file_string_table_by_index f1 index] returns the ELF file [f1] - * string table that is pointed to by the section header table entry at index - * [index]. May fail if index is out of range, or otherwise. - *) -(*val get_elf32_string_table_by_index : elf32_file -> natural -> error string_table*) -let get_elf32_string_table_by_index ef link1:(string_table)error= - (let hdr = (ef.elf32_file_header) in - let sht = (ef.elf32_file_section_header_table) in - let sects = (ef.elf32_file_interpreted_sections) in - (match Lem_list.list_index sects (Nat_big_num.to_int link1) with - | None -> fail "get_elf32_string_table_by_index: invalid index" - | Some sym -> return (mk_string_table (Byte_sequence.string_of_byte_sequence sym.elf32_section_body) Missing_pervasives.null_char) - )) - -(** [get_elf64_file_symbol_table_by_index f1 index] returns the ELF file [f1] - * symbol table that is pointed to by the section header table entry at index - * [index]. May fail if index is out of range, or otherwise. - *) -(*val get_elf64_symbol_table_by_index : elf64_file -> natural -> error elf64_symbol_table*) -let get_elf64_symbol_table_by_index ef link1:(elf64_symbol_table)error= - (let hdr = (ef.elf64_file_header) in - let sht = (ef.elf64_file_section_header_table) in - let sects = (ef.elf64_file_interpreted_sections) in - let endian = (get_elf64_header_endianness hdr) in - (match Lem_list.list_index sects (Nat_big_num.to_int link1) with - | None -> fail "get_elf64_symbol_table_by_index: invalid index" - | Some sym -> - read_elf64_symbol_table endian sym.elf64_section_body - )) - -(** [get_elf64_file_string_table_by_index f1 index] returns the ELF file [f1] - * string table that is pointed to by the section header table entry at index - * [index]. May fail if index is out of range, or otherwise. - *) -(*val get_elf64_string_table_by_index : elf64_file -> natural -> error string_table*) -let get_elf64_string_table_by_index ef link1:(string_table)error= - (let hdr = (ef.elf64_file_header) in - let sht = (ef.elf64_file_section_header_table) in - let sects = (ef.elf64_file_interpreted_sections) in - (match Lem_list.list_index sects (Nat_big_num.to_int link1) with - | None -> fail "get_elf64_string_table_by_index: invalid index" - | Some sym -> return (mk_string_table (Byte_sequence.string_of_byte_sequence sym.elf64_section_body) Missing_pervasives.null_char) - )) - -(** [segment_provenance] records whether a segment that appears in an executable - * process image has been derived directly from an ELF file, or was automatically - * created when the image calculation process noticed a segment with a memory - * size greater than its file size. - * Really a PPCMemism and not strictly needed for the ELF model itself. - *) -type segment_provenance - = FromELF (** Segment derived directly from the source ELF file. *) - | AutoGenerated (** Automatically generated during process extraction as memory size is greater than file size. *) - -(** [elf32_executable_process_image] is a process image for ELF32 files. Contains - * all that is necessary to load the executable components of an ELF32 file - * and begin execution. - * XXX: (segments, provenance), entry point, machine type - *) -type elf32_executable_process_image = - ( (elf32_interpreted_segment * segment_provenance)list * Nat_big_num.num * Nat_big_num.num) - -(** [elf64_executable_process_image] is a process image for ELF64 files. Contains - * all that is necessary to load the executable components of an ELF64 file - * and begin execution. - * XXX: (segments, provenance), entry point, machine type - *) -type elf64_executable_process_image = - ( (elf64_interpreted_segment * segment_provenance)list * Nat_big_num.num * Nat_big_num.num) - -(** [get_elf32_executable_image f1] extracts an executable process image from an - * executable ELF file. May fail if extraction is impossible. - *) -(*val get_elf32_executable_image : elf32_file -> error elf32_executable_process_image*) -let get_elf32_executable_image f3:((elf32_interpreted_segment*segment_provenance)list*Nat_big_num.num*Nat_big_num.num)error= - (if is_elf32_executable_file f3.elf32_file_header then - let entr = (f3.elf32_file_header.elf32_entry) in - let segs = (f3.elf32_file_interpreted_segments) in - let mach = (f3.elf32_file_header.elf32_machine) in - (match List.filter (fun sg -> Nat_big_num.equal 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 Nat_big_num.equal sg.elf32_segment_memsz(Nat_big_num.of_int 0) then - return [] - else if Nat_big_num.equal sg.elf32_segment_memsz sg.elf32_segment_size then - return [(sg, FromELF)] - else if Nat_big_num.less sg.elf32_segment_size sg.elf32_segment_memsz then - (* Cannot be negative due to check in constructing [segs]. *) - let diff = (Nat_big_num.sub_nat sg.elf32_segment_memsz sg.elf32_segment_size) in - let zeros1 = (Byte_sequence.zeros diff) in - let addr = (Nat_big_num.add sg.elf32_segment_base sg.elf32_segment_size) in - let align = (sg.elf32_segment_align) in - let paddr = (sg.elf32_segment_paddr) in - let seg = -({ elf32_segment_body = zeros1; elf32_segment_type = (sg.elf32_segment_type); - elf32_segment_size = diff; elf32_segment_memsz = diff; - elf32_segment_base = addr; elf32_segment_flags = (sg.elf32_segment_flags); - elf32_segment_align = align; elf32_segment_paddr = paddr; - elf32_segment_offset = (sg.elf32_segment_offset) }) - in - return [(sg, FromELF); (seg, AutoGenerated)] - else - fail "get_elf32_executable_image: invariant invalidated") load >>= (fun bs_base -> - return (List.concat bs_base, Nat_big_num.of_string (Uint32.to_string entr), Nat_big_num.of_string (Uint32.to_string mach))) - ) - else - fail "get_elf32_executable_image: not an ELF executable file") - -(** [get_elf64_executable_image f1] extracts an executable process image from an - * executable ELF file. May fail if extraction is impossible. - *) -(*val get_elf64_executable_image : elf64_file -> error elf64_executable_process_image*) -let get_elf64_executable_image f3:((elf64_interpreted_segment*segment_provenance)list*Nat_big_num.num*Nat_big_num.num)error= - (if is_elf64_executable_file f3.elf64_file_header then - let entr = (f3.elf64_file_header.elf64_entry) in - let segs = (f3.elf64_file_interpreted_segments) in - let mach = (f3.elf64_file_header.elf64_machine) in - (match List.filter (fun sg -> Nat_big_num.equal 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 Nat_big_num.equal sg.elf64_segment_memsz(Nat_big_num.of_int 0) then - return [] - else if Nat_big_num.equal sg.elf64_segment_memsz sg.elf64_segment_size then - return [(sg, FromELF)] - else if Nat_big_num.less sg.elf64_segment_size sg.elf64_segment_memsz then - (* Cannot be negative due to check in constructing [segs]. *) - let diff = (Nat_big_num.sub_nat sg.elf64_segment_memsz sg.elf64_segment_size) in - let zeros1 = (Byte_sequence.zeros diff) in - let addr = (Nat_big_num.add sg.elf64_segment_base sg.elf64_segment_size) in - let align = (sg.elf64_segment_align) in - let paddr = (sg.elf64_segment_paddr) in - let seg = -({ elf64_segment_body = zeros1; elf64_segment_type = (sg.elf64_segment_type); - elf64_segment_size = diff; elf64_segment_memsz = diff; - elf64_segment_base = addr; elf64_segment_flags = (sg.elf64_segment_flags); - elf64_segment_align = align; elf64_segment_paddr = paddr; - elf64_segment_offset = (sg.elf64_segment_offset) }) - in - return [(sg, FromELF); (seg, AutoGenerated)] - else - fail "get_elf64_executable_image: invariant invalidated") load >>= (fun bs_base -> - return (List.concat bs_base, Ml_bindings.nat_big_num_of_uint64 entr, Nat_big_num.of_string (Uint32.to_string mach))) - ) - else - fail "elf64_get_executable_image: not an executable ELF file") - -(** [global_symbol_init_info] records the name, type, size, address, chunk - * of initialisation data (if relevant for that symbol), and binding, of every - * global symbol in an ELF file. - * Another PPCMemism. - *) -type global_symbol_init_info - = (string * (Nat_big_num.num * Nat_big_num.num * Nat_big_num.num * byte_sequence option * Nat_big_num.num)) list - -(** [get_elf32_file_global_symbol_init f1] extracts the global symbol init info - * for ELF file [f1]. May fail. - *) -(*val get_elf32_file_global_symbol_init : elf32_file -> error global_symbol_init_info*) -let get_elf32_file_global_symbol_init f3:((string*(Nat_big_num.num*Nat_big_num.num*Nat_big_num.num*(byte_sequence)option*Nat_big_num.num))list)error= - (if is_elf32_executable_file f3.elf32_file_header then - let segs = (f3.elf32_file_interpreted_segments) in - bytes_of_elf32_file f3 >>= (fun bs0 -> - get_elf32_file_symbol_table f3 >>= (fun symtab -> - get_elf32_file_symbol_string_table f3 >>= (fun strtab -> - Elf_symbol_table.get_elf32_symbol_image_address symtab strtab >>= (fun strs -> - let mapped = (mapM (fun (symbol, (typ, size2, addr, bind)) -> - if Nat_big_num.equal typ Elf_symbol_table.stt_object then - get_elf32_executable_image f3 >>= (fun (img2, entry, mach) -> - let chunks1 = -(List.filter (fun (chunk, _) -> Nat_big_num.greater_equal - addr chunk.elf32_segment_base && - (if Nat_big_num.greater size2(Nat_big_num.of_int 0) - then Nat_big_num.less_equal (Nat_big_num.add addr size2) (Nat_big_num.add chunk.elf32_segment_base chunk.elf32_segment_size) - (* We don't consider a zero-size symbol one byte after a section - (i.e. addr = segment_base + segment_size) to be inside that section. *) - else Nat_big_num.less (Nat_big_num.add addr size2) (Nat_big_num.add chunk.elf32_segment_base chunk.elf32_segment_size)) - ) img2) - in - (match chunks1 with - | [] -> fail "get_elf32_global_symbol_init: global variable not present in executable image" - | [(x, _)] -> - let rebase = (Nat_big_num.sub_nat addr x.elf32_segment_base) in - Byte_sequence.offset_and_cut rebase size2 x.elf32_segment_body >>= (fun relevant -> - return (symbol, (typ, size2, addr, Some relevant, bind))) - | x::xs -> fail "get_elf32_global_symbol_init: invariant failed, global variable appears in multiple segments" - )) - else - return (symbol, (typ, size2, addr, None, bind))) strs) - in - mapped)))) - else - fail "get_elf32_file_global_symbol_init: not an executable ELF file") - -(** [get_elf64_file_global_symbol_init f1] extracts the global symbol init info - * for ELF file [f1]. May fail. - *) -(*val get_elf64_file_global_symbol_init : elf64_file -> error global_symbol_init_info*) -let get_elf64_file_global_symbol_init f3:((string*(Nat_big_num.num*Nat_big_num.num*Nat_big_num.num*(byte_sequence)option*Nat_big_num.num))list)error= - (if is_elf64_executable_file f3.elf64_file_header then - let segs = (f3.elf64_file_interpreted_segments) in - bytes_of_elf64_file f3 >>= (fun bs0 -> - get_elf64_file_symbol_table f3 >>= (fun symtab -> - get_elf64_file_symbol_string_table f3 >>= (fun strtab -> - Elf_symbol_table.get_elf64_symbol_image_address symtab strtab >>= (fun strs -> - let mapped = (mapM (fun (symbol, (typ, size2, addr, bind)) -> - if Nat_big_num.equal typ Elf_symbol_table.stt_object then - get_elf64_executable_image f3 >>= (fun (img2, entry, mach) -> - let chunks1 = -(List.filter (fun (chunk, _) -> Nat_big_num.greater_equal - addr chunk.elf64_segment_base && - (if Nat_big_num.greater size2(Nat_big_num.of_int 0) - then Nat_big_num.less_equal (Nat_big_num.add addr size2) (Nat_big_num.add chunk.elf64_segment_base chunk.elf64_segment_size) - (* We don't consider a zero-size symbol one byte after a section - (i.e. addr = segment_base + segment_size) to be inside that section. *) - else Nat_big_num.less (Nat_big_num.add addr size2) (Nat_big_num.add chunk.elf64_segment_base chunk.elf64_segment_size)) - ) img2) - in - (match chunks1 with - | [] -> fail "get_elf64_global_symbol_init: global variable not present in executable image" - | [(x, _)] -> - let rebase = (Nat_big_num.sub_nat addr x.elf64_segment_base) in - Byte_sequence.offset_and_cut rebase size2 x.elf64_segment_body >>= (fun relevant -> - return (symbol, (typ, size2, addr, Some relevant, bind))) - | x::xs -> fail "get_elf64_global_symbol_init: invariant failed, global variable appears in multiple segments" - )) - else - return (symbol, (typ, size2, addr, None, bind))) strs) - in - mapped)))) - else - fail "get_elf64_global_symbol_init: not an executable ELF file") - -(** [string_of_elf32_file hdr_bdl pht_bdl sht_bdl f1] produces a string-based - * representation of ELF file [f1] using ABI-specific print bundles [hdr_bdl], - * [pht_bdl] and [sht_bdl]. - *) -(*val string_of_elf32_file : hdr_print_bundle -> pht_print_bundle -> sht_print_bundle -> elf32_file -> string*) -let string_of_elf32_file hdr_bdl pht_bdl sht_bdl f3:string= - ((match get_elf32_file_section_header_string_table f3 with - | Fail err -> - unlines [ - "\nError obtaining ELF section header string table:" - ; err - ] - | Success strtab -> - unlines [ - "\n*Type elf32_file:" - ; "**Header:" - ; string_of_elf32_header hdr_bdl f3.elf32_file_header - ; "**Program header table:" - ; string_of_elf32_program_header_table pht_bdl f3.elf32_file_program_header_table - ; "**Section header table:" - ; string_of_elf32_section_header_table' sht_bdl strtab f3.elf32_file_section_header_table - ; "**Bits and bobs (unused junk space):" - ; string_of_list - (instance_Show_Show_tup2_dict instance_Show_Show_Num_natural_dict - instance_Show_Show_Byte_sequence_byte_sequence_dict) f3.elf32_file_bits_and_bobs - ] - )) - -(** [string_of_elf64_file hdr_bdl pht_bdl sht_bdl f1] produces a string-based - * representation of ELF file [f1] using ABI-specific print bundles [hdr_bdl], - * [pht_bdl] and [sht_bdl]. - *) -(*val string_of_elf64_file : hdr_print_bundle -> pht_print_bundle -> sht_print_bundle -> elf64_file -> string*) -let string_of_elf64_file hdr_bdl pht_bdl sht_bdl f3:string= - ((match get_elf64_file_section_header_string_table f3 with - | Fail err -> - unlines [ - "\nError obtaining ELF section header string table:" - ; err - ] - | Success strtab -> - unlines [ - "\n*Type elf64_file:" - ; "**Header:" - ; string_of_elf64_header hdr_bdl f3.elf64_file_header - ; "**Program header table:" - ; string_of_elf64_program_header_table pht_bdl f3.elf64_file_program_header_table - ; "**Section header table:" - ; string_of_elf64_section_header_table' sht_bdl strtab f3.elf64_file_section_header_table - ; "**Bits and bobs (unused junk space):" - ; string_of_list - (instance_Show_Show_tup2_dict instance_Show_Show_Num_natural_dict - instance_Show_Show_Byte_sequence_byte_sequence_dict) f3.elf64_file_bits_and_bobs - ] - )) - -(** [flag_is_set flag v] checks whether flag [flag] is set in [v]. - * TODO: move elsewhere. Check whether this is still being used. - *) -(*val flag_is_set : natural -> natural -> bool*) -let flag_is_set flag v:bool= -( - (* HACK: convert to elf64_xword first. Flags never live - * in objects bigger than 64 bits. *)Uint64.logand - (Uint64.of_string (Nat_big_num.to_string v)) - (Uint64.of_string (Nat_big_num.to_string flag)) - = (Uint64.of_string (Nat_big_num.to_string flag))) diff --git a/lib/ocaml_rts/linksem/elf_header.ml b/lib/ocaml_rts/linksem/elf_header.ml deleted file mode 100644 index d8730e9c..00000000 --- a/lib/ocaml_rts/linksem/elf_header.ml +++ /dev/null @@ -1,1508 +0,0 @@ -(*Generated by Lem from elf_header.lem.*) -(** [elf_header] includes types, functions and other definitions for working with - * ELF headers. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_function -open Lem_list -open Lem_maybe -open Lem_num -open Lem_string -(*import Set*) - -open Lem_assert_extra - -open Default_printing -open Endianness - -open Elf_types_native_uint - -open Byte_sequence -open Error -open Missing_pervasives -open Show - -(** Special section header table indices *) - -(** [shn_undef]: marks an undefined, missing or irrelevant section reference. - * Present here instead of in elf_section_header_table.lem because a calculation - * below requires this constant (i.e. forward reference in the ELF spec). - *) -let shn_undef : Nat_big_num.num= (Nat_big_num.of_int 0) - -(** [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). Present here instead - * of in elf_section_header_table.lem because a calculation below requires this - * constant (i.e. forward reference in the ELF spec). - *) -let shn_xindex : Nat_big_num.num= (Nat_big_num.of_int 65535) (* 0xffff *) - -(** ELF object file types. Enumerates the ELF object file types specified in the - * System V ABI. Values between [elf_ft_lo_os] and [elf_ft_hi_os] inclusive are - * reserved for operating system specific values typically defined in an - * addendum to the System V ABI for that operating system. Values between - * [elf_ft_lo_proc] and [elf_ft_hi_proc] inclusive are processor specific and - * are typically defined in an addendum to the System V ABI for that processor - * series. - *) - -(** No file type *) -let elf_ft_none : Nat_big_num.num= (Nat_big_num.of_int 0) -(** Relocatable file *) -let elf_ft_rel : Nat_big_num.num= (Nat_big_num.of_int 1) -(** Executable file *) -let elf_ft_exec : Nat_big_num.num= (Nat_big_num.of_int 2) -(** Shared object file *) -let elf_ft_dyn : Nat_big_num.num= (Nat_big_num.of_int 3) -(** Core file *) -let elf_ft_core : Nat_big_num.num= (Nat_big_num.of_int 4) -(** Operating-system specific *) -let elf_ft_lo_os : Nat_big_num.num= (Nat_big_num.of_int 65024) (* 0xfe00 *) -(** Operating-system specific *) -let elf_ft_hi_os : Nat_big_num.num= (Nat_big_num.of_int 65279) (* 0xfeff *) -(** Processor specific *) -let elf_ft_lo_proc : Nat_big_num.num= (Nat_big_num.of_int 65280) (* 0xff00 *) -(** Processor specific *) -let elf_ft_hi_proc : Nat_big_num.num= (Nat_big_num.of_int 65535) (* 0xffff *) - -(** [string_of_elf_file_type os proc m] produces a string representation of the - * numeric encoding [m] of the ELF file type. For values reserved for OS or - * processor specific values, the higher-order functions [os] and [proc] are - * used for printing, respectively. - *) -(*val string_of_elf_file_type : (natural -> string) -> (natural -> string) -> natural -> string*) -let string_of_elf_file_type os_specific proc_specific m:string= - (if Nat_big_num.equal m elf_ft_none then - "No file type" - else if Nat_big_num.equal m elf_ft_rel then - "REL (Relocatable file)" - else if Nat_big_num.equal m elf_ft_exec then - "EXEC (Executable file)" - else if Nat_big_num.equal m elf_ft_dyn then - "DYN (Shared object file)" - else if Nat_big_num.equal m elf_ft_core then - "CORE (Core file)" - else if Nat_big_num.greater_equal m elf_ft_lo_os && Nat_big_num.less_equal m elf_ft_hi_os then - os_specific m - else if Nat_big_num.greater_equal m elf_ft_lo_proc && Nat_big_num.less_equal m elf_ft_hi_proc then - proc_specific m - else - "Invalid file type") - -(** [is_operating_specific_file_type_value] checks whether a numeric value is - * reserved by the ABI for operating system-specific purposes. - *) -(*val is_operating_system_specific_object_file_type_value : natural -> bool*) -let is_operating_system_specific_object_file_type_value v:bool= (Nat_big_num.greater_equal - v(Nat_big_num.of_int 65024) && Nat_big_num.less_equal v(Nat_big_num.of_int 65279)) - -(** [is_processor_specific_file_type_value] checks whether a numeric value is - * reserved by the ABI for processor-specific purposes. - *) -(*val is_processor_specific_object_file_type_value : natural -> bool*) -let is_processor_specific_object_file_type_value v:bool= (Nat_big_num.greater_equal - v(Nat_big_num.of_int 65280) && Nat_big_num.less_equal v(Nat_big_num.of_int 65535)) - -(** ELF machine architectures *) - -(** RISC-V *) -let elf_ma_riscv : Nat_big_num.num= (Nat_big_num.of_int 243) -(** AMD GPU architecture *) -let elf_ma_amdgpu : Nat_big_num.num= (Nat_big_num.of_int 224) -(** Moxie processor family *) -let elf_ma_moxie : Nat_big_num.num= (Nat_big_num.of_int 223) -(** FTDI Chip FT32 high performance 32-bit RISC architecture *) -let elf_ma_ft32 : Nat_big_num.num= (Nat_big_num.of_int 222) -(** Controls and Data Services VISIUMcore processor *) -let elf_ma_visium : Nat_big_num.num= (Nat_big_num.of_int 221) -(** Zilog Z80 *) -let elf_ma_z80 : Nat_big_num.num= (Nat_big_num.of_int 220) -(** CSR Kalimba architecture family *) -let elf_ma_kalimba : Nat_big_num.num= (Nat_big_num.of_int 219) -(** Nanoradio optimised RISC *) -let elf_ma_norc : Nat_big_num.num= (Nat_big_num.of_int 218) -(** iCelero CoolEngine *) -let elf_ma_cool : Nat_big_num.num= (Nat_big_num.of_int 217) -(** Cognitive Smart Memory Processor *) -let elf_ma_coge : Nat_big_num.num= (Nat_big_num.of_int 216) -(** Paneve CDP architecture family *) -let elf_ma_cdp : Nat_big_num.num= (Nat_big_num.of_int 215) -(** KM211 KVARC processor *) -let elf_ma_kvarc : Nat_big_num.num= (Nat_big_num.of_int 214) -(** KM211 KMX8 8-bit processor *) -let elf_ma_kmx8 : Nat_big_num.num= (Nat_big_num.of_int 213) -(** KM211 KMX16 16-bit processor *) -let elf_ma_kmx16 : Nat_big_num.num= (Nat_big_num.of_int 212) -(** KM211 KMX32 32-bit processor *) -let elf_ma_kmx32 : Nat_big_num.num= (Nat_big_num.of_int 211) -(** KM211 KM32 32-bit processor *) -let elf_ma_km32 : Nat_big_num.num= (Nat_big_num.of_int 210) -(** Microchip 8-bit PIC(r) family *) -let elf_ma_mchp_pic : Nat_big_num.num= (Nat_big_num.of_int 204) -(** XMOS xCORE processor family *) -let elf_ma_xcore : Nat_big_num.num= (Nat_big_num.of_int 203) -(** Beyond BA2 CPU architecture *) -let elf_ma_ba2 : Nat_big_num.num= (Nat_big_num.of_int 202) -(** Beyond BA1 CPU architecture *) -let elf_ma_ba1 : Nat_big_num.num= (Nat_big_num.of_int 201) -(** Freescale 56800EX Digital Signal Controller (DSC) *) -let elf_ma_5600ex : Nat_big_num.num= (Nat_big_num.of_int 200) -(** 199 Renesas 78KOR family *) -let elf_ma_78kor : Nat_big_num.num= (Nat_big_num.of_int 199) -(** Broadcom VideoCore V processor *) -let elf_ma_videocore5 : Nat_big_num.num= (Nat_big_num.of_int 198) -(** Renesas RL78 family *) -let elf_ma_rl78 : Nat_big_num.num= (Nat_big_num.of_int 197) -(** Open8 8-bit RISC soft processing core *) -let elf_ma_open8 : Nat_big_num.num= (Nat_big_num.of_int 196) -(** Synopsys ARCompact V2 *) -let elf_ma_arc_compact2 : Nat_big_num.num= (Nat_big_num.of_int 195) -(** KIPO_KAIST Core-A 2nd generation processor family *) -let elf_ma_corea_2nd : Nat_big_num.num= (Nat_big_num.of_int 194) -(** KIPO_KAIST Core-A 1st generation processor family *) -let elf_ma_corea_1st : Nat_big_num.num= (Nat_big_num.of_int 193) -(** CloudShield architecture family *) -let elf_ma_cloudshield : Nat_big_num.num= (Nat_big_num.of_int 192) -(** Infineon Technologies SLE9X core *) -let elf_ma_sle9x : Nat_big_num.num= (Nat_big_num.of_int 179) -(** Intel L10M *) -let elf_ma_l10m : Nat_big_num.num= (Nat_big_num.of_int 180) -(** Intel K10M *) -let elf_ma_k10m : Nat_big_num.num= (Nat_big_num.of_int 181) -(** ARM 64-bit architecture (AARCH64) *) -let elf_ma_aarch64 : Nat_big_num.num= (Nat_big_num.of_int 183) -(** Atmel Corporation 32-bit microprocessor family *) -let elf_ma_avr32 : Nat_big_num.num= (Nat_big_num.of_int 185) -(** STMicroelectronics STM8 8-bit microcontroller *) -let elf_ma_stm8 : Nat_big_num.num= (Nat_big_num.of_int 186) -(** Tilera TILE64 multicore architecture family *) -let elf_ma_tile64 : Nat_big_num.num= (Nat_big_num.of_int 187) -(** Tilera TILEPro multicore architecture family *) -let elf_ma_tilepro : Nat_big_num.num= (Nat_big_num.of_int 188) -(** Xilinix MicroBlaze 32-bit RISC soft processor core *) -let elf_ma_microblaze : Nat_big_num.num= (Nat_big_num.of_int 189) -(** NVIDIA CUDA architecture *) -let elf_ma_cuda : Nat_big_num.num= (Nat_big_num.of_int 190) -(** Tilera TILE-Gx multicore architecture family *) -let elf_ma_tilegx : Nat_big_num.num= (Nat_big_num.of_int 191) -(** Cypress M8C microprocessor *) -let elf_ma_cypress : Nat_big_num.num= (Nat_big_num.of_int 161) -(** Renesas R32C series microprocessors *) -let elf_ma_r32c : Nat_big_num.num= (Nat_big_num.of_int 162) -(** NXP Semiconductors TriMedia architecture family *) -let elf_ma_trimedia : Nat_big_num.num= (Nat_big_num.of_int 163) -(** QUALCOMM DSP6 processor *) -let elf_ma_qdsp6 : Nat_big_num.num= (Nat_big_num.of_int 164) -(** Intel 8051 and variants *) -let elf_ma_8051 : Nat_big_num.num= (Nat_big_num.of_int 165) -(** STMicroelectronics STxP7x family of configurable and extensible RISC processors *) -let elf_ma_stxp7x : Nat_big_num.num= (Nat_big_num.of_int 166) -(** Andes Technology compact code size embedded RISC processor family *) -let elf_ma_nds32 : Nat_big_num.num= (Nat_big_num.of_int 167) -(** Cyan Technology eCOG1X family *) -let elf_ma_ecog1x : Nat_big_num.num= (Nat_big_num.of_int 168) -(** Dallas Semiconductor MAXQ30 Core Micro-controllers *) -let elf_ma_maxq30 : Nat_big_num.num= (Nat_big_num.of_int 169) -(** New Japan Radio (NJR) 16-bit DSP Processor *) -let elf_ma_ximo16 : Nat_big_num.num= (Nat_big_num.of_int 170) -(** M2000 Reconfigurable RISC Microprocessor *) -let elf_ma_manik : Nat_big_num.num= (Nat_big_num.of_int 171) -(** Cray Inc. NV2 vector architecture *) -let elf_ma_craynv2 : Nat_big_num.num= (Nat_big_num.of_int 172) -(** Renesas RX family *) -let elf_ma_rx : Nat_big_num.num= (Nat_big_num.of_int 173) -(** Imagination Technologies META processor architecture *) -let elf_ma_metag : Nat_big_num.num= (Nat_big_num.of_int 174) -(** MCST Elbrus general purpose hardware architecture *) -let elf_ma_mcst_elbrus : Nat_big_num.num= (Nat_big_num.of_int 175) -(** Cyan Technology eCOG16 family *) -let elf_ma_ecog16 : Nat_big_num.num= (Nat_big_num.of_int 176) -(** National Semiconductor CompactRISC CR16 16-bit microprocessor *) -let elf_ma_cr16 : Nat_big_num.num= (Nat_big_num.of_int 177) -(** Freescale Extended Time Processing Unit *) -let elf_ma_etpu : Nat_big_num.num= (Nat_big_num.of_int 178) -(** Altium TSK3000 core *) -let elf_ma_tsk3000 : Nat_big_num.num= (Nat_big_num.of_int 131) -(** Freescale RS08 embedded processor *) -let elf_ma_rs08 : Nat_big_num.num= (Nat_big_num.of_int 132) -(** Analog Devices SHARC family of 32-bit DSP processors *) -let elf_ma_sharc : Nat_big_num.num= (Nat_big_num.of_int 133) -(** Cyan Technology eCOG2 microprocessor *) -let elf_ma_ecog2 : Nat_big_num.num= (Nat_big_num.of_int 134) -(** Sunplus S+core7 RISC processor *) -let elf_ma_ccore7 : Nat_big_num.num= (Nat_big_num.of_int 135) -(** New Japan Radio (NJR) 24-bit DSP Processor *) -let elf_ma_dsp24 : Nat_big_num.num= (Nat_big_num.of_int 136) -(** Broadcom VideoCore III processor *) -let elf_ma_videocore3 : Nat_big_num.num= (Nat_big_num.of_int 137) -(** RISC processor for Lattice FPGA architecture *) -let elf_ma_latticemico32 : Nat_big_num.num= (Nat_big_num.of_int 138) -(** Seiko Epson C17 family *) -let elf_ma_c17 : Nat_big_num.num= (Nat_big_num.of_int 139) -(** The Texas Instruments TMS320C6000 DSP family *) -let elf_ma_c6000 : Nat_big_num.num= (Nat_big_num.of_int 140) -(** The Texas Instruments TMS320C2000 DSP family *) -let elf_ma_c2000 : Nat_big_num.num= (Nat_big_num.of_int 141) -(** The Texas Instruments TMS320C55x DSP family *) -let elf_ma_c5500 : Nat_big_num.num= (Nat_big_num.of_int 142) -(** STMicroelectronics 64bit VLIW Data Signal Processor *) -let elf_ma_mmdsp_plus : Nat_big_num.num= (Nat_big_num.of_int 160) -(** LSI Logic 16-bit DSP Processor *) -let elf_ma_zsp : Nat_big_num.num= (Nat_big_num.of_int 79) -(** Donald Knuth's educational 64-bit processor *) -let elf_ma_mmix : Nat_big_num.num= (Nat_big_num.of_int 80) -(** Harvard University machine-independent object files *) -let elf_ma_huany : Nat_big_num.num= (Nat_big_num.of_int 81) -(** SiTera Prism *) -let elf_ma_prism : Nat_big_num.num= (Nat_big_num.of_int 82) -(** Atmel AVR 8-bit microcontroller *) -let elf_ma_avr : Nat_big_num.num= (Nat_big_num.of_int 83) -(** Fujitsu FR30 *) -let elf_ma_fr30 : Nat_big_num.num= (Nat_big_num.of_int 84) -(** Mitsubishi D10V *) -let elf_ma_d10v : Nat_big_num.num= (Nat_big_num.of_int 85) -(** Mitsubishi D30V *) -let elf_ma_d30v : Nat_big_num.num= (Nat_big_num.of_int 86) -(** NEC v850 *) -let elf_ma_v850 : Nat_big_num.num= (Nat_big_num.of_int 87) -(** Mitsubishi M32R *) -let elf_ma_m32r : Nat_big_num.num= (Nat_big_num.of_int 88) -(** Matsushita MN10300 *) -let elf_ma_mn10300 : Nat_big_num.num= (Nat_big_num.of_int 89) -(** Matsushita MN10200 *) -let elf_ma_mn10200 : Nat_big_num.num= (Nat_big_num.of_int 90) -(** picoJava *) -let elf_ma_pj : Nat_big_num.num= (Nat_big_num.of_int 91) -(** OpenRISC 32-bit embedded processor *) -let elf_ma_openrisc : Nat_big_num.num= (Nat_big_num.of_int 92) -(** ARC International ARCompact processor (old spelling/synonym: ELF_MA_ARC_A5) *) -let elf_ma_arc_compact : Nat_big_num.num= (Nat_big_num.of_int 93) -(** Tensilica Xtensa Architecture *) -let elf_ma_xtensa : Nat_big_num.num= (Nat_big_num.of_int 94) -(** Alphamosaic VideoCore processor *) -let elf_ma_videocore : Nat_big_num.num= (Nat_big_num.of_int 95) -(** Thompson Multimedia General Purpose Processor *) -let elf_ma_tmm_gpp : Nat_big_num.num= (Nat_big_num.of_int 96) -(** National Semiconductor 32000 series *) -let elf_ma_ns32k : Nat_big_num.num= (Nat_big_num.of_int 97) -(** Tenor Network TPC processor *) -let elf_ma_tpc : Nat_big_num.num= (Nat_big_num.of_int 98) -(** Trebia SNP 1000 processor *) -let elf_ma_snp1k : Nat_big_num.num= (Nat_big_num.of_int 99) -(** STMicroelectronics ST200 microcontroller *) -let elf_ma_st200 : Nat_big_num.num= (Nat_big_num.of_int 100) -(** Ubicom IP2xxx microcontroller family *) -let elf_ma_ip2k : Nat_big_num.num= (Nat_big_num.of_int 101) -(** MAX Processor *) -let elf_ma_max : Nat_big_num.num= (Nat_big_num.of_int 102) -(** National Semiconductor CompactRISC microprocessor *) -let elf_ma_cr : Nat_big_num.num= (Nat_big_num.of_int 103) -(** Fujitsu F2MC16 *) -let elf_ma_f2mc16 : Nat_big_num.num= (Nat_big_num.of_int 104) -(** Texas Instruments embedded microcontroller msp430 *) -let elf_ma_msp430 : Nat_big_num.num= (Nat_big_num.of_int 105) -(** Analog Devices Blackfin (DSP) processor *) -let elf_ma_blackfin : Nat_big_num.num= (Nat_big_num.of_int 106) -(** S1C33 Family of Seiko Epson processors *) -let elf_ma_se_c33 : Nat_big_num.num= (Nat_big_num.of_int 107) -(** Sharp embedded microprocessor *) -let elf_ma_sep : Nat_big_num.num= (Nat_big_num.of_int 108) -(** Arca RISC Microprocessor *) -let elf_ma_arca : Nat_big_num.num= (Nat_big_num.of_int 109) -(** Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University *) -let elf_ma_unicore : Nat_big_num.num= (Nat_big_num.of_int 110) -(** eXcess: 16/32/64-bit configurable embedded CPU *) -let elf_ma_excess : Nat_big_num.num= (Nat_big_num.of_int 111) -(** Icera Semiconductor Inc. Deep Execution Processor *) -let elf_ma_dxp : Nat_big_num.num= (Nat_big_num.of_int 112) -(** Altera Nios II soft-core processor *) -let elf_ma_altera_nios2 : Nat_big_num.num= (Nat_big_num.of_int 113) -(** National Semiconductor CompactRISC CRX microprocessor *) -let elf_ma_crx : Nat_big_num.num= (Nat_big_num.of_int 114) -(** Motorola XGATE embedded processor *) -let elf_ma_xgate : Nat_big_num.num= (Nat_big_num.of_int 115) -(** Infineon C16x/XC16x processor *) -let elf_ma_c166 : Nat_big_num.num= (Nat_big_num.of_int 116) -(** Renesas M16C series microprocessors *) -let elf_ma_m16c : Nat_big_num.num= (Nat_big_num.of_int 117) -(** Microchip Technology dsPIC30F Digital Signal Controller *) -let elf_ma_dspic30f : Nat_big_num.num= (Nat_big_num.of_int 118) -(** Freescale Communication Engine RISC core *) -let elf_ma_ce : Nat_big_num.num= (Nat_big_num.of_int 119) -(** Renesas M32C series microprocessors *) -let elf_ma_m32c : Nat_big_num.num= (Nat_big_num.of_int 120) -(** No machine *) -let elf_ma_none : Nat_big_num.num= (Nat_big_num.of_int 0) -(** AT&T WE 32100 *) -let elf_ma_m32 : Nat_big_num.num= (Nat_big_num.of_int 1) -(** SPARC *) -let elf_ma_sparc : Nat_big_num.num= (Nat_big_num.of_int 2) -(** Intel 80386 *) -let elf_ma_386 : Nat_big_num.num= (Nat_big_num.of_int 3) -(** Motorola 68000 *) -let elf_ma_68k : Nat_big_num.num= (Nat_big_num.of_int 4) -(** Motorola 88000 *) -let elf_ma_88k : Nat_big_num.num= (Nat_big_num.of_int 5) -(** Intel 80860 *) -let elf_ma_860 : Nat_big_num.num= (Nat_big_num.of_int 7) -(** MIPS I Architecture *) -let elf_ma_mips : Nat_big_num.num= (Nat_big_num.of_int 8) -(** IBM System/370 Processor *) -let elf_ma_s370 : Nat_big_num.num= (Nat_big_num.of_int 9) -(** MIPS RS3000 Little-endian *) -let elf_ma_mips_rs3_le : Nat_big_num.num= (Nat_big_num.of_int 10) -(** Hewlett-Packard PA-RISC *) -let elf_ma_parisc : Nat_big_num.num= (Nat_big_num.of_int 15) -(** Fujitsu VPP500 *) -let elf_ma_vpp500 : Nat_big_num.num= (Nat_big_num.of_int 17) -(** Enhanced instruction set SPARC *) -let elf_ma_sparc32plus : Nat_big_num.num= (Nat_big_num.of_int 18) -(** Intel 80960 *) -let elf_ma_960 : Nat_big_num.num= (Nat_big_num.of_int 19) -(** PowerPC *) -let elf_ma_ppc : Nat_big_num.num= (Nat_big_num.of_int 20) -(** 64-bit PowerPC *) -let elf_ma_ppc64 : Nat_big_num.num= (Nat_big_num.of_int 21) -(** IBM System/390 Processor *) -let elf_ma_s390 : Nat_big_num.num= (Nat_big_num.of_int 22) -(** IBM SPU/SPC *) -let elf_ma_spu : Nat_big_num.num= (Nat_big_num.of_int 23) -(** NEC V800 *) -let elf_ma_v800 : Nat_big_num.num= (Nat_big_num.of_int 36) -(** Fujitsu FR20 *) -let elf_ma_fr20 : Nat_big_num.num= (Nat_big_num.of_int 37) -(** TRW RH-32 *) -let elf_ma_rh32 : Nat_big_num.num= (Nat_big_num.of_int 38) -(** Motorola RCE *) -let elf_ma_rce : Nat_big_num.num= (Nat_big_num.of_int 39) -(** ARM 32-bit architecture (AARCH32) *) -let elf_ma_arm : Nat_big_num.num= (Nat_big_num.of_int 40) -(** Digital Alpha *) -let elf_ma_alpha : Nat_big_num.num= (Nat_big_num.of_int 41) -(** Hitachi SH *) -let elf_ma_sh : Nat_big_num.num= (Nat_big_num.of_int 42) -(** SPARC Version 9 *) -let elf_ma_sparcv9 : Nat_big_num.num= (Nat_big_num.of_int 43) -(** Siemens TriCore embedded processor *) -let elf_ma_tricore : Nat_big_num.num= (Nat_big_num.of_int 44) -(** Argonaut RISC Core, Argonaut Technologies Inc. *) -let elf_ma_arc : Nat_big_num.num= (Nat_big_num.of_int 45) -(** Hitachi H8/300 *) -let elf_ma_h8_300 : Nat_big_num.num= (Nat_big_num.of_int 46) -(** Hitachi H8/300H *) -let elf_ma_h8_300h : Nat_big_num.num= (Nat_big_num.of_int 47) -(** Hitachi H8S *) -let elf_ma_h8s : Nat_big_num.num= (Nat_big_num.of_int 48) -(** Hitachi H8/500 *) -let elf_ma_h8_500 : Nat_big_num.num= (Nat_big_num.of_int 49) -(** Intel IA-64 processor architecture *) -let elf_ma_ia_64 : Nat_big_num.num= (Nat_big_num.of_int 50) -(** Stanford MIPS-X *) -let elf_ma_mips_x : Nat_big_num.num= (Nat_big_num.of_int 51) -(** Motorola ColdFire *) -let elf_ma_coldfire : Nat_big_num.num= (Nat_big_num.of_int 52) -(** Motorola M68HC12 *) -let elf_ma_68hc12 : Nat_big_num.num= (Nat_big_num.of_int 53) -(** Fujitsu MMA Multimedia Accelerator *) -let elf_ma_mma : Nat_big_num.num= (Nat_big_num.of_int 54) -(** Siemens PCP *) -let elf_ma_pcp : Nat_big_num.num= (Nat_big_num.of_int 55) -(** Sony nCPU embedded RISC processor *) -let elf_ma_ncpu : Nat_big_num.num= (Nat_big_num.of_int 56) -(** Denso NDR1 microprocessor *) -let elf_ma_ndr1 : Nat_big_num.num= (Nat_big_num.of_int 57) -(** Motorola Star*Core processor *) -let elf_ma_starcore : Nat_big_num.num= (Nat_big_num.of_int 58) -(** Toyota ME16 processor *) -let elf_ma_me16 : Nat_big_num.num= (Nat_big_num.of_int 59) -(** STMicroelectronics ST100 processor *) -let elf_ma_st100 : Nat_big_num.num= (Nat_big_num.of_int 60) -(** Advanced Logic Corp. TinyJ embedded processor family *) -let elf_ma_tinyj : Nat_big_num.num= (Nat_big_num.of_int 61) -(** AMD x86-64 architecture *) -let elf_ma_x86_64 : Nat_big_num.num= (Nat_big_num.of_int 62) -(** Sony DSP Processor *) -let elf_ma_pdsp : Nat_big_num.num= (Nat_big_num.of_int 63) -(** Digital Equipment Corp. PDP-10 *) -let elf_ma_pdp10 : Nat_big_num.num= (Nat_big_num.of_int 64) -(** Digital Equipment Corp. PDP-11 *) -let elf_ma_pdp11 : Nat_big_num.num= (Nat_big_num.of_int 65) -(** Siemens FX66 microcontroller *) -let elf_ma_fx66 : Nat_big_num.num= (Nat_big_num.of_int 66) -(** STMicroelectronics ST9+ 8/16 bit microcontroller *) -let elf_ma_st9plus : Nat_big_num.num= (Nat_big_num.of_int 67) -(** STMicroelectronics ST7 8-bit microcontroller *) -let elf_ma_st7 : Nat_big_num.num= (Nat_big_num.of_int 68) -(** Motorola MC68HC16 Microcontroller *) -let elf_ma_68hc16 : Nat_big_num.num= (Nat_big_num.of_int 69) -(** Motorola MC68HC11 Microcontroller *) -let elf_ma_68hc11 : Nat_big_num.num= (Nat_big_num.of_int 70) -(** Motorola MC68HC08 Microcontroller *) -let elf_ma_68hc08 : Nat_big_num.num= (Nat_big_num.of_int 71) -(** Motorola MC68HC05 Microcontroller *) -let elf_ma_68hc05 : Nat_big_num.num= (Nat_big_num.of_int 72) -(** Silicon Graphics SVx *) -let elf_ma_svx : Nat_big_num.num= (Nat_big_num.of_int 73) -(** STMicroelectronics ST19 8-bit microcontroller *) -let elf_ma_st19 : Nat_big_num.num= (Nat_big_num.of_int 74) -(** Digital VAX *) -let elf_ma_vax : Nat_big_num.num= (Nat_big_num.of_int 75) -(** Axis Communications 32-bit embedded processor *) -let elf_ma_cris : Nat_big_num.num= (Nat_big_num.of_int 76) -(** Infineon Technologies 32-bit embedded processor *) -let elf_ma_javelin : Nat_big_num.num= (Nat_big_num.of_int 77) -(** Element 14 64-bit DSP Processor *) -let elf_ma_firepath : Nat_big_num.num= (Nat_big_num.of_int 78) -(** Reserved by Intel *) -let elf_ma_intel209 : Nat_big_num.num= (Nat_big_num.of_int 209) -(** Reserved by Intel *) -let elf_ma_intel208 : Nat_big_num.num= (Nat_big_num.of_int 208) -(** Reserved by Intel *) -let elf_ma_intel207 : Nat_big_num.num= (Nat_big_num.of_int 207) -(** Reserved by Intel *) -let elf_ma_intel206 : Nat_big_num.num= (Nat_big_num.of_int 206) -(** Reserved by Intel *) -let elf_ma_intel205 : Nat_big_num.num= (Nat_big_num.of_int 205) -(** Reserved by Intel *) -let elf_ma_intel182 : Nat_big_num.num= (Nat_big_num.of_int 182) -(** Reserved by ARM *) -let elf_ma_arm184 : Nat_big_num.num= (Nat_big_num.of_int 184) -(** Reserved for future use *) -let elf_ma_reserved6 : Nat_big_num.num= (Nat_big_num.of_int 6) -(** Reserved for future use *) -let elf_ma_reserved11 : Nat_big_num.num= (Nat_big_num.of_int 11) -(** Reserved for future use *) -let elf_ma_reserved12 : Nat_big_num.num= (Nat_big_num.of_int 12) -(** Reserved for future use *) -let elf_ma_reserved13 : Nat_big_num.num= (Nat_big_num.of_int 13) -(** Reserved for future use *) -let elf_ma_reserved14 : Nat_big_num.num= (Nat_big_num.of_int 14) -(** Reserved for future use *) -let elf_ma_reserved16 : Nat_big_num.num= (Nat_big_num.of_int 16) -(** Reserved for future use *) -let elf_ma_reserved24 : Nat_big_num.num= (Nat_big_num.of_int 24) -(** Reserved for future use *) -let elf_ma_reserved25 : Nat_big_num.num= (Nat_big_num.of_int 25) -(** Reserved for future use *) -let elf_ma_reserved26 : Nat_big_num.num= (Nat_big_num.of_int 26) -(** Reserved for future use *) -let elf_ma_reserved27 : Nat_big_num.num= (Nat_big_num.of_int 27) -(** Reserved for future use *) -let elf_ma_reserved28 : Nat_big_num.num= (Nat_big_num.of_int 28) -(** Reserved for future use *) -let elf_ma_reserved29 : Nat_big_num.num= (Nat_big_num.of_int 29) -(** Reserved for future use *) -let elf_ma_reserved30 : Nat_big_num.num= (Nat_big_num.of_int 30) -(** Reserved for future use *) -let elf_ma_reserved31 : Nat_big_num.num= (Nat_big_num.of_int 31) -(** Reserved for future use *) -let elf_ma_reserved32 : Nat_big_num.num= (Nat_big_num.of_int 32) -(** Reserved for future use *) -let elf_ma_reserved33 : Nat_big_num.num= (Nat_big_num.of_int 33) -(** Reserved for future use *) -let elf_ma_reserved34 : Nat_big_num.num= (Nat_big_num.of_int 34) -(** Reserved for future use *) -let elf_ma_reserved35 : Nat_big_num.num= (Nat_big_num.of_int 35) -(** Reserved for future use *) -let elf_ma_reserved121 : Nat_big_num.num= (Nat_big_num.of_int 121) -(** Reserved for future use *) -let elf_ma_reserved122 : Nat_big_num.num= (Nat_big_num.of_int 122) -(** Reserved for future use *) -let elf_ma_reserved123 : Nat_big_num.num= (Nat_big_num.of_int 123) -(** Reserved for future use *) -let elf_ma_reserved124 : Nat_big_num.num= (Nat_big_num.of_int 124) -(** Reserved for future use *) -let elf_ma_reserved125 : Nat_big_num.num= (Nat_big_num.of_int 125) -(** Reserved for future use *) -let elf_ma_reserved126 : Nat_big_num.num= (Nat_big_num.of_int 126) -(** Reserved for future use *) -let elf_ma_reserved127 : Nat_big_num.num= (Nat_big_num.of_int 127) -(** Reserved for future use *) -let elf_ma_reserved128 : Nat_big_num.num= (Nat_big_num.of_int 128) -(** Reserved for future use *) -let elf_ma_reserved129 : Nat_big_num.num= (Nat_big_num.of_int 129) -(** Reserved for future use *) -let elf_ma_reserved130 : Nat_big_num.num= (Nat_big_num.of_int 130) -(** Reserved for future use *) -let elf_ma_reserved143 : Nat_big_num.num= (Nat_big_num.of_int 143) -(** Reserved for future use *) -let elf_ma_reserved144 : Nat_big_num.num= (Nat_big_num.of_int 144) -(** Reserved for future use *) -let elf_ma_reserved145 : Nat_big_num.num= (Nat_big_num.of_int 145) -(** Reserved for future use *) -let elf_ma_reserved146 : Nat_big_num.num= (Nat_big_num.of_int 146) -(** Reserved for future use *) -let elf_ma_reserved147 : Nat_big_num.num= (Nat_big_num.of_int 147) -(** Reserved for future use *) -let elf_ma_reserved148 : Nat_big_num.num= (Nat_big_num.of_int 148) -(** Reserved for future use *) -let elf_ma_reserved149 : Nat_big_num.num= (Nat_big_num.of_int 149) -(** Reserved for future use *) -let elf_ma_reserved150 : Nat_big_num.num= (Nat_big_num.of_int 150) -(** Reserved for future use *) -let elf_ma_reserved151 : Nat_big_num.num= (Nat_big_num.of_int 151) -(** Reserved for future use *) -let elf_ma_reserved152 : Nat_big_num.num= (Nat_big_num.of_int 152) -(** Reserved for future use *) -let elf_ma_reserved153 : Nat_big_num.num= (Nat_big_num.of_int 153) -(** Reserved for future use *) -let elf_ma_reserved154 : Nat_big_num.num= (Nat_big_num.of_int 154) -(** Reserved for future use *) -let elf_ma_reserved155 : Nat_big_num.num= (Nat_big_num.of_int 155) -(** Reserved for future use *) -let elf_ma_reserved156 : Nat_big_num.num= (Nat_big_num.of_int 156) -(** Reserved for future use *) -let elf_ma_reserved157 : Nat_big_num.num= (Nat_big_num.of_int 157) -(** Reserved for future use *) -let elf_ma_reserved158 : Nat_big_num.num= (Nat_big_num.of_int 158) -(** Reserved for future use *) -let elf_ma_reserved159 : Nat_big_num.num= (Nat_big_num.of_int 159) - -(** [string_of_elf_machine_architecture m] produces a string representation of - * the numeric encoding [m] of the ELF machine architecture. - * TODO: finish this . - *) -(*val string_of_elf_machine_architecture : natural -> string*) -let string_of_elf_machine_architecture m:string= - (if Nat_big_num.equal m elf_ma_386 then - "Intel 80386" - else if Nat_big_num.equal m elf_ma_ppc then - "PowerPC" - else if Nat_big_num.equal m elf_ma_ppc64 then - "PowerPC64" - else if Nat_big_num.equal m elf_ma_arm then - "AArch" - else if Nat_big_num.equal m elf_ma_x86_64 then - "Advanced Micro Devices X86-64" - else if Nat_big_num.equal m elf_ma_aarch64 then - "AArch64" - else - "Other architecture") - -(** ELF version numbers. Denotes the ELF version number of an ELF file. Current is - * defined to have a value of 1 with the present specification. Extensions - * may create versions of ELF with higher version numbers. - *) - -(** Invalid version *) -let elf_ev_none : Nat_big_num.num= (Nat_big_num.of_int 0) -(** Current version *) -let elf_ev_current : Nat_big_num.num= (Nat_big_num.of_int 1) - -(** [string_of_elf_version_number m] produces a string representation of the - * numeric encoding [m] of the ELF version number. - *) -(*val string_of_elf_version_number : natural -> string*) -let string_of_elf_version_number m:string= - (if Nat_big_num.equal m elf_ev_none then - "Invalid ELF version" - else if Nat_big_num.equal m elf_ev_current then - "1 (current)" - else - "Extended ELF version") - -(** Check that an extended version number is correct (i.e. greater than 1). *) -let is_valid_extended_version_number (n : Nat_big_num.num):bool= (Nat_big_num.greater n(Nat_big_num.of_int 1)) - -(** Identification indices. The initial bytes of an ELF header (and an object - * file) correspond to the e_ident member. - *) - -(** File identification *) -let elf_ii_mag0 : Nat_big_num.num= (Nat_big_num.of_int 0) -(** File identification *) -let elf_ii_mag1 : Nat_big_num.num= (Nat_big_num.of_int 1) -(** File identification *) -let elf_ii_mag2 : Nat_big_num.num= (Nat_big_num.of_int 2) -(** File identification *) -let elf_ii_mag3 : Nat_big_num.num= (Nat_big_num.of_int 3) -(** File class *) -let elf_ii_class : Nat_big_num.num= (Nat_big_num.of_int 4) -(** Data encoding *) -let elf_ii_data : Nat_big_num.num= (Nat_big_num.of_int 5) -(** File version *) -let elf_ii_version : Nat_big_num.num= (Nat_big_num.of_int 6) -(** Operating system/ABI identification *) -let elf_ii_osabi : Nat_big_num.num= (Nat_big_num.of_int 7) -(** ABI version *) -let elf_ii_abiversion : Nat_big_num.num= (Nat_big_num.of_int 8) -(** Start of padding bytes *) -let elf_ii_pad : Nat_big_num.num= (Nat_big_num.of_int 9) -(** Size of e*_ident[] *) -let elf_ii_nident : Nat_big_num.num= (Nat_big_num.of_int 16) - -(** Magic number indices. A file's first 4 bytes hold a ``magic number,'' - * identifying the file as an ELF object file. - *) - -(** Position: e*_ident[elf_ii_mag0], 0x7f magic number *) -let elf_mn_mag0 : Uint32.uint32= (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 127))) -(** Position: e*_ident[elf_ii_mag1], 'E' format identifier *) -let elf_mn_mag1 : Uint32.uint32= (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 69))) -(** Position: e*_ident[elf_ii_mag2], 'L' format identifier *) -let elf_mn_mag2 : Uint32.uint32= (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 76))) -(** Position: e*_ident[elf_ii_mag3], 'F' format identifier *) -let elf_mn_mag3 : Uint32.uint32= (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 70))) - -(** ELf file classes. The file format is designed to be portable among machines - * of various sizes, without imposing the sizes of the largest machine on the - * smallest. The class of the file defines the basic types used by the data - * structures of the object file container itself. - *) - -(** Invalid class *) -let elf_class_none : Nat_big_num.num= (Nat_big_num.of_int 0) -(** 32 bit objects *) -let elf_class_32 : Nat_big_num.num= (Nat_big_num.of_int 1) -(** 64 bit objects *) -let elf_class_64 : Nat_big_num.num= (Nat_big_num.of_int 2) - -(** [string_of_elf_file_class m] produces a string representation of the numeric - * encoding [m] of the ELF file class. - *) -(*val string_of_elf_file_class : natural -> string*) -let string_of_elf_file_class m:string= - (if Nat_big_num.equal m elf_class_none then - "Invalid ELF file class" - else if Nat_big_num.equal m elf_class_32 then - "ELF32" - else if Nat_big_num.equal m elf_class_64 then - "ELF64" - else - "Invalid ELF file class") - -(** ELF data encodings. Byte e_ident[elf_ei_data] specifies the encoding of both the - * data structures used by object file container and data contained in object - * file sections. - *) - -(** Invalid data encoding *) -let elf_data_none : Nat_big_num.num= (Nat_big_num.of_int 0) -(** Two's complement values, least significant byte occupying lowest address *) -let elf_data_2lsb : Nat_big_num.num= (Nat_big_num.of_int 1) -(** Two's complement values, most significant byte occupying lowest address *) -let elf_data_2msb : Nat_big_num.num= (Nat_big_num.of_int 2) - -(** [string_of_elf_data_encoding m] produces a string representation of the - * numeric encoding [m] of the ELF data encoding. - *) -(*val string_of_elf_data_encoding : natural -> string*) -let string_of_elf_data_encoding m:string= - (if Nat_big_num.equal m elf_data_none then - "Invalid data encoding" - else if Nat_big_num.equal m elf_data_2lsb then - "2's complement, little endian" - else if Nat_big_num.equal m elf_data_2msb then - "2's complement, big endian" - else - "Invalid data encoding") - -(** OS and ABI versions. Byte e_ident[elf_ei_osabi] identifies the OS- or - * ABI-specific ELF extensions used by this file. Some fields in other ELF - * structures have flags and values that have operating system and/or ABI - * specific meanings; the interpretation of those fields is determined by the - * value of this byte. - *) - -(** No extensions or unspecified *) -let elf_osabi_none : Nat_big_num.num= (Nat_big_num.of_int 0) -(** Hewlett-Packard HP-UX *) -let elf_osabi_hpux : Nat_big_num.num= (Nat_big_num.of_int 1) -(** NetBSD *) -let elf_osabi_netbsd : Nat_big_num.num= (Nat_big_num.of_int 2) -(** GNU *) -let elf_osabi_gnu : Nat_big_num.num= (Nat_big_num.of_int 3) -(** Linux, historical alias for GNU *) -let elf_osabi_linux : Nat_big_num.num= (Nat_big_num.of_int 3) -(** Sun Solaris *) -let elf_osabi_solaris : Nat_big_num.num= (Nat_big_num.of_int 6) -(** AIX *) -let elf_osabi_aix : Nat_big_num.num= (Nat_big_num.of_int 7) -(** IRIX *) -let elf_osabi_irix : Nat_big_num.num= (Nat_big_num.of_int 8) -(** FreeBSD *) -let elf_osabi_freebsd : Nat_big_num.num= (Nat_big_num.of_int 9) -(** Compaq Tru64 Unix *) -let elf_osabi_tru64 : Nat_big_num.num= (Nat_big_num.of_int 10) -(** Novell Modesto *) -let elf_osabi_modesto : Nat_big_num.num= (Nat_big_num.of_int 11) -(** OpenBSD *) -let elf_osabi_openbsd : Nat_big_num.num= (Nat_big_num.of_int 12) -(** OpenVMS *) -let elf_osabi_openvms : Nat_big_num.num= (Nat_big_num.of_int 13) -(** Hewlett-Packard Non-stop Kernel *) -let elf_osabi_nsk : Nat_big_num.num= (Nat_big_num.of_int 14) -(** Amiga Research OS *) -let elf_osabi_aros : Nat_big_num.num= (Nat_big_num.of_int 15) -(** FenixOS highly-scalable multi-core OS *) -let elf_osabi_fenixos : Nat_big_num.num= (Nat_big_num.of_int 16) -(** Nuxi CloudABI *) -let elf_osabi_cloudabi : Nat_big_num.num= (Nat_big_num.of_int 17) -(** Stratus technologies OpenVOS *) -let elf_osabi_openvos : Nat_big_num.num= (Nat_big_num.of_int 18) - -(** Checks an architecture defined OSABI version is correct, i.e. in the range - * 64 to 255 inclusive. - *) -let is_valid_architecture_defined_osabi_version (n : Nat_big_num.num):bool= (Nat_big_num.greater_equal - n(Nat_big_num.of_int 64) && Nat_big_num.less_equal n(Nat_big_num.of_int 255)) - -(** [string_of_elf_osabi_version m] produces a string representation of the - * numeric encoding [m] of the ELF OSABI version. - *) -(*val string_of_elf_osabi_version : (natural -> string) -> natural -> string*) -let string_of_elf_osabi_version arch m:string= - (if Nat_big_num.equal m elf_osabi_none then - "UNIX - System V" - else if Nat_big_num.equal m elf_osabi_netbsd then - "Hewlett-Packard HP-UX" - else if Nat_big_num.equal m elf_osabi_netbsd then - "NetBSD" - else if Nat_big_num.equal m elf_osabi_gnu then - "UNIX - GNU" - else if Nat_big_num.equal m elf_osabi_linux then - "Linux" - else if Nat_big_num.equal m elf_osabi_solaris then - "Sun Solaris" - else if Nat_big_num.equal m elf_osabi_aix then - "AIX" - else if Nat_big_num.equal m elf_osabi_irix then - "IRIX" - else if Nat_big_num.equal m elf_osabi_freebsd then - "FreeBSD" - else if Nat_big_num.equal m elf_osabi_tru64 then - "Compaq Tru64 Unix" - else if Nat_big_num.equal m elf_osabi_modesto then - "Novell Modesto" - else if Nat_big_num.equal m elf_osabi_openbsd then - "OpenBSD" - else if Nat_big_num.equal m elf_osabi_openvms then - "OpenVMS" - else if Nat_big_num.equal m elf_osabi_nsk then - "Hewlett-Packard Non-stop Kernel" - else if Nat_big_num.equal m elf_osabi_aros then - "Amiga Research OS" - else if Nat_big_num.equal m elf_osabi_fenixos then - "FenixOS highly-scalable multi-core OS" - else if Nat_big_num.equal m elf_osabi_cloudabi then - "Nuxi CloudABI" - else if Nat_big_num.equal m elf_osabi_openvos then - "Stratus technologies OpenVOS" - else if is_valid_architecture_defined_osabi_version m then - arch m - else - "Invalid OSABI version") - -(** ELF Header type *) - -(** [ei_nident] is the fixed length of the identification field in the - * [elf32_ehdr] type. - *) -(*val ei_nident : natural*) -let ei_nident:Nat_big_num.num= (Nat_big_num.of_int 16) - -(** [elf32_header] is the type of headers for 32-bit ELF files. - *) -type elf32_header = - { elf32_ident : Uint32.uint32 list (** Identification field *) - ; elf32_type : Uint32.uint32 (** The object file type *) - ; elf32_machine : Uint32.uint32 (** Required machine architecture *) - ; elf32_version : Uint32.uint32 (** Object file version *) - ; elf32_entry : Uint32.uint32 (** Virtual address for transfer of control *) - ; elf32_phoff : Uint32.uint32 (** Program header table offset in bytes *) - ; elf32_shoff : Uint32.uint32 (** Section header table offset in bytes *) - ; elf32_flags : Uint32.uint32 (** Processor-specific flags *) - ; elf32_ehsize : Uint32.uint32 (** ELF header size in bytes *) - ; elf32_phentsize: Uint32.uint32 (** Program header table entry size in bytes *) - ; elf32_phnum : Uint32.uint32 (** Number of entries in program header table *) - ; elf32_shentsize: Uint32.uint32 (** Section header table entry size in bytes *) - ; elf32_shnum : Uint32.uint32 (** Number of entries in section header table *) - ; elf32_shstrndx : Uint32.uint32 (** Section header table entry for section name string table *) - } - -(** [elf64_header] is the type of headers for 64-bit ELF files. - *) -type elf64_header = - { elf64_ident : Uint32.uint32 list (** Identification field *) - ; elf64_type : Uint32.uint32 (** The object file type *) - ; elf64_machine : Uint32.uint32 (** Required machine architecture *) - ; elf64_version : Uint32.uint32 (** Object file version *) - ; elf64_entry : Uint64.uint64 (** Virtual address for transfer of control *) - ; elf64_phoff : Uint64.uint64 (** Program header table offset in bytes *) - ; elf64_shoff : Uint64.uint64 (** Section header table offset in bytes *) - ; elf64_flags : Uint32.uint32 (** Processor-specific flags *) - ; elf64_ehsize : Uint32.uint32 (** ELF header size in bytes *) - ; elf64_phentsize: Uint32.uint32 (** Program header table entry size in bytes *) - ; elf64_phnum : Uint32.uint32 (** Number of entries in program header table *) - ; elf64_shentsize: Uint32.uint32 (** Section header table entry size in bytes *) - ; elf64_shnum : Uint32.uint32 (** Number of entries in section header table *) - ; elf64_shstrndx : Uint32.uint32 (** Section header table entry for section name string table *) - } - -(** [is_valid_elf32_header hdr] checks whether header [hdr] is valid, i.e. has - * the correct magic numbers. - * TODO: this should be expanded, presumably, or merged with some of the other - * checks. - *) -(*val is_valid_elf32_header : elf32_header -> bool*) -let is_valid_elf32_header hdr:bool= (listEqualBy (=) -(Lem_list.take( 4) hdr.elf32_ident) [elf_mn_mag0; elf_mn_mag1; elf_mn_mag2; elf_mn_mag3]) - -(** [is_valid_elf64_header hdr] checks whether header [hdr] is valid, i.e. has - * the correct magic numbers. - * TODO: this should be expanded, presumably, or merged with some of the other - * checks. - *) -(*val is_valid_elf64_header : elf64_header -> bool*) -let is_valid_elf64_header hdr:bool= (listEqualBy (=) -(Lem_list.take( 4) hdr.elf64_ident) [elf_mn_mag0; elf_mn_mag1; elf_mn_mag2; elf_mn_mag3]) - -(** [elf32_header_compare hdr1 hdr2] is an ordering comparison function for - * ELF headers suitable for use in sets, finite maps and other ordered - * data types. - *) -(*val elf32_header_compare : elf32_header -> elf32_header -> Basic_classes.ordering*) -let elf32_header_compare h1 h2:int= - (pairCompare (lexicographic_compare Nat_big_num.compare) (lexicographic_compare Nat_big_num.compare) (Lem_list.map (fun u->Nat_big_num.of_string (Uint32.to_string u)) h1.elf32_ident, [Nat_big_num.of_string (Uint32.to_string h1.elf32_type); - Nat_big_num.of_string (Uint32.to_string h1.elf32_machine) ; Nat_big_num.of_string (Uint32.to_string h1.elf32_version) ; - Nat_big_num.of_string (Uint32.to_string h1.elf32_entry) ; Nat_big_num.of_string (Uint32.to_string h1.elf32_phoff) ; Nat_big_num.of_string (Uint32.to_string h1.elf32_shoff) ; - Nat_big_num.of_string (Uint32.to_string h1.elf32_flags) ; Nat_big_num.of_string (Uint32.to_string h1.elf32_ehsize) ; - Nat_big_num.of_string (Uint32.to_string h1.elf32_phentsize); Nat_big_num.of_string (Uint32.to_string h1.elf32_phnum) ; - Nat_big_num.of_string (Uint32.to_string h1.elf32_shentsize); Nat_big_num.of_string (Uint32.to_string h1.elf32_shnum) ; - Nat_big_num.of_string (Uint32.to_string h1.elf32_shstrndx)]) - (Lem_list.map (fun u->Nat_big_num.of_string (Uint32.to_string u)) h2.elf32_ident, [Nat_big_num.of_string (Uint32.to_string h2.elf32_type); - Nat_big_num.of_string (Uint32.to_string h2.elf32_machine) ; Nat_big_num.of_string (Uint32.to_string h2.elf32_version) ; - Nat_big_num.of_string (Uint32.to_string h2.elf32_entry) ; Nat_big_num.of_string (Uint32.to_string h2.elf32_phoff) ; Nat_big_num.of_string (Uint32.to_string h2.elf32_shoff) ; - Nat_big_num.of_string (Uint32.to_string h2.elf32_flags) ; Nat_big_num.of_string (Uint32.to_string h2.elf32_ehsize) ; - Nat_big_num.of_string (Uint32.to_string h2.elf32_phentsize); Nat_big_num.of_string (Uint32.to_string h2.elf32_phnum) ; - Nat_big_num.of_string (Uint32.to_string h2.elf32_shentsize); Nat_big_num.of_string (Uint32.to_string h2.elf32_shnum) ; - Nat_big_num.of_string (Uint32.to_string h2.elf32_shstrndx)])) - -let instance_Basic_classes_Ord_Elf_header_elf32_header_dict:(elf32_header)ord_class= ({ - - compare_method = elf32_header_compare; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(elf32_header_compare f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (elf32_header_compare f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(elf32_header_compare f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (elf32_header_compare f1 f2)(Pset.from_list compare [1; 0])))}) - -(** [elf64_header_compare hdr1 hdr2] is an ordering comparison function for - * ELF headers suitable for use in sets, finite maps and other ordered - * data types. - *) -(*val elf64_header_compare : elf64_header -> elf64_header -> Basic_classes.ordering*) -let elf64_header_compare h1 h2:int= - (pairCompare (lexicographic_compare Nat_big_num.compare) (lexicographic_compare Nat_big_num.compare) (Lem_list.map (fun u->Nat_big_num.of_string (Uint32.to_string u)) h1.elf64_ident, [Nat_big_num.of_string (Uint32.to_string h1.elf64_type); - Nat_big_num.of_string (Uint32.to_string h1.elf64_machine) ; Nat_big_num.of_string (Uint32.to_string h1.elf64_version) ; - Ml_bindings.nat_big_num_of_uint64 h1.elf64_entry ; Nat_big_num.of_string (Uint64.to_string h1.elf64_phoff) ; Nat_big_num.of_string (Uint64.to_string h1.elf64_shoff) ; - Nat_big_num.of_string (Uint32.to_string h1.elf64_flags) ; Nat_big_num.of_string (Uint32.to_string h1.elf64_ehsize) ; - Nat_big_num.of_string (Uint32.to_string h1.elf64_phentsize); Nat_big_num.of_string (Uint32.to_string h1.elf64_phnum) ; - Nat_big_num.of_string (Uint32.to_string h1.elf64_shentsize); Nat_big_num.of_string (Uint32.to_string h1.elf64_shnum) ; - Nat_big_num.of_string (Uint32.to_string h1.elf64_shstrndx)]) - (Lem_list.map (fun u->Nat_big_num.of_string (Uint32.to_string u)) h2.elf64_ident, [Nat_big_num.of_string (Uint32.to_string h2.elf64_type); - Nat_big_num.of_string (Uint32.to_string h2.elf64_machine) ; Nat_big_num.of_string (Uint32.to_string h2.elf64_version) ; - Ml_bindings.nat_big_num_of_uint64 h2.elf64_entry ; Nat_big_num.of_string (Uint64.to_string h2.elf64_phoff) ; Nat_big_num.of_string (Uint64.to_string h2.elf64_shoff) ; - Nat_big_num.of_string (Uint32.to_string h2.elf64_flags) ; Nat_big_num.of_string (Uint32.to_string h2.elf64_ehsize) ; - Nat_big_num.of_string (Uint32.to_string h2.elf64_phentsize); Nat_big_num.of_string (Uint32.to_string h2.elf64_phnum) ; - Nat_big_num.of_string (Uint32.to_string h2.elf64_shentsize); Nat_big_num.of_string (Uint32.to_string h2.elf64_shnum) ; - Nat_big_num.of_string (Uint32.to_string h2.elf64_shstrndx)])) - -let instance_Basic_classes_Ord_Elf_header_elf64_header_dict:(elf64_header)ord_class= ({ - - compare_method = elf64_header_compare; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(elf64_header_compare f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (elf64_header_compare f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(elf64_header_compare f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (elf64_header_compare f1 f2)(Pset.from_list compare [1; 0])))}) - -(** [is_elf32_executable_file hdr] checks whether the header [hdr] states if the - * ELF file is of executable type. - *) -(*val is_elf32_executable_file : elf32_header -> bool*) -let is_elf32_executable_file hdr:bool= (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string hdr.elf32_type)) elf_ft_exec) - -(** [is_elf64_executable_file hdr] checks whether the header [hdr] states if the - * ELF file is of executable type. - *) -(*val is_elf64_executable_file : elf64_header -> bool*) -let is_elf64_executable_file hdr:bool= (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string hdr.elf64_type)) elf_ft_exec) - -(** [is_elf32_shared_object_file hdr] checks whether the header [hdr] states if the - * ELF file is of shared object type. - *) -(*val is_elf32_shared_object_file : elf32_header -> bool*) -let is_elf32_shared_object_file hdr:bool= (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string hdr.elf32_type)) elf_ft_dyn) - -(** [is_elf64_shared_object_file hdr] checks whether the header [hdr] states if the - * ELF file is of shared object type. - *) -(*val is_elf64_shared_object_file : elf64_header -> bool*) -let is_elf64_shared_object_file hdr:bool= (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string hdr.elf64_type)) elf_ft_dyn) - -(** [is_elf32_relocatable_file hdr] checks whether the header [hdr] states if the - * ELF file is of relocatable type. - *) -(*val is_elf32_relocatable_file : elf32_header -> bool*) -let is_elf32_relocatable_file hdr:bool= (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string hdr.elf32_type)) elf_ft_rel) - -(** [is_elf64_relocatable_file hdr] checks whether the header [hdr] states if the - * ELF file is of relocatable type. - *) -(*val is_elf64_relocatable_file : elf64_header -> bool*) -let is_elf64_relocatable_file hdr:bool= (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string hdr.elf64_type)) elf_ft_rel) - -(** [is_elf32_linkable_file hdr] checks whether the header [hdr] states if the - * ELF file is of linkable (shared object or relocatable) type. - *) -(*val is_elf32_linkable_file : elf32_header -> bool*) -let is_elf32_linkable_file hdr:bool= - (is_elf32_shared_object_file hdr || is_elf32_relocatable_file hdr) - -(** [is_elf64_linkable_file hdr] checks whether the header [hdr] states if the - * ELF file is of linkable (shared object or relocatable) type. - *) -(*val is_elf64_linkable_file : elf64_header -> bool*) -let is_elf64_linkable_file hdr:bool= - (is_elf64_shared_object_file hdr || is_elf64_relocatable_file hdr) - -(** [get_elf32_machine_architecture hdr] returns the ELF file's declared machine - * architecture, extracting the information from header [hdr]. - *) -(*val get_elf32_machine_architecture : elf32_header -> natural*) -let get_elf32_machine_architecture hdr:Nat_big_num.num= - (Nat_big_num.of_string (Uint32.to_string hdr.elf32_machine)) - -(** [get_elf64_machine_architecture hdr] returns the ELF file's declared machine - * architecture, extracting the information from header [hdr]. - *) -(*val get_elf64_machine_architecture : elf64_header -> natural*) -let get_elf64_machine_architecture hdr:Nat_big_num.num= - (Nat_big_num.of_string (Uint32.to_string hdr.elf64_machine)) - -(** [get_elf32_osabi hdr] returns the ELF file's declared OS/ABI - * architecture, extracting the information from header [hdr]. - *) -(*val get_elf32_osabi : elf32_header -> natural*) -let get_elf32_osabi hdr:Nat_big_num.num= - ((match Lem_list.list_index hdr.elf32_ident (Nat_big_num.to_int elf_ii_osabi) with - | Some osabi -> Nat_big_num.of_string (Uint32.to_string osabi) - | None -> failwith "get_elf32_osabi: lookup in ident failed" - )) (* Partial: should never return Nothing *) - -(** [get_elf64_osabi hdr] returns the ELF file's declared OS/ABI - * architecture, extracting the information from header [hdr]. - *) -(*val get_elf64_osabi : elf64_header -> natural*) -let get_elf64_osabi hdr:Nat_big_num.num= - ((match Lem_list.list_index hdr.elf64_ident (Nat_big_num.to_int elf_ii_osabi) with - | Some osabi -> Nat_big_num.of_string (Uint32.to_string osabi) - | None -> failwith "get_elf64_osabi: lookup in ident failed" - )) (* Partial: should never return Nothing *) - -(** [get_elf32_data_encoding hdr] returns the ELF file's declared data - * encoding, extracting the information from header [hdr]. - *) -(*val get_elf32_data_encoding : elf32_header -> natural*) -let get_elf32_data_encoding hdr:Nat_big_num.num= - ((match Lem_list.list_index hdr.elf32_ident (Nat_big_num.to_int elf_ii_data) with - | Some data -> Nat_big_num.of_string (Uint32.to_string data) - | None -> failwith "get_elf32_data_encoding: lookup in ident failed" - )) (* Partial: should never return Nothing *) - -(** [get_elf64_data_encoding hdr] returns the ELF file's declared data - * encoding, extracting the information from header [hdr]. - *) -(*val get_elf64_data_encoding : elf64_header -> natural*) -let get_elf64_data_encoding hdr:Nat_big_num.num= - ((match Lem_list.list_index hdr.elf64_ident (Nat_big_num.to_int elf_ii_data) with - | Some data -> Nat_big_num.of_string (Uint32.to_string data) - | None -> failwith "get_elf64_data_encoding: lookup in ident failed" - )) (* Partial: should never return Nothing *) - -(** [get_elf32_file_class hdr] returns the ELF file's declared file - * class, extracting the information from header [hdr]. - *) -(*val get_elf32_file_class : elf32_header -> natural*) -let get_elf32_file_class hdr:Nat_big_num.num= - ((match Lem_list.list_index hdr.elf32_ident (Nat_big_num.to_int elf_ii_class) with - | Some cls -> Nat_big_num.of_string (Uint32.to_string cls) - | None -> failwith "get_elf32_file_class: lookup in ident failed" - )) (* Partial: should never return Nothing *) - -(** [get_elf64_file_class hdr] returns the ELF file's declared file - * class, extracting the information from header [hdr]. - *) -(*val get_elf64_file_class : elf64_header -> natural*) -let get_elf64_file_class hdr:Nat_big_num.num= - ((match Lem_list.list_index hdr.elf64_ident (Nat_big_num.to_int elf_ii_class) with - | Some cls -> Nat_big_num.of_string (Uint32.to_string cls) - | None -> failwith "get_elf64_file_class: lookup in ident failed" - )) (* Partial: should never return Nothing *) - -(** [get_elf32_version_number hdr] returns the ELF file's declared version - * number, extracting the information from header [hdr]. - *) -(*val get_elf32_version_number : elf32_header -> natural*) -let get_elf32_version_number hdr:Nat_big_num.num= - ((match Lem_list.list_index hdr.elf32_ident (Nat_big_num.to_int elf_ii_version) with - | Some ver -> Nat_big_num.of_string (Uint32.to_string ver) - | None -> failwith "get_elf32_version_number: lookup in ident failed" - )) (* Partial: should never return Nothing *) - -(** [get_elf64_version_number hdr] returns the ELF file's declared version - * number, extracting the information from header [hdr]. - *) -(*val get_elf64_version_number : elf64_header -> natural*) -let get_elf64_version_number hdr:Nat_big_num.num= - ((match Lem_list.list_index hdr.elf64_ident (Nat_big_num.to_int elf_ii_version) with - | Some ver -> Nat_big_num.of_string (Uint32.to_string ver) - | None -> failwith "get_elf64_version_number: lookup in ident failed" - )) (* Partial: should never return Nothing *) - -(** [is_valid_elf32_version_number hdr] checks whether an ELF file's declared - * version number matches the current, mandatory version number. - * TODO: this should be merged into [is_valid_elf32_header] to create a single - * correctness check. - *) -(*val is_valid_elf32_version_number : elf32_header -> bool*) -let is_valid_elf32_version_numer hdr:bool= (Nat_big_num.equal -(get_elf32_version_number hdr) elf_ev_current) - -(** [is_valid_elf64_version_number hdr] checks whether an ELF file's declared - * version number matches the current, mandatory version number. - * TODO: this should be merged into [is_valid_elf64_header] to create a single - * correctness check. - *) -(*val is_valid_elf64_version_number : elf64_header -> bool*) -let is_valid_elf64_version_numer hdr:bool= (Nat_big_num.equal -(get_elf64_version_number hdr) elf_ev_current) - -(** [get_elf32_abi_version hdr] returns the ELF file's declared ABI version - * number, extracting the information from header [hdr]. - *) -(*val get_elf32_abi_version : elf32_header -> natural*) -let get_elf32_abi_version hdr:Nat_big_num.num= - ((match Lem_list.list_index hdr.elf32_ident (Nat_big_num.to_int elf_ii_abiversion) with - | Some ver -> Nat_big_num.of_string (Uint32.to_string ver) - | None -> failwith "get_elf32_abi_version: lookup in ident failed" - )) (* Partial: should never return Nothing *) - -(** [get_elf64_abi_version hdr] returns the ELF file's declared ABI version - * number, extracting the information from header [hdr]. - *) -(*val get_elf64_abi_version : elf64_header -> natural*) -let get_elf64_abi_version hdr:Nat_big_num.num= - ((match Lem_list.list_index hdr.elf64_ident (Nat_big_num.to_int elf_ii_abiversion) with - | Some ver -> Nat_big_num.of_string (Uint32.to_string ver) - | None -> failwith "get_elf64_abi_version: lookup in ident failed" - )) (* Partial: should never return Nothing *) - -(** [deduce_endianness uc] deduces the endianness of an ELF file based on the ELF - * header's magic number [uc]. - *) -(*val deduce_endianness : list unsigned_char -> endianness*) -let deduce_endianness id2:endianness= - ((match Lem_list.list_index id2( 5) with - | None -> failwith "deduce_endianness: read of magic number has failed" - | Some v -> - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string v)) elf_data_2lsb then - Little - else if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string v)) elf_data_2msb then - Big - else - failwith "deduce_endianness: value is not valid" - )) - -(** [get_elf32_header_endianness hdr] returns the endianness of the ELF file - * as declared in its header, [hdr]. - *) -(*val get_elf32_header_endianness : elf32_header -> endianness*) -let get_elf32_header_endianness hdr:endianness= - (deduce_endianness (hdr.elf32_ident)) - -(** [get_elf64_header_endianness hdr] returns the endianness of the ELF file - * as declared in its header, [hdr]. - *) -(*val get_elf64_header_endianness : elf64_header -> endianness*) -let get_elf64_header_endianness hdr:endianness= - (deduce_endianness (hdr.elf64_ident)) - -(** [has_elf32_header_associated_entry_point hdr] checks whether the header - * [hdr] declares an entry point for the program. - *) -(*val has_elf32_header_associated_entry_point : elf32_header -> bool*) -let has_elf32_header_associated_entry_point hdr:bool= (not (Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string hdr.elf32_entry))(Nat_big_num.of_int 0))) - -(** [has_elf64_header_associated_entry_point hdr] checks whether the header - * [hdr] declares an entry point for the program. - *) -(*val has_elf64_header_associated_entry_point : elf64_header -> bool*) -let has_elf64_header_associated_entry_point hdr:bool= (not (Nat_big_num.equal (Ml_bindings.nat_big_num_of_uint64 hdr.elf64_entry)(Nat_big_num.of_int 0))) - -(** [has_elf32_header_string_table hdr] checks whether the header - * [hdr] declares whether the program has a string table or not. - *) -(*val has_elf32_header_string_table : elf32_header -> bool*) -let has_elf32_header_string_table hdr:bool= (not (Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string hdr.elf32_shstrndx)) shn_undef)) - -(** [has_elf64_header_string_table hdr] checks whether the header - * [hdr] declares whether the program has a string table or not. - *) -(*val has_elf64_header_string_table : elf64_header -> bool*) -let has_elf64_header_string_table hdr:bool= (not (Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string hdr.elf64_shstrndx)) shn_undef)) - -(** [is_elf32_header_section_size_in_section_header_table hdr] checks whether the header - * [hdr] declares whether the section size is too large to fit in the header - * field and is instead stored in the section header table. - *) -(*val is_elf32_header_section_size_in_section_header_table : elf32_header -> bool*) -let is_elf32_header_section_size_in_section_header_table hdr:bool= (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string hdr.elf32_shnum))(Nat_big_num.of_int 0)) - -(** [is_elf64_header_section_size_in_section_header_table hdr] checks whether the header - * [hdr] declares whether the section size is too large to fit in the header - * field and is instead stored in the section header table. - *) -(*val is_elf64_header_section_size_in_section_header_table : elf64_header -> bool*) -let is_elf64_header_section_size_in_section_header_table hdr:bool= (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string hdr.elf64_shnum))(Nat_big_num.of_int 0)) - -(** [is_elf32_header_string_table_index_in_link hdr] checks whether the header - * [hdr] declares whether the string table index is too large to fit in the - * header's field and is instead stored in the link field of an entry in the - * section header table. - *) -(*val is_elf32_header_string_table_index_in_link : elf32_header -> bool*) -let is_elf32_header_string_table_index_in_link hdr:bool= (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string hdr.elf32_shstrndx)) shn_xindex) - -(** [is_elf64_header_string_table_index_in_link hdr] checks whether the header - * [hdr] declares whether the string table index is too large to fit in the - * header's field and is instead stored in the link field of an entry in the - * section header table. - *) -(*val is_elf64_header_string_table_index_in_link : elf64_header -> bool*) -let is_elf64_header_string_table_index_in_link hdr:bool= (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string hdr.elf64_shstrndx)) shn_xindex) - -(** The [hdr_print_bundle] type is used to tidy up other type signatures. Some of the - * top-level string_of_ functions require six or more functions passed to them, - * which quickly gets out of hand. This type is used to reduce that complexity. - * The first component of the type is an OS specific print function, the second is - * a processor specific print function. - *) -type hdr_print_bundle = (Nat_big_num.num -> string) * (Nat_big_num.num -> string) - -(** [string_of_elf32_header hdr_bdl hdr] returns a string-based representation - * of header [hdr] using the ABI-specific print bundle [hdr_bdl]. - *) -(*val string_of_elf32_header : hdr_print_bundle -> elf32_header -> string*) -let string_of_elf32_header (os, proc) hdr:string= - (unlines [ -("\t" ^ ("Magic number: " ^ string_of_list - instance_Show_Show_Elf_types_native_uint_unsigned_char_dict hdr.elf32_ident)) - ; ("\t" ^ ("Endianness: " ^ string_of_endianness (deduce_endianness hdr.elf32_ident))) - ; ("\t" ^ ("Type: " ^ string_of_elf_file_type os proc (Nat_big_num.of_string (Uint32.to_string hdr.elf32_type)))) - ; ("\t" ^ ("Version: " ^ string_of_elf_version_number (Nat_big_num.of_string (Uint32.to_string hdr.elf32_version)))) - ; ("\t" ^ ("Machine: " ^ string_of_elf_machine_architecture (Nat_big_num.of_string (Uint32.to_string hdr.elf32_machine)))) - ; ("\t" ^ ("Entry point: " ^ Uint32.to_string hdr.elf32_entry)) - ; ("\t" ^ ("Flags: " ^ Uint32.to_string hdr.elf32_flags)) - ; ("\t" ^ ("Entries in program header table: " ^ Uint32.to_string hdr.elf32_phnum)) - ; ("\t" ^ ("Entries in section header table: " ^ Uint32.to_string hdr.elf32_shnum)) - ]) - -(** [string_of_elf64_header hdr_bdl hdr] returns a string-based representation - * of header [hdr] using the ABI-specific print bundle [hdr_bdl]. - *) -(*val string_of_elf64_header : hdr_print_bundle -> elf64_header -> string*) -let string_of_elf64_header (os, proc) hdr:string= - (unlines [ -("\t" ^ ("Magic number: " ^ string_of_list - instance_Show_Show_Elf_types_native_uint_unsigned_char_dict hdr.elf64_ident)) - ; ("\t" ^ ("Endianness: " ^ string_of_endianness (deduce_endianness hdr.elf64_ident))) - ; ("\t" ^ ("Type: " ^ string_of_elf_file_type os proc (Nat_big_num.of_string (Uint32.to_string hdr.elf64_type)))) - ; ("\t" ^ ("Version: " ^ string_of_elf_version_number (Nat_big_num.of_string (Uint32.to_string hdr.elf64_version)))) - ; ("\t" ^ ("Machine: " ^ string_of_elf_machine_architecture (Nat_big_num.of_string (Uint32.to_string hdr.elf64_machine)))) - ; ("\t" ^ ("Entry point: " ^ Uint64.to_string hdr.elf64_entry)) - ; ("\t" ^ ("Flags: " ^ Uint32.to_string hdr.elf64_flags)) - ; ("\t" ^ ("Entries in program header table: " ^ Uint32.to_string hdr.elf64_phnum)) - ; ("\t" ^ ("Entries in section header table: " ^ Uint32.to_string hdr.elf64_shnum)) - ]) - -(** The following are thin wrappers around the pretty-printing functions above - * using a default print bundle for the header. - *) - -(*val string_of_elf32_header_default : elf32_header -> string*) -let string_of_elf32_header_default:elf32_header ->string= - (string_of_elf32_header - (default_os_specific_print, - default_proc_specific_print)) - -(*val string_of_elf64_header_default : elf64_header -> string*) -let string_of_elf64_header_default:elf64_header ->string= - (string_of_elf64_header - (default_os_specific_print, - default_proc_specific_print)) - -let instance_Show_Show_Elf_header_elf32_header_dict:(elf32_header)show_class= ({ - - show_method = string_of_elf32_header_default}) - -let instance_Show_Show_Elf_header_elf64_header_dict:(elf64_header)show_class= ({ - - show_method = string_of_elf64_header_default}) - -(** [read_elf_ident bs0] reads the initial bytes of an ELF file from byte sequence - * [bs0], returning the remainder of the byte sequence too. - * Fails if transcription fails. - *) -(*val read_elf_ident : byte_sequence -> error (list unsigned_char * byte_sequence)*) -let read_elf_ident bs:((Uint32.uint32)list*byte_sequence)error= -(repeatM' ei_nident bs (read_unsigned_char default_endianness)) - -(** [bytes_of_elf32_header hdr] blits an ELF header [hdr] to a byte sequence, - * ready for transcription to a binary file. - *) -(*val bytes_of_elf32_header : elf32_header -> byte_sequence*) -let bytes_of_elf32_header hdr:byte_sequence= - (let endian = (deduce_endianness hdr.elf32_ident) in - Byte_sequence.from_byte_lists [ - Lem_list.map (fun u->Char.chr (Uint32.to_int u)) hdr.elf32_ident - ; bytes_of_elf32_half endian hdr.elf32_type - ; bytes_of_elf32_half endian hdr.elf32_machine - ; bytes_of_elf32_word endian hdr.elf32_version - ; bytes_of_elf32_addr endian hdr.elf32_entry - ; bytes_of_elf32_off endian hdr.elf32_phoff - ; bytes_of_elf32_off endian hdr.elf32_shoff - ; bytes_of_elf32_word endian hdr.elf32_flags - ; bytes_of_elf32_half endian hdr.elf32_ehsize - ; bytes_of_elf32_half endian hdr.elf32_phentsize - ; bytes_of_elf32_half endian hdr.elf32_phnum - ; bytes_of_elf32_half endian hdr.elf32_shentsize - ; bytes_of_elf32_half endian hdr.elf32_shnum - ; bytes_of_elf32_half endian hdr.elf32_shstrndx - ]) - -(** [bytes_of_elf64_header hdr] blits an ELF header [hdr] to a byte sequence, - * ready for transcription to a binary file. - *) -(*val bytes_of_elf64_header : elf64_header -> byte_sequence*) -let bytes_of_elf64_header hdr:byte_sequence= - (let endian = (deduce_endianness hdr.elf64_ident) in - Byte_sequence.from_byte_lists [ - Lem_list.map (fun u->Char.chr (Uint32.to_int u)) hdr.elf64_ident - ; bytes_of_elf64_half endian hdr.elf64_type - ; bytes_of_elf64_half endian hdr.elf64_machine - ; bytes_of_elf64_word endian hdr.elf64_version - ; bytes_of_elf64_addr endian hdr.elf64_entry - ; bytes_of_elf64_off endian hdr.elf64_phoff - ; bytes_of_elf64_off endian hdr.elf64_shoff - ; bytes_of_elf64_word endian hdr.elf64_flags - ; bytes_of_elf64_half endian hdr.elf64_ehsize - ; bytes_of_elf64_half endian hdr.elf64_phentsize - ; bytes_of_elf64_half endian hdr.elf64_phnum - ; bytes_of_elf64_half endian hdr.elf64_shentsize - ; bytes_of_elf64_half endian hdr.elf64_shnum - ; bytes_of_elf64_half endian hdr.elf64_shstrndx - ]) - -(*val is_elf32_header_padding_correct : elf32_header -> bool*) -let is_elf32_header_padding_correct ehdr:bool= ((Lem.option_equal (=) -(Lem_list.list_index ehdr.elf32_ident( 9)) (Some (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))))) && ((Lem.option_equal (=) -(Lem_list.list_index ehdr.elf32_ident( 10)) (Some (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))))) && ((Lem.option_equal (=) -(Lem_list.list_index ehdr.elf32_ident( 11)) (Some (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))))) && ((Lem.option_equal (=) -(Lem_list.list_index ehdr.elf32_ident( 12)) (Some (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))))) && ((Lem.option_equal (=) -(Lem_list.list_index ehdr.elf32_ident( 13)) (Some (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))))) && ((Lem.option_equal (=) -(Lem_list.list_index ehdr.elf32_ident( 14)) (Some (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))))) && (Lem.option_equal (=) -(Lem_list.list_index ehdr.elf32_ident( 15)) (Some (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))))))))))) - -(*val is_magic_number_correct : list unsigned_char -> bool*) -let is_magic_number_correct ident:bool= ((Lem.option_equal (=) -(Lem_list.list_index ident( 0)) (Some (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 127))))) && ((Lem.option_equal (=) -(Lem_list.list_index ident( 1)) (Some (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 69))))) && ((Lem.option_equal (=) -(Lem_list.list_index ident( 2)) (Some (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 76))))) && (Lem.option_equal (=) -(Lem_list.list_index ident( 3)) (Some (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 70)))))))) - -(** [read_elf32_header bs0] reads an ELF header from the byte sequence [bs0]. - * Fails if transcription fails. - *) -(*val read_elf32_header : byte_sequence -> error (elf32_header * byte_sequence)*) -let read_elf32_header bs:(elf32_header*byte_sequence)error= - (read_elf_ident bs >>= (fun (ident, bs) -> - if not (is_magic_number_correct ident) then - fail "read_elf32_header: magic number incorrect" - else - let endian = (deduce_endianness ident) in - read_elf32_half endian bs >>= (fun (typ, bs) -> - read_elf32_half endian bs >>= (fun (machine, bs) -> - read_elf32_word endian bs >>= (fun (version, bs) -> - read_elf32_addr endian bs >>= (fun (entry, bs) -> - read_elf32_off endian bs >>= (fun (phoff, bs) -> - read_elf32_off endian bs >>= (fun (shoff, bs) -> - read_elf32_word endian bs >>= (fun (flags, bs) -> - read_elf32_half endian bs >>= (fun (ehsize, bs) -> - read_elf32_half endian bs >>= (fun (phentsize, bs) -> - read_elf32_half endian bs >>= (fun (phnum, bs) -> - read_elf32_half endian bs >>= (fun (shentsize, bs) -> - read_elf32_half endian bs >>= (fun (shnum, bs) -> - read_elf32_half endian bs >>= (fun (shstrndx, bs) -> - (match Lem_list.list_index ident( 4) with - | None -> fail "read_elf32_header: transcription of ELF identifier failed" - | Some c -> - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string c)) elf_class_32 then - return ({ elf32_ident = ident; elf32_type = typ; - elf32_machine = machine; elf32_version = version; - elf32_entry = entry; elf32_phoff = phoff; - elf32_shoff = shoff; elf32_flags = flags; - elf32_ehsize = ehsize; elf32_phentsize = phentsize; - elf32_phnum = phnum; elf32_shentsize = shentsize; - elf32_shnum = shnum; elf32_shstrndx = shstrndx }, bs) - else - fail "read_elf32_header: not a 32-bit ELF file" - )))))))))))))))) - -(** [read_elf64_header bs0] reads an ELF header from the byte sequence [bs0]. - * Fails if transcription fails. - *) -(*val read_elf64_header : byte_sequence -> error (elf64_header * byte_sequence)*) -let read_elf64_header bs:(elf64_header*byte_sequence)error= - (read_elf_ident bs >>= (fun (ident, bs) -> - if not (is_magic_number_correct ident) then - fail "read_elf64_header: magic number incorrect" - else - let endian = (deduce_endianness ident) in - read_elf64_half endian bs >>= (fun (typ, bs) -> - read_elf64_half endian bs >>= (fun (machine, bs) -> - read_elf64_word endian bs >>= (fun (version, bs) -> - read_elf64_addr endian bs >>= (fun (entry, bs) -> - read_elf64_off endian bs >>= (fun (phoff, bs) -> - read_elf64_off endian bs >>= (fun (shoff, bs) -> - read_elf64_word endian bs >>= (fun (flags, bs) -> - read_elf64_half endian bs >>= (fun (ehsize, bs) -> - read_elf64_half endian bs >>= (fun (phentsize, bs) -> - read_elf64_half endian bs >>= (fun (phnum, bs) -> - read_elf64_half endian bs >>= (fun (shentsize, bs) -> - read_elf64_half endian bs >>= (fun (shnum, bs) -> - read_elf64_half endian bs >>= (fun (shstrndx, bs) -> - (match Lem_list.list_index ident( 4) with - | None -> fail "read_elf64_header: transcription of ELF identifier failed" - | Some c -> - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string c)) elf_class_64 then - return ({ elf64_ident = ident; elf64_type = typ; - elf64_machine = machine; elf64_version = version; - elf64_entry = entry; elf64_phoff = phoff; - elf64_shoff = shoff; elf64_flags = flags; - elf64_ehsize = ehsize; elf64_phentsize = phentsize; - elf64_phnum = phnum; elf64_shentsize = shentsize; - elf64_shnum = shnum; elf64_shstrndx = shstrndx }, bs) - else - fail "read_elf64_header: not a 64-bit ELF file" - )))))))))))))))) - -(** [is_elf32_header_class_correct hdr] checks whether the declared file class - * is correct. - *) -(*val is_elf32_header_class_correct : elf32_header -> bool*) -let is_elf32_header_class_correct ehdr:bool= (Lem.option_equal (=) -(Lem_list.list_index ehdr.elf32_ident( 4)) (Some (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 1))))) - -(** [is_elf64_header_class_correct hdr] checks whether the declared file class - * is correct. - *) -(*val is_elf64_header_class_correct : elf64_header -> bool*) -let is_elf64_header_class_correct ehdr:bool= (Lem.option_equal (=) -(Lem_list.list_index ehdr.elf64_ident( 4)) (Some (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 1))))) - -(** [is_elf32_header_version_correct hdr] checks whether the declared file version - * is correct. - *) -(*val is_elf32_header_version_correct : elf32_header -> bool*) -let is_elf32_header_version_correct ehdr:bool= (Lem.option_equal (=) -(Lem_list.list_index ehdr.elf32_ident( 6)) (Some (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 1))))) - -(** [is_elf64_header_version_correct hdr] checks whether the declared file version - * is correct. - *) -(*val is_elf64_header_version_correct : elf64_header -> bool*) -let is_elf64_header_version_correct ehdr:bool= (Lem.option_equal (=) -(Lem_list.list_index ehdr.elf64_ident( 6)) (Some (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 1))))) - -(** [is_elf32_header_valid] checks whether an [elf32_header] value is a valid 32-bit - * ELF file header (i.e. [elf32_ident] is [ei_nident] entries long, and other - * constraints on headers). - *) -(*val is_elf32_header_valid : elf32_header -> bool*) -let is_elf32_header_valid ehdr:bool= (Nat_big_num.equal -(Nat_big_num.of_int (List.length ehdr.elf32_ident)) ei_nident && -(is_magic_number_correct ehdr.elf32_ident && -(is_elf32_header_padding_correct ehdr && -(is_elf32_header_class_correct ehdr && - is_elf32_header_version_correct ehdr)))) - -(** [get_elf32_header_program_table_size] calculates the size of the program table - * (entry size x number of entries) based on data in the ELF header. - *) -(*val get_elf32_header_program_table_size : elf32_header -> natural*) -let get_elf32_header_program_table_size ehdr:Nat_big_num.num= - (let phentsize = (Nat_big_num.of_string (Uint32.to_string ehdr.elf32_phentsize)) in - let phnum = (Nat_big_num.of_string (Uint32.to_string ehdr.elf32_phnum)) in Nat_big_num.mul - phentsize phnum) - -(** [get_elf64_header_program_table_size] calculates the size of the program table - * (entry size x number of entries) based on data in the ELF header. - *) -(*val get_elf64_header_program_table_size : elf64_header -> natural*) -let get_elf64_header_program_table_size ehdr:Nat_big_num.num= - (let phentsize = (Nat_big_num.of_string (Uint32.to_string ehdr.elf64_phentsize)) in - let phnum = (Nat_big_num.of_string (Uint32.to_string ehdr.elf64_phnum)) in Nat_big_num.mul - phentsize phnum) - -(** [is_elf32_header_section_table_present] calculates whether a section table - * is present in the ELF file or not. - *) -(*val is_elf32_header_section_table_present : elf32_header -> bool*) -let is_elf32_header_section_table_present ehdr:bool= - (not ( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string ehdr.elf32_shoff))(Nat_big_num.of_int 0))) - -(** [is_elf64_header_section_table_present] calculates whether a section table - * is present in the ELF file or not. - *) -(*val is_elf64_header_section_table_present : elf64_header -> bool*) -let is_elf64_header_section_table_present ehdr:bool= - (not ( Nat_big_num.equal(Nat_big_num.of_string (Uint64.to_string ehdr.elf64_shoff))(Nat_big_num.of_int 0))) - -(** [get_elf32_header_section_table_size] calculates the size of the section table - * (entry size x number of entries) based on data in the ELF header. - *) -(*val get_elf32_header_section_table_size : elf32_header -> natural*) -let get_elf32_header_section_table_size ehdr:Nat_big_num.num= - (let shentsize = (Nat_big_num.of_string (Uint32.to_string ehdr.elf32_shentsize)) in - let shnum = (Nat_big_num.of_string (Uint32.to_string ehdr.elf32_shnum)) in Nat_big_num.mul - shentsize shnum) - -(** [get_elf64_header_section_table_size] calculates the size of the section table - * (entry size x number of entries) based on data in the ELF header. - *) -(*val get_elf64_header_section_table_size : elf64_header -> natural*) -let get_elf64_header_section_table_size ehdr:Nat_big_num.num= - (let shentsize = (Nat_big_num.of_string (Uint32.to_string ehdr.elf64_shentsize)) in - let shnum = (Nat_big_num.of_string (Uint32.to_string ehdr.elf64_shnum)) in Nat_big_num.mul - shentsize shnum) diff --git a/lib/ocaml_rts/linksem/elf_interpreted_section.ml b/lib/ocaml_rts/linksem/elf_interpreted_section.ml deleted file mode 100644 index 7fcf59b4..00000000 --- a/lib/ocaml_rts/linksem/elf_interpreted_section.ml +++ /dev/null @@ -1,305 +0,0 @@ -(*Generated by Lem from elf_interpreted_section.lem.*) -(** Module [elf_interpreted_section] provides a record of "interpreted" sections, - * i.e. the data stored in the section header table converted to more amenable - * infinite precision types, and operation on those records. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_list -open Lem_maybe -open Lem_num -open Lem_string - -open Byte_sequence -open Error -open String_table - -open Elf_types_native_uint -open Elf_section_header_table - -open Missing_pervasives -open Show - -(** [elf32_interpreted_section] exactly mirrors the structure of a section header - * table entry, barring the conversion of all fields to more amenable types. - *) -type elf32_interpreted_section = - { elf32_section_name : Nat_big_num.num (** Name of the section *) - ; elf32_section_type : Nat_big_num.num (** Type of the section *) - ; elf32_section_flags : Nat_big_num.num (** Flags associated with the section *) - ; elf32_section_addr : Nat_big_num.num (** Base address of the section in memory *) - ; elf32_section_offset : Nat_big_num.num (** Offset from beginning of file *) - ; elf32_section_size : Nat_big_num.num (** Section size in bytes *) - ; elf32_section_link : Nat_big_num.num (** Section header table index link *) - ; elf32_section_info : Nat_big_num.num (** Extra information, depends on section type *) - ; elf32_section_align : Nat_big_num.num (** Alignment constraints for section *) - ; elf32_section_entsize : Nat_big_num.num (** Size of each entry in table, if section is one *) - ; elf32_section_body : byte_sequence (** Body of section *) - ; elf32_section_name_as_string : string (** Name of the section, as a string; "" for no name (name = 0) *) - } - -(** [elf32_interpreted_section_equal s1 s2] is an equality test on interpreted - * sections [s1] and [s2]. - *) -(*val elf32_interpreted_section_equal : elf32_interpreted_section -> elf32_interpreted_section -> bool*) -let elf32_interpreted_section_equal x y:bool= (Nat_big_num.equal - x.elf32_section_name y.elf32_section_name && (Nat_big_num.equal - x.elf32_section_type y.elf32_section_type && (Nat_big_num.equal - x.elf32_section_flags y.elf32_section_flags && (Nat_big_num.equal - x.elf32_section_addr y.elf32_section_addr && (Nat_big_num.equal - x.elf32_section_offset y.elf32_section_offset && (Nat_big_num.equal - x.elf32_section_size y.elf32_section_size && (Nat_big_num.equal - x.elf32_section_link y.elf32_section_link && (Nat_big_num.equal - x.elf32_section_info y.elf32_section_info && (Nat_big_num.equal - x.elf32_section_align y.elf32_section_align && (Nat_big_num.equal - x.elf32_section_entsize y.elf32_section_entsize && (equal - x.elf32_section_body y.elf32_section_body && -(x.elf32_section_name_as_string = y.elf32_section_name_as_string)))))))))))) - -let instance_Basic_classes_Eq_Elf_interpreted_section_elf32_interpreted_section_dict:(elf32_interpreted_section)eq_class= ({ - - isEqual_method = elf32_interpreted_section_equal; - - isInequal_method = (fun x y->not (elf32_interpreted_section_equal x y))}) - -(** [elf64_interpreted_section] exactly mirrors the structure of a section header - * table entry, barring the conversion of all fields to more amenable types. - *) -type elf64_interpreted_section = - { elf64_section_name : Nat_big_num.num (** Name of the section *) - ; elf64_section_type : Nat_big_num.num (** Type of the section *) - ; elf64_section_flags : Nat_big_num.num (** Flags associated with the section *) - ; elf64_section_addr : Nat_big_num.num (** Base address of the section in memory *) - ; elf64_section_offset : Nat_big_num.num (** Offset from beginning of file *) - ; elf64_section_size : Nat_big_num.num (** Section size in bytes *) - ; elf64_section_link : Nat_big_num.num (** Section header table index link *) - ; elf64_section_info : Nat_big_num.num (** Extra information, depends on section type *) - ; elf64_section_align : Nat_big_num.num (** Alignment constraints for section *) - ; elf64_section_entsize : Nat_big_num.num (** Size of each entry in table, if section is one *) - ; elf64_section_body : byte_sequence (** Body of section *) - ; elf64_section_name_as_string : string (** Name of the section, as a string; "" for no name (name = 0) *) - } - -(** [compare_elf64_interpreted_section s1 s2] is an ordering comparison function - * on interpreted sections suitable for use in sets, finite maps and other - * ordered structures. - *) -(*val compare_elf64_interpreted_section : elf64_interpreted_section -> elf64_interpreted_section -> - ordering*) -let compare_elf64_interpreted_section s1 s2:int= - (pairCompare (lexicographic_compare Nat_big_num.compare) compare_byte_sequence - ([s1.elf64_section_name ; - s1.elf64_section_type ; - s1.elf64_section_flags ; - s1.elf64_section_addr ; - s1.elf64_section_offset ; - s1.elf64_section_size ; - s1.elf64_section_link ; - s1.elf64_section_info ; - s1.elf64_section_align ; - s1.elf64_section_entsize], s1.elf64_section_body) - ([s2.elf64_section_name ; - s2.elf64_section_type ; - s2.elf64_section_flags ; - s2.elf64_section_addr ; - s2.elf64_section_offset ; - s2.elf64_section_size ; - s2.elf64_section_link ; - s2.elf64_section_info ; - s2.elf64_section_align ; - s2.elf64_section_entsize], s2.elf64_section_body)) - -let instance_Basic_classes_Ord_Elf_interpreted_section_elf64_interpreted_section_dict:(elf64_interpreted_section)ord_class= ({ - - compare_method = compare_elf64_interpreted_section; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(compare_elf64_interpreted_section f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (compare_elf64_interpreted_section f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(compare_elf64_interpreted_section f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (compare_elf64_interpreted_section f1 f2)(Pset.from_list compare [1; 0])))}) - -(** [elf64_interpreted_section_equal s1 s2] is an equality test on interpreted - * sections [s1] and [s2]. - *) -(*val elf64_interpreted_section_equal : elf64_interpreted_section -> elf64_interpreted_section -> bool*) -let elf64_interpreted_section_equal x y:bool= (Nat_big_num.equal - x.elf64_section_name y.elf64_section_name && (Nat_big_num.equal - x.elf64_section_type y.elf64_section_type && (Nat_big_num.equal - x.elf64_section_flags y.elf64_section_flags && (Nat_big_num.equal - x.elf64_section_addr y.elf64_section_addr && (Nat_big_num.equal - x.elf64_section_offset y.elf64_section_offset && (Nat_big_num.equal - x.elf64_section_size y.elf64_section_size && (Nat_big_num.equal - x.elf64_section_link y.elf64_section_link && (Nat_big_num.equal - x.elf64_section_info y.elf64_section_info && (Nat_big_num.equal - x.elf64_section_align y.elf64_section_align && (Nat_big_num.equal - x.elf64_section_entsize y.elf64_section_entsize && (equal - x.elf64_section_body y.elf64_section_body && -(x.elf64_section_name_as_string = y.elf64_section_name_as_string)))))))))))) - -(** [null_elf32_interpreted_section] --- the null interpreted section. - *) -(*val null_elf32_interpreted_section : elf32_interpreted_section*) -let null_elf32_interpreted_section:elf32_interpreted_section= - ({ elf32_section_name =(Nat_big_num.of_int 0) - ; elf32_section_type =(Nat_big_num.of_int 0) - ; elf32_section_flags =(Nat_big_num.of_int 0) - ; elf32_section_addr =(Nat_big_num.of_int 0) - ; elf32_section_offset =(Nat_big_num.of_int 0) - ; elf32_section_size =(Nat_big_num.of_int 0) - ; elf32_section_link =(Nat_big_num.of_int 0) - ; elf32_section_info =(Nat_big_num.of_int 0) - ; elf32_section_align =(Nat_big_num.of_int 0) - ; elf32_section_entsize =(Nat_big_num.of_int 0) - ; elf32_section_body = Byte_sequence.empty - ; elf32_section_name_as_string = "" - }) - -(** [null_elf64_interpreted_section] --- the null interpreted section. - *) -(*val null_elf64_interpreted_section : elf64_interpreted_section*) -let null_elf64_interpreted_section:elf64_interpreted_section= - ({ elf64_section_name =(Nat_big_num.of_int 0) - ; elf64_section_type =(Nat_big_num.of_int 0) - ; elf64_section_flags =(Nat_big_num.of_int 0) - ; elf64_section_addr =(Nat_big_num.of_int 0) - ; elf64_section_offset =(Nat_big_num.of_int 0) - ; elf64_section_size =(Nat_big_num.of_int 0) - ; elf64_section_link =(Nat_big_num.of_int 0) - ; elf64_section_info =(Nat_big_num.of_int 0) - ; elf64_section_align =(Nat_big_num.of_int 0) - ; elf64_section_entsize =(Nat_big_num.of_int 0) - ; elf64_section_body = Byte_sequence.empty - ; elf64_section_name_as_string = "" - }) - -let instance_Basic_classes_Eq_Elf_interpreted_section_elf64_interpreted_section_dict:(elf64_interpreted_section)eq_class= ({ - - isEqual_method = elf64_interpreted_section_equal; - - isInequal_method = (fun x y->not (elf64_interpreted_section_equal x y))}) - -(** [elf64_interpreted_section_matches_section_header sect ent] checks whether - * the interpreted section and the corresponding section header table entry - * match. - *) -(*val elf64_interpreted_section_matches_section_header : - elf64_interpreted_section - -> elf64_section_header_table_entry - -> bool*) -let elf64_interpreted_section_matches_section_header i sh:bool= (Nat_big_num.equal - i.elf64_section_name (Nat_big_num.of_string (Uint32.to_string sh.elf64_sh_name)) && (Nat_big_num.equal - i.elf64_section_type (Nat_big_num.of_string (Uint32.to_string sh.elf64_sh_type)) && (Nat_big_num.equal - i.elf64_section_flags (Ml_bindings.nat_big_num_of_uint64 sh.elf64_sh_flags) && (Nat_big_num.equal - i.elf64_section_addr (Ml_bindings.nat_big_num_of_uint64 sh.elf64_sh_addr) && (Nat_big_num.equal - i.elf64_section_offset (Nat_big_num.of_string (Uint64.to_string sh.elf64_sh_offset)) && (Nat_big_num.equal - i.elf64_section_size (Ml_bindings.nat_big_num_of_uint64 sh.elf64_sh_size) && (Nat_big_num.equal - i.elf64_section_link (Nat_big_num.of_string (Uint32.to_string sh.elf64_sh_link)) && (Nat_big_num.equal - i.elf64_section_info (Nat_big_num.of_string (Uint32.to_string sh.elf64_sh_info)) && (Nat_big_num.equal - i.elf64_section_align (Ml_bindings.nat_big_num_of_uint64 sh.elf64_sh_addralign) (* WHY? *) && Nat_big_num.equal - i.elf64_section_entsize (Ml_bindings.nat_big_num_of_uint64 sh.elf64_sh_entsize)))))))))) - (* Don't compare the name as a string, because it's implied by the shshtrtab index. *) - (* NOTE that we can have multiple sections *indistinguishable* - * except by their section header table index. Imagine - * multiple zero-size bss sections at the same address with the same name. - * That's why in elf_memory_image we always label each ElfSection - * with its SHT index. - *) - -type elf32_interpreted_sections = elf32_interpreted_section list -type elf64_interpreted_sections = elf64_interpreted_section list - -(** [string_of_elf32_interpreted_section sect] returns a string-based representation - * of interpreted section, [sect]. - *) -(*val string_of_elf32_interpreted_section : elf32_interpreted_section -> string*) -let string_of_elf32_interpreted_section is:string= - (unlines [ -("Name: " ^ (is.elf32_section_name_as_string ^ ("(" ^ ((Nat_big_num.to_string is.elf32_section_name) ^ ")")))) - ; ("Type: " ^ Nat_big_num.to_string is.elf32_section_type) - ; ("Flags: " ^ Nat_big_num.to_string is.elf32_section_type) - ; ("Base address: " ^ Nat_big_num.to_string is.elf32_section_addr) - ; ("Section offset: " ^ Nat_big_num.to_string is.elf32_section_offset) - ; ("Section size: " ^ Nat_big_num.to_string is.elf32_section_size) - ; ("Link: " ^ Nat_big_num.to_string is.elf32_section_link) - ; ("Info: " ^ Nat_big_num.to_string is.elf32_section_info) - ; ("Section alignment: " ^ Nat_big_num.to_string is.elf32_section_align) - ; ("Entry size: " ^ Nat_big_num.to_string is.elf32_section_entsize) - ]) - -(** [string_of_elf64_interpreted_section sect] returns a string-based representation - * of interpreted section, [sect]. - *) -(*val string_of_elf64_interpreted_section : elf64_interpreted_section -> string*) -let string_of_elf64_interpreted_section is:string= - (unlines [ -("Name: " ^ (is.elf64_section_name_as_string ^ ("(" ^ ((Nat_big_num.to_string is.elf64_section_name) ^ ")")))) - ; ("Type: " ^ Nat_big_num.to_string is.elf64_section_type) - ; ("Flags: " ^ Nat_big_num.to_string is.elf64_section_type) - ; ("Base address: " ^ Nat_big_num.to_string is.elf64_section_addr) - ; ("Section offset: " ^ Nat_big_num.to_string is.elf64_section_offset) - ; ("Section size: " ^ Nat_big_num.to_string is.elf64_section_size) - ; ("Link: " ^ Nat_big_num.to_string is.elf64_section_link) - ; ("Info: " ^ Nat_big_num.to_string is.elf64_section_info) - ; ("Section alignment: " ^ Nat_big_num.to_string is.elf64_section_align) - ; ("Entry size: " ^ Nat_big_num.to_string is.elf64_section_entsize) - ]) - -(** [is_valid_elf32_section_header_table_entry sect stab] checks whether a - * interpreted section conforms with the prescribed flags and types declared - * in the "special sections" table of the ELF specification. - * TODO: some of these entries in the table are overridden by ABI supplements. - * Make sure it is these that are passed in rather than the default table - * declared in the spec? - *) -(*val is_valid_elf32_section_header_table_entry : elf32_interpreted_section -> - string_table -> bool*) -let is_valid_elf32_section_header_table_entry ent stbl:bool= - ((match String_table.get_string_at ent.elf32_section_name stbl with - | Fail f -> false - | Success name1 -> - (match Pmap.lookup name1 elf_special_sections with - | None -> false (* ??? *) - | Some (typ, flags) -> Nat_big_num.equal - typ ent.elf32_section_type && Nat_big_num.equal flags ent.elf32_section_flags - ) - )) - -(** [is_valid_elf64_section_header_table_entry sect stab] checks whether a - * interpreted section conforms with the prescribed flags and types declared - * in the "special sections" table of the ELF specification. - * TODO: some of these entries in the table are overridden by ABI supplements. - * Make sure it is these that are passed in rather than the default table - * declared in the spec? - *) -(*val is_valid_elf64_section_header_table_entry : elf64_interpreted_section -> - string_table -> bool*) -let is_valid_elf64_section_header_table_entry ent stbl:bool= - ((match String_table.get_string_at ent.elf64_section_name stbl with - | Fail f -> false - | Success name1 -> - (match Pmap.lookup name1 elf_special_sections with - | None -> false (* ??? *) - | Some (typ, flags) -> Nat_big_num.equal - typ ent.elf64_section_type && Nat_big_num.equal flags ent.elf64_section_flags - ) - )) - -(** [is_valid_elf32_section_header_table sects] checks whether all entries in - * [sect] are valid. - *) -(*val is_valid_elf32_section_header_table : list elf32_interpreted_section -> - string_table -> bool*) -let is_valid_elf32_section_header_table0 ents stbl:bool= - (List.for_all (fun x -> is_valid_elf32_section_header_table_entry x stbl) ents) - -(** [is_valid_elf64_section_header_table sects] checks whether all entries in - * [sect] are valid. - *) -(*val is_valid_elf64_section_header_table : list elf64_interpreted_section -> - string_table -> bool*) -let is_valid_elf64_section_header_table0 ents stbl:bool= - (List.for_all (fun x -> is_valid_elf64_section_header_table_entry x stbl) ents) diff --git a/lib/ocaml_rts/linksem/elf_interpreted_segment.ml b/lib/ocaml_rts/linksem/elf_interpreted_segment.ml deleted file mode 100644 index 1971f350..00000000 --- a/lib/ocaml_rts/linksem/elf_interpreted_segment.ml +++ /dev/null @@ -1,167 +0,0 @@ -(*Generated by Lem from elf_interpreted_segment.lem.*) -(** [elf_interpreted_segment] defines interpreted segments, i.e. the contents of - * a program header table entry converted to more amenable types, and operations - * built on top of them. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_num -open Lem_string - -open Elf_types_native_uint -open Elf_program_header_table - -open Byte_sequence -open Missing_pervasives -open Show - -open Hex_printing - -(** [elf32_interpreted_segment] represents an ELF32 interpreted segment, i.e. the - * contents of an ELF program header table entry converted into more amenable - * (infinite precision) types, for manipulation. - * Invariant: the nth entry of the program header table corresponds to the nth - * entry of the list of interpreted segments in an [elf32_file] record. The - * lengths of the two lists are exactly the same. - *) -type elf32_interpreted_segment = - { elf32_segment_body : byte_sequence (** Body of the segment *) - ; elf32_segment_type : Nat_big_num.num (** Type of the segment *) - ; elf32_segment_size : Nat_big_num.num (** Size of the segment in bytes *) - ; elf32_segment_memsz : Nat_big_num.num (** Size of the segment in memory in bytes *) - ; elf32_segment_base : Nat_big_num.num (** Base address of the segment *) - ; elf32_segment_paddr : Nat_big_num.num (** Physical address of segment *) - ; elf32_segment_align : Nat_big_num.num (** Alignment of the segment *) - ; elf32_segment_offset : Nat_big_num.num (** Offset of the segment *) - ; elf32_segment_flags : (bool * bool * bool) (** READ, WRITE, EXECUTE flags. *) - } - -(** [elf64_interpreted_segment] represents an ELF64 interpreted segment, i.e. the - * contents of an ELF program header table entry converted into more amenable - * (infinite precision) types, for manipulation. - * Invariant: the nth entry of the program header table corresponds to the nth - * entry of the list of interpreted segments in an [elf64_file] record. The - * lengths of the two lists are exactly the same. - *) -type elf64_interpreted_segment = - { elf64_segment_body : byte_sequence (** Body of the segment *) - ; elf64_segment_type : Nat_big_num.num (** Type of the segment *) - ; elf64_segment_size : Nat_big_num.num (** Size of the segment in bytes *) - ; elf64_segment_memsz : Nat_big_num.num (** Size of the segment in memory in bytes *) - ; elf64_segment_base : Nat_big_num.num (** Base address of the segment *) - ; elf64_segment_paddr : Nat_big_num.num (** Physical address of segment *) - ; elf64_segment_align : Nat_big_num.num (** Alignment of the segment *) - ; elf64_segment_offset : Nat_big_num.num (** Offset of the segment *) - ; elf64_segment_flags : (bool * bool * bool) (** READ, WRITE, EXECUTE flags. *) - } - -(** [compare_elf64_interpreted_segment seg1 seg2] is an ordering comparison function - * on interpreted segments suitable for constructing sets, finite maps and other - * ordered data types out of. - *) -(*val compare_elf64_interpreted_segment : elf64_interpreted_segment -> - elf64_interpreted_segment -> ordering*) -let compare_elf64_interpreted_segment s1 s2:int= - (tripleCompare compare_byte_sequence (Lem_list.lexicographic_compare Nat_big_num.compare) (Lem_list.lexicographic_compare Nat_big_num.compare) - (s1.elf64_segment_body, - [s1.elf64_segment_type ; - s1.elf64_segment_size ; - s1.elf64_segment_memsz ; - s1.elf64_segment_base ; - s1.elf64_segment_paddr ; - s1.elf64_segment_align ; - s1.elf64_segment_offset], - (let (f1, f2, f3) = (s1.elf64_segment_flags) in - Lem_list.map natural_of_bool [f1; f2; f3])) - (s2.elf64_segment_body, - [s2.elf64_segment_type ; - s2.elf64_segment_size ; - s2.elf64_segment_memsz ; - s2.elf64_segment_base ; - s2.elf64_segment_paddr ; - s2.elf64_segment_align ; - s2.elf64_segment_offset], -(let (f1, f2, f3) = (s2.elf64_segment_flags) in - Lem_list.map natural_of_bool [f1; f2; f3]))) - -let instance_Basic_classes_Ord_Elf_interpreted_segment_elf64_interpreted_segment_dict:(elf64_interpreted_segment)ord_class= ({ - - compare_method = compare_elf64_interpreted_segment; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(compare_elf64_interpreted_segment f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> let result = (compare_elf64_interpreted_segment f1 f2) in Lem.orderingEqual result (-1) || Lem.orderingEqual result 0)); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(compare_elf64_interpreted_segment f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> let result = (compare_elf64_interpreted_segment f1 f2) in Lem.orderingEqual result 1 || Lem.orderingEqual result 0))}) - -type elf32_interpreted_segments = elf32_interpreted_segment list -type elf64_interpreted_segments = elf64_interpreted_segment list - -(** [elf32_interpreted_program_header_flags w] extracts a boolean triple of flags - * from the flags field of an interpreted segment. - *) -(*val elf32_interpret_program_header_flags : elf32_word -> (bool * bool * bool)*) -let elf32_interpret_program_header_flags flags:bool*bool*bool= - (let zero = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) in - let one = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 1))) in - let two = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 2))) in - let four = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 4))) in - (not (Uint32.logand flags one = zero), - not (Uint32.logand flags two = zero), - not (Uint32.logand flags four = zero))) - -(** [elf64_interpreted_program_header_flags w] extracts a boolean triple of flags - * from the flags field of an interpreted segment. - *) -(*val elf64_interpret_program_header_flags : elf64_word -> (bool * bool * bool)*) -let elf64_interpret_program_header_flags flags:bool*bool*bool= - (let zero = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) in - let one = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 1))) in - let two = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 2))) in - let four = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 4))) in - (not (Uint32.logand flags one = zero), - not (Uint32.logand flags two = zero), - not (Uint32.logand flags four = zero))) - -(** [string_of_flags bs] produces a string-based representation of an interpreted - * segments flags (represented as a boolean triple). - *) -(*val string_of_flags : (bool * bool * bool) -> string*) -let string_of_flags flags:string= - ((match flags with - | (read, write, execute) -> - bracket [string_of_bool read; string_of_bool write; string_of_bool execute] - )) - -(** [string_of_elf32_interpreted_segment seg] produces a string-based representation - * of interpreted segment [seg]. - *) -(*val string_of_elf32_interpreted_segment : elf32_interpreted_segment -> string*) -let string_of_elf32_interpreted_segment seg:string= - (unlines [ -("Body of length: " ^ unsafe_hex_string_of_natural( 16) (Byte_sequence.length0 seg.elf32_segment_body)) - ; ("Segment type: " ^ string_of_segment_type (fun _ -> "ABI specific") (fun _ -> "ABI specific") seg.elf32_segment_type) - ; ("Segment size: " ^ unsafe_hex_string_of_natural( 16) seg.elf32_segment_size) - ; ("Segment memory size: " ^ unsafe_hex_string_of_natural( 16) seg.elf32_segment_memsz) - ; ("Segment base address: " ^ unsafe_hex_string_of_natural( 16) seg.elf32_segment_base) - ; ("Segment physical address: " ^ unsafe_hex_string_of_natural( 16) seg.elf32_segment_paddr) - ; ("Segment flags: " ^ string_of_flags seg.elf32_segment_flags) - ]) - -(** [string_of_elf64_interpreted_segment seg] produces a string-based representation - * of interpreted segment [seg]. - *) -(*val string_of_elf64_interpreted_segment : elf64_interpreted_segment -> string*) -let string_of_elf64_interpreted_segment seg:string= - (unlines [ -("Body of length: " ^ unsafe_hex_string_of_natural( 16) (Byte_sequence.length0 seg.elf64_segment_body)) - ; ("Segment type: " ^ string_of_segment_type (fun _ -> "ABI specific") (fun _ -> "ABI specific") seg.elf64_segment_type) - ; ("Segment size: " ^ unsafe_hex_string_of_natural( 16) seg.elf64_segment_size) - ; ("Segment memory size: " ^ unsafe_hex_string_of_natural( 16) seg.elf64_segment_memsz) - ; ("Segment base address: " ^ unsafe_hex_string_of_natural( 16) seg.elf64_segment_base) - ; ("Segment physical address: " ^ unsafe_hex_string_of_natural( 16) seg.elf64_segment_paddr) - ; ("Segment flags: " ^ string_of_flags seg.elf64_segment_flags) - ]) diff --git a/lib/ocaml_rts/linksem/elf_memory_image.ml b/lib/ocaml_rts/linksem/elf_memory_image.ml deleted file mode 100644 index d408c358..00000000 --- a/lib/ocaml_rts/linksem/elf_memory_image.ml +++ /dev/null @@ -1,315 +0,0 @@ -(*Generated by Lem from elf_memory_image.lem.*) -open Lem_basic_classes -open Lem_function -open Lem_string -open Lem_tuple -open Lem_bool -open Lem_list -open Lem_sorting -open Lem_map -(*import Set*) -open Lem_num -open Lem_maybe -open Lem_assert_extra - -open Byte_sequence -open Default_printing -open Error -open Missing_pervasives -open Show -open Endianness - -open Elf_header -open Elf_file -open Elf_interpreted_section -open Elf_interpreted_segment -open Elf_section_header_table -open Elf_program_header_table -open Elf_symbol_table -open Elf_types_native_uint -open Elf_relocation -open String_table - -open Memory_image -open Abis - -type elf_memory_image = any_abi_feature annotated_memory_image - -let elf_section_is_special0 s f:bool= (not (Nat_big_num.equal s.elf64_section_type sht_progbits) - && not (Nat_big_num.equal s.elf64_section_type sht_nobits)) - -(*val noop_reloc : forall 'abifeature. natural -> ((maybe elf64_symbol_table_entry -> natural) * (annotated_memory_image 'abifeature -> maybe natural))*) -let noop_reloc0 r:((elf64_symbol_table_entry)option ->Nat_big_num.num)*('abifeature annotated_memory_image ->(Nat_big_num.num)option)= ((fun r_type ->Nat_big_num.of_int 8), (fun sym_val -> None)) - -let empty_elf_memory_image:(any_abi_feature)annotated_memory_image= ({ - elements = (Pmap.empty compare) - ; by_range = (Pset.empty (pairCompare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))) compare)) - ; by_tag = (Pset.empty (pairCompare compare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))))) -}) - -(* HMM. For the elf_ident, I don't really want to express it this way. - * I want something more bidirectional: something that can tell me - * not only that a given ident is valid for a given ABI, but also, - * to *construct* an ident for a given abstract ELF file satisfying x. - * This is very much like a lens. - * - * Similarly for relocs, I might want a way to map back to an allowable - * *concrete* representation, from some *abstract* description of the - * reloc's intent (i.e. a symbol binding: "point this reference at symbol - * Foo"), given the constraints imposed by the ABI (such as "use only - * RELA, not rel". FIXME: figure out how to lensify what we're doing. *) - -type elf_range_tag = any_abi_feature range_tag - -let null_section_header_table:elf_file_feature= (ElfSectionHeaderTable([])) -let null_program_header_table:elf_file_feature= (ElfProgramHeaderTable([])) -let null_elf_header:elf64_header= ({ - elf64_ident = ([]) - ; elf64_type = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_machine = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_version = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_entry = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_phoff = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_shoff = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_flags = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_ehsize = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_phentsize= (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_phnum = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_shentsize= (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_shnum = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_shstrndx = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - }) - -(* Here we build the image of a file in file offset space. - * To transform to memory space, we - * - * - switch positions to be addresses - * - switch lengths of nobits etc. to be memory lengths - * - PROBLEM: an offset might map to >1 virtual address. - * So we have to clone it as multiple elements. - * Each gets a label identifying the "file feature" it came from - * -- i.e. sections, ELF header, SHT and PHT are all file features. - * - PROBLEM: the memory image might only contain part of an element. - * We need to reflect this truncatedness somehow in the label. - * - * Is the offset-space view really useful? - * SORT OF: want to be able to make an image out of relocatable ELF files - * that have no address assignments or phdrs yet. - * AHA. NO. This is not an offset-space view; it's a sectionwise memory view. - * All allocatable sections become elements with Nothing as their address. - * The remainder of the ELF file *should* be represented as labels. - * But, hmm, some stuff like the ELF header and SHT will likely get discarded. - * - * In short, we should work entirely with memory space. - * Then - * - * - do we want to encode the aliasing of multiple virtual addresses - * down to single "features" in offset-space, like multiple mappings - * of the ELF header, say? - *) - -(*val offset_to_vaddr_mappings : elf64_file -> natural -> list (natural * elf64_interpreted_segment)*) -let offset_to_vaddr_mappings f off:(Nat_big_num.num*elf64_interpreted_segment)list= - (Lem_list.mapMaybe (fun ph -> - if Nat_big_num.greater_equal off ph.elf64_segment_offset - && Nat_big_num.less off (Nat_big_num.add ph.elf64_segment_base ph.elf64_segment_size) - then Some ( Nat_big_num.add ph.elf64_segment_base ( Nat_big_num.sub_nat off ph.elf64_segment_offset), ph) - else None - ) f.elf64_file_interpreted_segments) - -(*val gensym : string -> string*) -let gensym hint:string= hint (* FIXME: remember duplicates *) - -(*val extract_symbol : (elf64_symbol_table * string_table * natural) -> natural -> maybe (string * elf64_symbol_table_entry)*) -let extract_symbol symtab_triple symidx:(string*elf64_symbol_table_entry)option= - (let (symtab, strtab, scnidx) = symtab_triple - in - (match Ml_bindings.list_index_big_int symidx symtab with - Some ent -> - (match (get_string_at (Nat_big_num.of_string (Uint32.to_string ent.elf64_st_name)) strtab) with - Success str -> Some (str, ent) - | Fail _ -> Some ("", ent) (* ELF doesn't distinguish "no string" from "empty string" *) - ) - | None -> None - )) - -(*val extract_satisfying_symbols : (elf64_symbol_table * string_table * natural) -> - (elf64_symbol_table_entry -> bool) -> list (string * elf64_symbol_table_entry * natural (* scnidx *) * natural (* symidx *))*) -let extract_satisfying_symbols symtab_triple pred:(string*elf64_symbol_table_entry*Nat_big_num.num*Nat_big_num.num)list= - (let (symtab, strtab, scnidx) = symtab_triple - in - (*let _ = Missing_pervasives.errln ("extracting satisfying symbols from symtab index " ^ (show scnidx) ^ ", size " - ^ (show (length symtab)) ) - in*) - mapMaybei (fun symidx -> (fun ent -> - ((match (get_string_at (Nat_big_num.of_string (Uint32.to_string ent.elf64_st_name)) strtab) with - Success str -> - (* exclude those that don't match *) - if (pred ent) - then Some(str, ent, scnidx, symidx) - else None - | Fail s -> (*let _ = Missing_pervasives.errln ("couldn't get string from strtab of symtab with index " ^ (show scnidx) - ^ ": " ^ s) in *) - None - )) - )) symtab) - -(*val extract_all_symbols : (elf64_symbol_table * string_table * natural) -> list (string * elf64_symbol_table_entry * natural (* scnidx *) * natural (* symidx *))*) -let extract_all_symbols symtab_triple:(string*elf64_symbol_table_entry*Nat_big_num.num*Nat_big_num.num)list= (extract_satisfying_symbols symtab_triple (fun _ -> true)) - -let definitions_pred:elf64_symbol_table_entry ->bool= (fun ent -> not (Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string ent.elf64_st_shndx)) stn_undef)) -let references_pred:elf64_symbol_table_entry ->bool= (fun ent -> Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string ent.elf64_st_shndx)) stn_undef && (not (is_elf64_null_entry ent))) - -(*val extract_definitions_from_symtab_of_type : natural -> elf64_file -> list symbol_definition*) -let extract_definitions_from_symtab_of_type t e:(symbol_definition)list= - ((match (find_elf64_symtab_by_type t e >>= (fun symtab -> ( - let (allsyms : (string * elf64_symbol_table_entry * Nat_big_num.num (* scnidx *) * Nat_big_num.num (* symidx *)) list) - = (extract_satisfying_symbols symtab definitions_pred) - in - let (extracted : symbol_definition list) - = (mapMaybei (fun i -> (fun (str, ent, scnidx, symidx) -> Some { - def_symname = str - ; def_syment = ent - ; def_sym_scn = scnidx - ; def_sym_idx = symidx - ; def_linkable_idx =(Nat_big_num.of_int 0) - })) allsyms) - in return extracted - ))) with Fail _ -> [] | Success x -> x )) - -(*val extract_references_from_symtab_of_type : natural -> elf64_file -> list symbol_reference*) -let extract_references_from_symtab_of_type t e:(symbol_reference)list= - ((match (find_elf64_symtab_by_type t e >>= (fun symtab -> ( - let (allsyms : (string * elf64_symbol_table_entry * Nat_big_num.num (* scnidx *) * Nat_big_num.num (* symidx *)) list) - = (extract_satisfying_symbols symtab references_pred) - in - let (extracted : symbol_reference list) = - (mapMaybei (fun symidx -> (fun (str, ent, scnidx, symidx) -> Some { - ref_symname = str - ; ref_syment = ent - ; ref_sym_scn = scnidx - ; ref_sym_idx = symidx - })) allsyms) - in - (*let _ = Missing_pervasives.errs ("Extracted " ^ (show (length allsyms)) ^ " undefined references: " - ^ (show (List.map (fun (str, _, scnidx, symidx) -> (str, scnidx, symidx)) allsyms)) ^ "\n") -(* ^ " (syminds " - ^ (show (List.map (fun extracted -> extracted.ref_sym_idx) x)) ^ ", symnames " - ^ (show (List.map (fun extracted -> extracted.ref_symname) x)) ^ ")") *) - - in*) return extracted - ))) with Fail _ -> [] | Success x -> x )) - -(*val extract_all_relocs : string -> elf64_file -> list (natural (* scn *) * natural (* rel idx *) * natural (* rel src scn *) * elf64_relocation_a)*) -let extract_all_relocs fname1 e:(Nat_big_num.num*Nat_big_num.num*Nat_big_num.num*elf64_relocation_a)list= - (let (all_rel_sections : (Nat_big_num.num * elf64_interpreted_section) list) = (mapMaybei (fun i -> (fun isec1 -> - if Nat_big_num.equal isec1.elf64_section_type sht_rel then Some (i, isec1) else None - )) e.elf64_file_interpreted_sections) - in - (*let _ = Missing_pervasives.errln ("File " ^ fname ^ " has " ^ (show (length all_rel_sections)) ^ - " rel sections (indices " ^ (show (List.map (fun (scn, _) -> scn) all_rel_sections)) ^ ")") - in*) - let (all_rela_sections : (Nat_big_num.num * elf64_interpreted_section) list) = (mapMaybei (fun i -> (fun isec1 -> - if Nat_big_num.equal isec1.elf64_section_type sht_rela then Some (i, isec1) else None - )) e.elf64_file_interpreted_sections) - in - (*let _ = Missing_pervasives.errln ("File " ^ fname ^ " has " ^ (show (length all_rela_sections)) ^ - " rela sections (indices " ^ (show (List.map (fun (scn, _) -> scn) all_rela_sections)) ^ ")") - in*) - let rel_to_rela = (fun rel -> { - elf64_ra_offset = (rel.elf64_r_offset) - ; elf64_ra_info = (rel.elf64_r_info) - ; elf64_ra_addend = (Nat_big_num.to_int64(Nat_big_num.of_int 0)) - }) - in - let endian = (get_elf64_header_endianness e.elf64_file_header) - in - (* Build per-section lists of rels paired with their originating section id. - * We also pair each element with its index *in that section*, and then flatten - * the whole lot using mapConcat. *) - let (all_rels_list : (Nat_big_num.num * Nat_big_num.num * Nat_big_num.num * elf64_relocation_a) list) = (list_reverse_concat_map (fun (scn, isec1) -> - (match read_elf64_relocation_section isec1.elf64_section_size endian isec1.elf64_section_body - with - Success (relocs, _) -> - (*let _ = Missing_pervasives.errln ("Rel section with index " ^ (show scn) ^ " has " ^ (show (length relocs)) ^ - " entries") - in*) - mapMaybei (fun idx1 -> (fun rel -> Some (scn, idx1, isec1.elf64_section_info, rel_to_rela rel))) relocs - | Fail _ -> [] - )) all_rel_sections) - in - let (all_relas_list : (Nat_big_num.num * Nat_big_num.num * Nat_big_num.num * elf64_relocation_a) list) = (list_reverse_concat_map (fun (scn, isec1) -> - (match read_elf64_relocation_a_section isec1.elf64_section_size endian isec1.elf64_section_body - with - Success (relocs, _) -> - (*let _ = Missing_pervasives.errln ("Rela section with index " ^ (show scn) ^ " has " ^ (show (length relocs)) ^ - " entries") - in*) - mapMaybei (fun idx1 -> (fun rela -> Some (scn, idx1, isec1.elf64_section_info, rela))) relocs - | Fail _ -> [] - )) all_rela_sections) - in - List.rev_append (List.rev all_rels_list) all_relas_list) - -(*val extract_all_relocs_as_symbol_references : string -> elf64_file -> list symbol_reference_and_reloc_site*) -let extract_all_relocs_as_symbol_references fname1 e:(symbol_reference_and_reloc_site)list= -(let all_relocs = (extract_all_relocs fname1 e) - in - let all_symtab_triples_by_scnidx = (mapMaybei (fun scnidx -> (fun isec1 -> - if Nat_big_num.equal isec1.elf64_section_type sht_symtab - then - let found = (find_elf64_symbols_by_symtab_idx scnidx e) - in - (match found with - Fail _ -> None - | Success triple -> Some (scnidx, triple) - ) - else None - )) e.elf64_file_interpreted_sections) - in - let (all_extracted_symtabs_by_scnidx : ( (Nat_big_num.num, ( (string * elf64_symbol_table_entry * Nat_big_num.num (* scnidx *) * Nat_big_num.num (* symidx *))list))Pmap.map)) - = (List.fold_left (fun acc -> (fun (scnidx, triple) -> Pmap.add scnidx (extract_all_symbols triple) acc)) (Pmap.empty Nat_big_num.compare) all_symtab_triples_by_scnidx) - in - (*let _ = Missing_pervasives.errln ("All extracted symtabs by scnidx: " ^ (show (Set_extra.toList (Map.toSet all_extracted_symtabs_by_scnidx)))) - in*) - let ref_for_relocation_a_in_section_index = (fun rel_scn_idx -> (fun rel_idx -> (fun rela -> - let rela_isec = ((match Ml_bindings.list_index_big_int rel_scn_idx e.elf64_file_interpreted_sections with - Some x -> x - | None -> failwith "relocation references nonexistent section" - )) - in - let symtab_idx = (rela_isec.elf64_section_link) - in - (match Pmap.lookup symtab_idx all_extracted_symtabs_by_scnidx with - None -> failwith "referenced symtab does not exist" - | Some quads -> - let sym_idx = (get_elf64_relocation_a_sym rela) - in - let maybe_quad = (Ml_bindings.list_index_big_int sym_idx quads) - in - (match maybe_quad with - Some(symname, syment, scnidx, symidx) -> { - ref_symname = symname - ; ref_syment = syment - ; ref_sym_scn = symtab_idx - ; ref_sym_idx = sym_idx - } - | None -> failwith "reloc references symbol that does not exist" (*("reloc at index " ^ (show rel_idx) ^ " references symbol (index " ^ (show sym_idx) ^ - ") that does not exist: symtab (index " ^ (show symtab_idx) ^ ") has " ^ (show (length quads)) ^ " entries")*) - ) - ) - ))) - in - (*let _ = Missing_pervasives.errs ("Extracted " ^ (show (length all_relocs)) ^ " reloc references (rel_scn, rel_idx, src_scn): " - ^ (show (List.map (fun (rel_scn, rel_idx, srcscn, rela) -> (rel_scn, rel_idx, srcscn)) all_relocs)) ^ "\n") - in*) - Lem_list.map (fun (scn, idx1, srcscn, rela) -> { - ref = ( (* NOTE that a reference is not necessarily to an undefined symbol! *)ref_for_relocation_a_in_section_index scn idx1 rela) - ; maybe_reloc = (Some - { ref_relent = rela - ; ref_rel_scn = scn - ; ref_rel_idx = idx1 - ; ref_src_scn = srcscn (* what section does the reference come from? it's the 'info' link of the rel section header *) - }) - ; maybe_def_bound_to = None - }) all_relocs) diff --git a/lib/ocaml_rts/linksem/elf_memory_image_of_elf64_file.ml b/lib/ocaml_rts/linksem/elf_memory_image_of_elf64_file.ml deleted file mode 100644 index 66b996df..00000000 --- a/lib/ocaml_rts/linksem/elf_memory_image_of_elf64_file.ml +++ /dev/null @@ -1,563 +0,0 @@ -(*Generated by Lem from elf_memory_image_of_elf64_file.lem.*) -open Lem_basic_classes -open Lem_function -open Lem_string -open Lem_tuple -open Lem_bool -open Lem_list -open Lem_sorting -open Lem_map -(*import Set*) -open Lem_num -open Lem_maybe -open Lem_assert_extra - -open Byte_sequence -open Default_printing -open Error -open Missing_pervasives -open Show -open Endianness - -open Elf_header -open Elf_file -open Elf_interpreted_section -open Elf_interpreted_segment -open Elf_section_header_table -open Elf_program_header_table -open Elf_symbol_table -open Elf_types_native_uint -open Elf_relocation -open String_table - -open Memory_image -open Memory_image_orderings - -open Elf_memory_image - -(*val section_name_is_unique : string -> elf64_file -> bool*) -let section_name_is_unique name1 f:bool= - ((match mapMaybe (fun sec -> - if name1 = sec.elf64_section_name_as_string then Some sec else None - ) f.elf64_file_interpreted_sections - with - [_] -> true - | _ -> false - )) - -(*val create_unique_name_for_section_from_index : natural -> elf64_interpreted_section -> elf64_file -> string*) -let create_unique_name_for_section_from_index idx1 s f:string= - (let secname1 = (s.elf64_section_name_as_string) - in if section_name_is_unique secname1 f then secname1 else gensym secname1) - -(*val create_unique_name_for_common_symbol_from_linkable_name : string -> elf64_symbol_table_entry -> string -> elf64_file -> string*) -let create_unique_name_for_common_symbol_from_linkable_name fname1 syment symname f:string= -( - (* FIXME: uniqueness? I suppose file names are unique. How to avoid overlapping with - * section names? *)fname1 ^ ("_" ^ symname)) - -(*val get_unique_name_for_common_symbol_from_linkable_name : string -> elf64_symbol_table_entry -> string -> string*) -let get_unique_name_for_common_symbol_from_linkable_name fname1 syment symname:string= -( - (* FIXME: uniqueness? I suppose file names are unique. How to avoid overlapping with - * section names? *)fname1 ^ ("_" ^ symname)) - -(*val elf_memory_image_of_elf64_file : forall 'abifeature. abi 'abifeature -> string -> elf64_file -> elf_memory_image*) -let elf_memory_image_of_elf64_file a fname1 f:(Abis.any_abi_feature)annotated_memory_image= -( - (* Do we have program headers? This decides whether we choose a - * sectionwise or segmentwise view. *)(match f.elf64_file_program_header_table with - [] -> let extracted_symbols = (extract_definitions_from_symtab_of_type sht_symtab f) - in - let interpreted_sections_without_null = ((match f.elf64_file_interpreted_sections with - [] -> failwith "impossible: empty list of interpreted sections" - | null_entry :: more -> more - )) - in - let section_names_and_elements = (mapMaybei (fun i -> (fun isec1 -> - (* In principle, we can have unnamed sections. But - * don't add the dummy initial SHT entry. This is *not* in the - * list of interpreted sections. *) - if elf64_interpreted_section_equal isec1 null_elf64_interpreted_section then - (if Nat_big_num.equal i(Nat_big_num.of_int 0) then None else failwith "internal error: null interpreted section not at index 0") - else - if Nat_big_num.equal i(Nat_big_num.of_int 0) then failwith "internal error: non-null interpreted section at index 0" - else - let created_name = (create_unique_name_for_section_from_index i isec1 f) - in - (*let _ = errln ("In file " ^ fname ^ " created element name " ^ created_name ^ " for section idx " ^ (show i) ^ ", name " ^ - isec.elf64_section_name_as_string) - in*) - Some (created_name, { - startpos = None - ; length1 = (Some isec1.elf64_section_size) - ; contents = (byte_pattern_of_byte_sequence isec1.elf64_section_body) - }) - )) f.elf64_file_interpreted_sections) - in - let common_symbols = (List.filter (fun x -> Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string (x.def_syment.elf64_st_shndx))) shn_common) extracted_symbols) - in - (*let _ = Missing_pervasives.errln ("Found " ^ (show (length common_symbols)) ^ " common symbols in file " ^ fname) - in*) - let common_symbol_names_and_elements = (mapMaybei (fun i -> (fun isym -> - let symlen = (Ml_bindings.nat_big_num_of_uint64 isym.def_syment.elf64_st_size) - in - Some (get_unique_name_for_common_symbol_from_linkable_name fname1 isym.def_syment isym.def_symname, { - startpos = None - ; length1 = (Some symlen) - ; contents = (Missing_pervasives.replicate0 symlen None) - }) - )) common_symbols) - in - let all_names_and_elements = (List.rev_append (List.rev section_names_and_elements) common_symbol_names_and_elements) - in - (* -- annotations are reloc sites, symbol defs, ELF sections/segments/headers, PLT/GOT/... - * Since we stripped the null SHT entry, mapMaybei would ideally index from one. We add one. *) - let (elf_sections : ( element_range option * elf_range_tag) list) = (mapMaybei (fun secidx_minus_one -> ( - (fun (isec1, (secname1, _)) -> - let (r : element_range option) = (Some(secname1, (Nat_big_num.of_int 0, isec1.elf64_section_size))) - in - Some (r, FileFeature(ElfSection( Nat_big_num.add secidx_minus_one(Nat_big_num.of_int 1), isec1))) - ))) - (list_combine interpreted_sections_without_null section_names_and_elements)) - in - let (symbol_defs : ( element_range option * elf_range_tag) list) = (mapMaybe - (fun x -> - let section_num = (Nat_big_num.of_string (Uint32.to_string x.def_syment.elf64_st_shndx)) - in - let labelled_range = - (if Nat_big_num.equal section_num shn_abs then - (* We have an annotation that doesn't apply to any range. - * That's all right -- that's why the range is a maybe. *) - None - else if Nat_big_num.equal section_num shn_common then - (* Each common symbol becomes its own elemenet (\approx section). - * We label *that element* with a (coextensive) symbol definition. *) - let element_name = (get_unique_name_for_common_symbol_from_linkable_name - fname1 x.def_syment x.def_symname) - in - Some(element_name, (Nat_big_num.of_int 0, Ml_bindings.nat_big_num_of_uint64 x.def_syment.elf64_st_size)) - else - let (section_name, _) = ((match Ml_bindings.list_index_big_int ( Nat_big_num.sub_nat section_num(Nat_big_num.of_int 1)) section_names_and_elements with - Some x -> x - | None -> failwith ("symbol " ^ (x.def_symname ^ " references nonexistent section")) - )) - in - Some(section_name, (Ml_bindings.nat_big_num_of_uint64 x.def_syment.elf64_st_value, Ml_bindings.nat_big_num_of_uint64 x.def_syment.elf64_st_size))) - in - Some (labelled_range, SymbolDef(x)) - ) - (extract_definitions_from_symtab_of_type sht_symtab f)) - in - (* FIXME: should a common symbol be a reference too? - * I prefer to think of common symbols as mergeable sections. - * Under this interpretation, there's no need for a reference. - * BUT the GC behaviour might be different! What happens if - * a common symbol is not referenced? *) - let (symbol_refs : ( element_range option * elf_range_tag) list) = (mapMaybe - (fun (x : symbol_reference) -> - Some (None, SymbolRef({ ref = x; maybe_reloc = None; maybe_def_bound_to = None })) - ) - (extract_references_from_symtab_of_type sht_symtab f)) - in - let (all_reloc_sites : (element_range * elf_range_tag) list) = (Lem_list.map - (fun (x : symbol_reference_and_reloc_site) -> - let rel = ((match x.maybe_reloc with - Some rel -> rel - | None -> failwith "impossible: reloc site has no reloc" - )) - in - let (section_name, _) = ((match Ml_bindings.list_index_big_int ( Nat_big_num.sub_nat rel.ref_src_scn(Nat_big_num.of_int 1)) section_names_and_elements with - Some y -> y - | None -> failwith "relocs came from nonexistent section" - )) - in - let (_, applyfn) = (a.reloc (get_elf64_relocation_a_type rel.ref_relent)) - in - let (width, calcfn) = (applyfn (get_empty_memory_image ())(Nat_big_num.of_int 0) x) - (* GAH. We don't have an image. - If we pass an empty memory image, will we fail? Need to make it work *) - in - (* FIXME: for copy relocs, the size depends on the *definition*. - AHA! a copy reloc always *has* a symbol definition locally; it just gets its *value* - from the shared object's definition. - In other words, a copy reloc always references a defined symbol, and the amount - copied is the minimum of that symbol's size and the overridden (copied-from .so)'s - symbol's size. *) - let (offset : Uint64.uint64) = (rel.ref_relent.elf64_ra_offset) - in - ((section_name, (Ml_bindings.nat_big_num_of_uint64 offset, width)), SymbolRef(x)) - ) - (extract_all_relocs_as_symbol_references fname1 f)) - in - let all_reloc_pairs = (Lem_list.map (fun (el_range, r_tag) -> (Some el_range, r_tag)) all_reloc_sites) - in - let reloc_as_triple = (fun ((_ : bool Memory_image.range_tag), (x : bool Memory_image.range_tag)) -> ((match x with - SymbolRef(r) -> (match r.maybe_reloc with - Some rel -> (rel.ref_rel_scn, rel.ref_rel_idx, rel.ref_src_scn) - | None -> failwith "impossible: " - ) - | _ -> failwith "unexpected tag" - ))) - in - (*let _ = Missing_pervasives.errln ("Extracted " ^ (show (length all_reloc_sites)) ^ " reloc site tags from " - ^ "file " ^ fname ^ ": " ^ (show (List.map reloc_as_triple all_reloc_sites))) - in*) - let retrieved_reloc_sites = (Multimap.lookupBy0 - (instance_Basic_classes_Ord_Memory_image_range_tag_dict - Abis.instance_Basic_classes_Ord_Abis_any_abi_feature_dict) (instance_Basic_classes_Ord_tup2_dict - Lem_string_extra.instance_Basic_classes_Ord_string_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_Num_natural_dict - instance_Basic_classes_Ord_Num_natural_dict)) instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict)) (Memory_image_orderings.tagEquiv - Abis.instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict) - (SymbolRef(null_symbol_reference_and_reloc_site)) - (let ((fst : (string * Memory_image.range) list), (snd : ( Abis.any_abi_feature Memory_image.range_tag) list)) = (List.split all_reloc_sites) in (Pset.from_list (pairCompare compare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))) (list_combine snd fst)))) - in - (*let _ = Missing_pervasives.errln ("Re-reading: retrieved " ^ (show (length retrieved_reloc_sites)) ^ " reloc site tags from " - ^ "file " ^ fname ^ ": " ^ (show (List.map reloc_as_triple (let (fst, snd) = unzip retrieved_reloc_sites in zip snd fst)))) - in*) - let elf_header = ([(Some("header", (Nat_big_num.of_int 0, Nat_big_num.of_string (Uint32.to_string f.elf64_file_header.elf64_ehsize))), FileFeature(ElfHeader(f.elf64_file_header)))]) - in - (*let _ = Missing_pervasives.errln ("ELF header contributes " ^ (show (List.length elf_header)) ^ " annotations.") - in*) - let all_annotations_list = (List.rev_append (List.rev (List.rev_append (List.rev (List.rev_append (List.rev (List.rev_append (List.rev all_reloc_pairs) symbol_refs)) symbol_defs)) elf_sections)) elf_header) - in - let all_annotations_length = (List.length all_annotations_list) - in - (*let _ = Missing_pervasives.errln ("total annotations: " ^ (show all_annotations_length)) - in*) - let all_annotations = (Pset.from_list (pairCompare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))) compare) all_annotations_list) - in - let (apply_content_relocations : string -> byte_pattern -> byte_pattern) = (fun (name1 : string) -> (fun content -> - let this_element_reloc_sites = (List.filter (fun ((n, range1), _) -> name1 = n) all_reloc_sites) - in - let ((this_element_name_and_reloc_ranges : (string * (Nat_big_num.num * Nat_big_num.num)) list), _) = (List.split this_element_reloc_sites) - in - let (this_element_reloc_ranges : (Nat_big_num.num * Nat_big_num.num) list) = (snd (List.split this_element_name_and_reloc_ranges)) - in - let (all_ranges_expanded : bool list) = (expand_unsorted_ranges this_element_reloc_ranges (Missing_pervasives.length content) []) - in - relax_byte_pattern content all_ranges_expanded - )) - in - let new_elements_list = (Lem_list.map (fun (name1, element1) -> - (* We can now mark the relocation sites in the section contents as "subject to change". *) - ( - name1, - { - startpos = (element1.startpos) - ; length1 = (element1.length1) - ; contents = -( - (*let _ = errln ("Reloc-relaxing section " ^ name ^ " in file " ^ fname ^ ": before, first 20 bytes: " ^ - (show (take 20 element.contents))) - in*)let relaxed = (apply_content_relocations name1 element1.contents) - in - (*let _ = errln ("After, first 20 bytes: " ^ (show (take 20 relaxed))) - in*) - relaxed) - - } - ) - ) all_names_and_elements) - in - (* - List.foldr (fun acc -> (fun element.contents this_element_reloc_ranges - let (expand_and_relax : list (maybe byte) -> (natural * natural) -> list (maybe byte)) = fun pat -> (fun r -> ( - relax_byte_pattern pat (expand_ranges r) - )) - in*) - { - elements = (Lem_map.fromList - (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) new_elements_list) - (* : memory_image -- the image elements, without annotation, i.e. - a map from string to (startpos, length, contents) - -- an element is the ELF header, PHT, SHT, section or segment - -- exploit the fact that section names beginning `.' are reserved, and - the reserved ones don't use caps: ".PHT", ".SHT", ".HDR" - -- what about ambiguous section names? use ".GENSYM_<...>" perhaps - *) - ; by_range = all_annotations - ; by_tag = (let (fst, snd) = (List.split all_annotations_list) in (Pset.from_list (pairCompare compare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare)))) (list_combine snd fst))) - (* : multimap (elf_range_tag 'symdef 'reloc 'filefeature 'abifeature) (string * range) - -- annotations by *) - } - | pht -> let segment_names_and_images = (mapMaybei (fun i -> (fun seg -> - Some((gensym (hex_string_of_natural seg.elf64_segment_base) ^ ("_" ^ (hex_string_of_natural seg.elf64_segment_type))), - { - startpos = (Some seg.elf64_segment_base) - ; length1 = (Some seg.elf64_segment_memsz) - ; contents = ([]) (* FIXME *) - }) - )) f.elf64_file_interpreted_segments) - in - (* let annotations = *) - { - elements = (Lem_map.fromList - (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) segment_names_and_images) (* : memory_image -- the image elements, without annotation, i.e. - a map from string to (startpos, length, contents) - -- an element is the ELF header, PHT, SHT, section or segment - -- exploit the fact that section names beginning `.' are reserved, and - the reserved ones don't use caps: ".PHT", ".SHT", ".HDR" - -- what about ambiguous section names? use ".GENSYM_<...>" perhaps - *) - ; by_range = (Pset.from_list (pairCompare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))) compare) []) - (* : map element_range (list (elf_range_tag 'symdef 'reloc 'filefeature 'abifeature)) - -- annotations are reloc sites, symbol defs, ELF sections/segments/headers, PLT/GOT/... *) - ; by_tag = (Pset.from_list (pairCompare compare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare)))) []) - (* : multimap (elf_range_tag 'symdef 'reloc 'filefeature 'abifeature) (string * range) - -- annotations by *) - } - - )) - -(*val elf_memory_image_header : elf_memory_image -> elf64_header*) -let elf_memory_image_header img2:elf64_header= - ((match unique_tag_matching - Abis.instance_Basic_classes_Ord_Abis_any_abi_feature_dict Abis.instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict (FileFeature(ElfHeader(null_elf_header))) img2 with - FileFeature(ElfHeader(x)) -> x - | _ -> failwith "impossible: no header" - )) - -(*val elf_memory_image_sht : elf_memory_image -> maybe elf64_section_header_table*) -let elf_memory_image_sht img2:((elf64_section_header_table_entry)list)option= - ((match unique_tag_matching - Abis.instance_Basic_classes_Ord_Abis_any_abi_feature_dict Abis.instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict (FileFeature(null_section_header_table)) img2 with - FileFeature(ElfSectionHeaderTable(x)) -> Some x - | _ -> None - )) - -(*val elf_memory_image_section_ranges : elf_memory_image -> (list elf_range_tag * list element_range)*) -let elf_memory_image_section_ranges img2:((Abis.any_abi_feature)range_tag)list*(element_range)list= -( - (* find all element ranges labelled as ELF sections *)let tagged_ranges = (tagged_ranges_matching_tag - Abis.instance_Basic_classes_Ord_Abis_any_abi_feature_dict Abis.instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict (FileFeature(ElfSection(Nat_big_num.of_int 0, null_elf64_interpreted_section))) img2) - in - let (tags, maybe_ranges) = (List.split tagged_ranges) - in - (tags, make_ranges_definite maybe_ranges)) - -(*val elf_memory_image_section_by_index : natural -> elf_memory_image -> maybe elf64_interpreted_section*) -let elf_memory_image_section_by_index idx1 img2:(elf64_interpreted_section)option= -( - (* find all element ranges labelled as ELF sections *)let (allSectionTags, allSectionElementRanges) = (elf_memory_image_section_ranges img2) - in - let matches = (mapMaybei (fun i -> (fun tag -> (match tag with - FileFeature(ElfSection(itsIdx, s)) -> if Nat_big_num.equal itsIdx idx1 then Some s else None - | _ -> failwith "impossible" - ))) allSectionTags) - in - (match matches with - [] -> None - | [x] -> Some x - | x -> failwith ("impossible: more than one ELF section with same index" (*"(" ^ (show idx) ^ ")"*)) - )) - -(*val elf_memory_image_element_coextensive_with_section : natural -> elf_memory_image -> maybe string*) -let elf_memory_image_element_coextensive_with_section idx1 img2:(string)option= -( - (* find all element ranges labelled as ELF sections *)let (allSectionTags, allSectionElementRanges) = (elf_memory_image_section_ranges img2) - in - let matches = (mapMaybei (fun i -> (fun (tag, (elName, (rangeStart, rangeLen))) -> (match tag with - FileFeature(ElfSection(itsIdx, s)) -> - let el_rec = ((match Pmap.lookup elName img2.elements with - Some x -> x - | None -> failwith "impossible: element not found" - )) - in - let size_matches = -( - (* HMM. This is complicated. Generally we like to ignore - * isec fields that are superseded by memory_image fields, - * here the element length. But we want to catch the case - * where there's an inconsistency, and we *might* want to allow the - * case where the element length is still vague (Nothing). *)let range_len_matches_sec = ( Nat_big_num.equal rangeLen s.elf64_section_size) - in - let sec_matches_element_len = ( (Lem.option_equal Nat_big_num.equal(Some(s.elf64_section_size)) el_rec.length1)) - in - let range_len_matches_element_len = ( (Lem.option_equal Nat_big_num.equal(Some(rangeLen)) el_rec.length1)) - in - (* If any pair are unequal, then warn. *) - (*let _ = - if (range_len_matches_sec <> sec_matches_element_len - || sec_matches_element_len <> range_len_matches_element_len - || range_len_matches_sec <> range_len_matches_element_len) - then errln ("Warning: section lengths do not agree: " ^ s.elf64_section_name_as_string) - else () - in*) - range_len_matches_element_len) - in - if Nat_big_num.equal itsIdx idx1 && (Nat_big_num.equal rangeStart(Nat_big_num.of_int 0) - && size_matches) - then - (* *) - (* Sanity check: does the *) - Some elName - else None - | _ -> failwith "impossible" - ))) (list_combine allSectionTags allSectionElementRanges)) - in - (match matches with - [] -> None - | [x] -> Some x - | xs -> failwith ("impossible: more than one ELF section coextensive with section" ^ ((Nat_big_num.to_string idx1) ^ (", names: " - ^ (string_of_list - instance_Show_Show_string_dict xs)))) - )) - - -(*val name_of_elf_interpreted_section : - elf64_interpreted_section -> elf64_interpreted_section -> maybe string*) -let name_of_elf_interpreted_section s shstrtab:(string)option= - ((match get_string_at s.elf64_section_name (string_table_of_byte_sequence shstrtab.elf64_section_body) with - Success(x) -> Some x - | Fail(e) -> None - )) - -(*val elf_memory_image_sections_with_indices : elf_memory_image -> list (elf64_interpreted_section * natural)*) -let elf_memory_image_sections_with_indices img2:(elf64_interpreted_section*Nat_big_num.num)list= -( - (* We have to get all sections and their names, - * because section names need not be unique. *)let ((all_section_tags : elf_range_tag list), (all_section_ranges : element_range list)) - = (elf_memory_image_section_ranges img2) - in - Lem_list.map (fun tag -> - (match tag with - FileFeature(ElfSection(idx1, i)) -> (i, idx1) - | _ -> failwith "impossible: non-section in list of sections" - )) all_section_tags) - -(*val elf_memory_image_sections : elf_memory_image -> list elf64_interpreted_section*) -let elf_memory_image_sections img2:(elf64_interpreted_section)list= - (let (secs, _) = (List.split (elf_memory_image_sections_with_indices img2)) - in secs) - -(*val elf_memory_image_sections_with_name : string -> elf_memory_image -> list elf64_interpreted_section*) -let elf_memory_image_sections_with_name name1 img2:(elf64_interpreted_section)list= - (let all_interpreted_sections = (elf_memory_image_sections img2) - in - let maybe_shstrtab = (elf_memory_image_section_by_index (Nat_big_num.of_string (Uint32.to_string ((elf_memory_image_header img2).elf64_shstrndx))) img2) - in - let shstrtab = ((match maybe_shstrtab with - None -> failwith "no shtstrtab" - | Some x -> x - )) - in - let all_section_names = (Lem_list.map (fun i -> - let (stringtab : string_table) = (string_table_of_byte_sequence (shstrtab.elf64_section_body)) in - (match get_string_at i.elf64_section_name stringtab with - Fail _ -> None - | Success x -> Some x - )) all_interpreted_sections) - in - mapMaybe (fun (n, i) -> if (Lem.option_equal (=) (Some(name1)) n) then Some i else None) (list_combine all_section_names all_interpreted_sections)) -(* -val elf_memory_image_unique_section_with_name : string -> elf_memory_image -> elf64_interpreted_section -let elf_memory_image_unique_section_with_name name img = - match Map.lookup name img.image with - Just el -> match el with - FileFeature(ElfSection(_, x)) -> x - | _ -> failwith "impossible: section name does not name a section" - end - | - | Nothing -> failwith ("no section named '" ^ name ^ "' but asserted unique") - end -*) - -(* FIXME: delete these symbol functions, because Memory_image_orderings - * has generic ones. *) - -(*val elf_memory_image_symbol_def_ranges : elf_memory_image -> (list elf_range_tag * list (maybe element_range))*) -let elf_memory_image_symbol_def_ranges img2:((Abis.any_abi_feature)range_tag)list*((element_range)option)list= -( - (* find all element ranges labelled as ELF symbols *)let (tags, maybe_ranges) = (List.split ( - tagged_ranges_matching_tag - Abis.instance_Basic_classes_Ord_Abis_any_abi_feature_dict Abis.instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict (SymbolDef(null_symbol_definition)) img2 - )) - in - (* some symbols, specifically ABS symbols, needn't label a range. *) - (tags, maybe_ranges)) - -(*val name_of_symbol_def : symbol_definition -> string*) -let name_of_symbol_def0 sym:string= (sym.def_symname) - -(*val elf_memory_image_defined_symbols_and_ranges : elf_memory_image -> list ((maybe element_range) * symbol_definition)*) -let elf_memory_image_defined_symbols_and_ranges img2:((element_range)option*symbol_definition)list= - (Memory_image_orderings.defined_symbols_and_ranges - Abis.instance_Basic_classes_Ord_Abis_any_abi_feature_dict Abis.instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict img2) - -(*val elf_memory_image_defined_symbols : elf_memory_image -> list symbol_definition*) -let elf_memory_image_defined_symbols img2:(symbol_definition)list= - (let ((all_symbol_tags : elf_range_tag list), (all_symbol_ranges : ( element_range option) list)) - = (elf_memory_image_symbol_def_ranges img2) - in - Lem_list.mapMaybe (fun tag -> - (match tag with - SymbolDef(ent) -> Some ent - | _ -> failwith "impossible: non-symbol def in list of symbol defs" - )) all_symbol_tags) - -(* -val elf_memory_image_symbols_with_name : string -> elf_memory_image -> list symbol_definition -let elf_memory_image_symbols_with_name name img = - let all_interpreted_sections = elf_memory_image_sections img - in - let maybe_shstrtab = elf_memory_image_section_by_index (natural_of_elf64_half ((elf_memory_image_header img).elf64_shstrndx)) img - in - let shstrtab = match maybe_shstrtab with - Nothing -> failwith "no shtstrtab" - | Just x -> x - end - in - let all_section_names = List.map (fun i -> - let (stringtab : string_table) = string_table_of_byte_sequence (shstrtab.elf64_section_body) in - match get_string_at i.elf64_section_name stringtab with - Fail _ -> Nothing - | Success x -> Just x - end) all_interpreted_sections - in - mapMaybe (fun (n, i) -> if Just(name) = n then Just i else Nothing) (zip all_section_names all_interpreted_sections) -*) -(* -val elf_memory_image_unique_symbol_with_name : string -> elf_memory_image -> symbol_def -let elf_memory_image_unique_symbol_with_name name img = - match Map.lookup name img.image with - Just el -> match el with - FileFeature(ElfSection(_, x)) -> x - | _ -> failwith "impossible: section name does not name a section" - end - | - | Nothing -> failwith ("no section named '" ^ name ^ "' but asserted unique") - end -*) - - -(*val name_of_elf_section : elf64_interpreted_section -> elf_memory_image -> maybe string*) -let name_of_elf_section sec img2:(string)option= -( - (* let shstrndx = natural_of_elf64_half ((elf_memory_image_header img).elf64_shstrndx) - in - match elf_memory_image_section_by_index shstrndx img with - Nothing -> Nothing - | Just shstrtab -> name_of_elf_interpreted_section sec shstrtab - end *)Some sec.elf64_section_name_as_string) - -(*val name_of_elf_element : elf_file_feature -> elf_memory_image -> maybe string*) -let name_of_elf_element feature img2:(string)option= - ((match feature with - ElfSection(_, sec) -> name_of_elf_section sec img2 - | _ -> None (* FIXME *) - )) - -(*val get_unique_name_for_section_from_index : natural -> elf64_interpreted_section -> elf_memory_image -> string*) -let get_unique_name_for_section_from_index idx1 isec1 img2:string= -( - (* Don't call gensym just to retrieve the name *)(match elf_memory_image_element_coextensive_with_section idx1 img2 with - Some n -> n - | None -> failwith "section does not have an element name" - )) diff --git a/lib/ocaml_rts/linksem/elf_note.ml b/lib/ocaml_rts/linksem/elf_note.ml deleted file mode 100644 index f9965d68..00000000 --- a/lib/ocaml_rts/linksem/elf_note.ml +++ /dev/null @@ -1,196 +0,0 @@ -(*Generated by Lem from elf_note.lem.*) -(** [elf_note] contains data types and functions for interpreting the .note - * section/segment of an ELF file, and extracting information from that - * section/segment. - *) - -open Lem_basic_classes -open Lem_list -open Lem_num -open Lem_string - -open Byte_sequence -open Endianness -open Error -open Missing_pervasives -open Show - -open Elf_program_header_table -open Elf_section_header_table -open Elf_types_native_uint - -(** [elf32_note] represents the contents of a .note section or segment. - *) -type elf32_note = - { elf32_note_namesz : Uint32.uint32 (** The size of the name field. *) - ; elf32_note_descsz : Uint32.uint32 (** The size of the description field. *) - ; elf32_note_type : Uint32.uint32 (** The type of the note. *) - ; elf32_note_name : char list (** The list of bytes (of length indicated above) corresponding to the name string. *) - ; elf32_note_desc : char list (** The list of bytes (of length indicated above) corresponding to the desc string. *) - } - -(** [elf64_note] represents the contents of a .note section or segment. - *) -type elf64_note = - { elf64_note_namesz : Uint64.uint64 (** The size of the name field. *) - ; elf64_note_descsz : Uint64.uint64 (** The size of the description field. *) - ; elf64_note_type : Uint64.uint64 (** The type of the note. *) - ; elf64_note_name : char list (** The list of bytes (of length indicated above) corresponding to the name string. *) - ; elf64_note_desc : char list (** The list of bytes (of length indicated above) corresponding to the desc string. *) - } - -(** [read_elf32_note endian bs0] transcribes an ELF note section from byte - * sequence [bs0] assuming endianness [endian]. May fail if transcription fails - * (i.e. if the byte sequence is not sufficiently long). - *) -(*val read_elf32_note : endianness -> byte_sequence -> error (elf32_note * byte_sequence)*) -let read_elf32_note endian bs0:(elf32_note*byte_sequence)error= - (read_elf32_word endian bs0 >>= (fun (namesz, bs0) -> - read_elf32_word endian bs0 >>= (fun (descsz, bs0) -> - read_elf32_word endian bs0 >>= (fun (typ, bs0) -> - repeatM' (Nat_big_num.of_string (Uint32.to_string namesz)) bs0 read_char >>= (fun (name1, bs0) -> - repeatM' (Nat_big_num.of_string (Uint32.to_string descsz)) bs0 read_char >>= (fun (desc, bs0) -> - return ({ elf32_note_namesz = namesz; elf32_note_descsz = descsz; - elf32_note_type = typ; elf32_note_name = name1; elf32_note_desc = desc }, - bs0))))))) - -(** [read_elf64_note endian bs0] transcribes an ELF note section from byte - * sequence [bs0] assuming endianness [endian]. May fail if transcription fails - * (i.e. if the byte sequence is not sufficiently long). - *) -(*val read_elf64_note : endianness -> byte_sequence -> error (elf64_note * byte_sequence)*) -let read_elf64_note endian bs0:(elf64_note*byte_sequence)error= - (read_elf64_xword endian bs0 >>= (fun (namesz, bs0) -> - read_elf64_xword endian bs0 >>= (fun (descsz, bs0) -> - read_elf64_xword endian bs0 >>= (fun (typ, bs0) -> - repeatM' (Ml_bindings.nat_big_num_of_uint64 namesz) bs0 read_char >>= (fun (name1, bs0) -> - repeatM' (Ml_bindings.nat_big_num_of_uint64 descsz) bs0 read_char >>= (fun (desc, bs0) -> - return ({ elf64_note_namesz = namesz; elf64_note_descsz = descsz; - elf64_note_type = typ; elf64_note_name = name1; elf64_note_desc = desc }, - bs0))))))) - -(** [obtain_elf32_note_sections endian sht bs0] returns all note sections present - * in an ELF file, as indicated by the file's section header table [sht], reading - * them from byte sequence [bs0] assuming endianness [endian]. May fail if - * transcription of a note section fails. - *) -(*val obtain_elf32_note_sections : endianness -> elf32_section_header_table -> - byte_sequence -> error (list elf32_note)*) -let obtain_elf32_note_sections endian sht bs0:((elf32_note)list)error= - (let note_sects = -(List.filter (fun x -> - x.elf32_sh_type = Uint32.of_string (Nat_big_num.to_string sht_note) - ) sht) - in - mapM (fun x -> - let offset = (Nat_big_num.of_string (Uint32.to_string x.elf32_sh_offset)) in - let size2 = (Nat_big_num.of_string (Uint32.to_string x.elf32_sh_size)) in - Byte_sequence.offset_and_cut offset size2 bs0 >>= (fun rel -> - read_elf32_note endian rel >>= (fun (note, _) -> - return note)) - ) note_sects) - -(** [obtain_elf64_note_sections endian sht bs0] returns all note sections present - * in an ELF file, as indicated by the file's section header table [sht], reading - * them from byte sequence [bs0] assuming endianness [endian]. May fail if - * transcription of a note section fails. - *) -(*val obtain_elf64_note_sections : endianness -> elf64_section_header_table -> - byte_sequence -> error (list elf64_note)*) -let obtain_elf64_note_sections endian sht bs0:((elf64_note)list)error= - (let note_sects = -(List.filter (fun x -> - x.elf64_sh_type = Uint32.of_string (Nat_big_num.to_string sht_note) - ) sht) - in - mapM (fun x -> - let offset = (Nat_big_num.of_string (Uint64.to_string x.elf64_sh_offset)) in - let size2 = (Ml_bindings.nat_big_num_of_uint64 x.elf64_sh_size) in - Byte_sequence.offset_and_cut offset size2 bs0 >>= (fun rel -> - read_elf64_note endian rel >>= (fun (note, _) -> - return note)) - ) note_sects) - -(** [obtain_elf32_note_segments endian pht bs0] returns all note segments present - * in an ELF file, as indicated by the file's program header table [pht], reading - * them from byte sequence [bs0] assuming endianness [endian]. May fail if - * transcription of a note section fails. - *) -(*val obtain_elf32_note_segments : endianness -> elf32_program_header_table -> - byte_sequence -> error (list elf32_note)*) -let obtain_elf32_note_segments endian pht bs0:((elf32_note)list)error= - (let note_segs = -(List.filter (fun x -> - x.elf32_p_type = Uint32.of_string (Nat_big_num.to_string elf_pt_note) - ) pht) - in - mapM (fun x -> - let offset = (Nat_big_num.of_string (Uint32.to_string x.elf32_p_offset)) in - let size2 = (Nat_big_num.of_string (Uint32.to_string x.elf32_p_filesz)) in - Byte_sequence.offset_and_cut offset size2 bs0 >>= (fun rel -> - read_elf32_note endian rel >>= (fun (note, _) -> - return note)) - ) note_segs) - -(** [obtain_elf64_note_segments endian pht bs0] returns all note segments present - * in an ELF file, as indicated by the file's program header table [pht], reading - * them from byte sequence [bs0] assuming endianness [endian]. May fail if - * transcription of a note section fails. - *) -(*val obtain_elf64_note_segments : endianness -> elf64_program_header_table -> - byte_sequence -> error (list elf64_note)*) -let obtain_elf64_note_segments endian pht bs0:((elf64_note)list)error= - (let note_segs = -(List.filter (fun x -> - x.elf64_p_type = Uint32.of_string (Nat_big_num.to_string elf_pt_note) - ) pht) - in - mapM (fun x -> - let offset = (Nat_big_num.of_string (Uint64.to_string x.elf64_p_offset)) in - let size2 = (Ml_bindings.nat_big_num_of_uint64 x.elf64_p_filesz) in - Byte_sequence.offset_and_cut offset size2 bs0 >>= (fun rel -> - read_elf64_note endian rel >>= (fun (note, _) -> - return note)) - ) note_segs) - -(** [obtain_elf32_note_section_and_segments endian pht sht bs0] returns all note - * sections and segments present in an ELF file, as indicated by the file's - * program header table [pht] and section header table [sht], reading - * them from byte sequence [bs0] assuming endianness [endian]. May fail if - * transcription of a note section or segment fails. - *) -(*val obtain_elf32_note_section_and_segments : endianness -> elf32_program_header_table -> - elf32_section_header_table -> byte_sequence -> error (list elf32_note)*) -let obtain_elf32_note_section_and_segments endian pht sht bs0:((elf32_note)list)error= - (obtain_elf32_note_segments endian pht bs0 >>= (fun pht_notes -> - obtain_elf32_note_sections endian sht bs0 >>= (fun sht_notes -> - return ( List.rev_append (List.rev pht_notes) sht_notes)))) - -(** [obtain_elf64_note_section_and_segments endian pht sht bs0] returns all note - * sections and segments present in an ELF file, as indicated by the file's - * program header table [pht] and section header table [sht], reading - * them from byte sequence [bs0] assuming endianness [endian]. May fail if - * transcription of a note section or segment fails. - *) -(*val obtain_elf64_note_section_and_segments : endianness -> elf64_program_header_table -> - elf64_section_header_table -> byte_sequence -> error (list elf64_note)*) -let obtain_elf64_note_section_and_segments endian pht sht bs0:((elf64_note)list)error= - (obtain_elf64_note_segments endian pht bs0 >>= (fun pht_notes -> - obtain_elf64_note_sections endian sht bs0 >>= (fun sht_notes -> - return ( List.rev_append (List.rev pht_notes) sht_notes)))) - -(** [name_string_of_elf32_note note] extracts the name string of an ELF note - * section, interpreting the section's uninterpreted name field as a string. - *) -(*val name_string_of_elf32_note : elf32_note -> string*) -let name_string_of_elf32_note note:string= - (let bs0 = (Byte_sequence.from_byte_lists [note.elf32_note_name]) in - Byte_sequence.string_of_byte_sequence bs0) - -(** [name_string_of_elf64_note note] extracts the name string of an ELF note - * section, interpreting the section's uninterpreted name field as a string. - *) -(*val name_string_of_elf64_note : elf64_note -> string*) -let name_string_of_elf64_note note:string= - (let bs0 = (Byte_sequence.from_byte_lists [note.elf64_note_name]) in - Byte_sequence.string_of_byte_sequence bs0) diff --git a/lib/ocaml_rts/linksem/elf_program_header_table.ml b/lib/ocaml_rts/linksem/elf_program_header_table.ml deleted file mode 100644 index 6afe4d53..00000000 --- a/lib/ocaml_rts/linksem/elf_program_header_table.ml +++ /dev/null @@ -1,605 +0,0 @@ -(*Generated by Lem from elf_program_header_table.lem.*) -(** [elf_program_header_table] contains type, functions and other definitions - * for working with program header tables and their entries and ELF segments. - * Related files are [elf_interpreted_segments] which extracts information - * derived from PHTs presented in this file and converts it into a more usable - * format for processing. - * - * FIXME: - * Bug in Lem as Lem codebase uses [int] type throughout where [BigInt.t] - * is really needed, hence chokes on huge constants below, which is why they are - * written in the way that they are. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_function -open Lem_list -open Lem_maybe -open Lem_num -open Lem_string -(*import Set*) - -open Elf_types_native_uint -open Endianness - -open Byte_sequence -open Error -open Missing_pervasives -open Show - -(** Segment types *) - -(** Unused array element. All other members of the structure are undefined. *) -let elf_pt_null : Nat_big_num.num= (Nat_big_num.of_int 0) -(** A loadable segment. *) -let elf_pt_load : Nat_big_num.num= (Nat_big_num.of_int 1) -(** Dynamic linking information. *) -let elf_pt_dynamic : Nat_big_num.num= (Nat_big_num.of_int 2) -(** Specifies the location and size of a null-terminated path name to be used to - * invoke an interpreter. - *) -let elf_pt_interp : Nat_big_num.num= (Nat_big_num.of_int 3) -(** Specifies location and size of auxiliary information. *) -let elf_pt_note : Nat_big_num.num= (Nat_big_num.of_int 4) -(** Reserved but with unspecified semantics. If the file contains a segment of - * this type then it is to be regarded as non-conformant with the ABI. - *) -let elf_pt_shlib : Nat_big_num.num= (Nat_big_num.of_int 5) -(** Specifies the location and size of the program header table. *) -let elf_pt_phdr : Nat_big_num.num= (Nat_big_num.of_int 6) -(** Specifies the thread local storage (TLS) template. Need not be supported. *) -let elf_pt_tls : Nat_big_num.num= (Nat_big_num.of_int 7) -(** Start of reserved indices for operating system specific semantics. *) -let elf_pt_loos : Nat_big_num.num= (Nat_big_num.mul (Nat_big_num.mul (Nat_big_num.mul (Nat_big_num.mul(Nat_big_num.of_int 128)(Nat_big_num.of_int 128))(Nat_big_num.of_int 128))(Nat_big_num.of_int 256))(Nat_big_num.of_int 3)) (* 1610612736 (* 0x60000000 *) *) -(** End of reserved indices for operating system specific semantics. *) -let elf_pt_hios : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 469762047)(Nat_big_num.of_int 4))(Nat_big_num.of_int 3)) (* 1879048191 (* 0x6fffffff *) *) -(** Start of reserved indices for processor specific semantics. *) -let elf_pt_loproc : Nat_big_num.num= ( Nat_big_num.mul(Nat_big_num.of_int 469762048)(Nat_big_num.of_int 4)) (* 1879048192 (* 0x70000000 *) *) -(** End of reserved indices for processor specific semantics. *) -let elf_pt_hiproc : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 536870911)(Nat_big_num.of_int 4))(Nat_big_num.of_int 3)) (* 2147483647 (* 0x7fffffff *) *) - -(** [string_of_elf_segment_type os proc st] produces a string representation of - * the coding of an ELF segment type [st] using [os] and [proc] to render OS- - * and processor-specific codings. - *) -(* XXX: is GNU stuff supposed to be hardcoded here? *) -(*val string_of_segment_type : (natural -> string) -> (natural -> string) -> natural -> string*) -let string_of_segment_type os proc pt:string= - (if Nat_big_num.equal pt elf_pt_null then - "NULL" - else if Nat_big_num.equal pt elf_pt_load then - "LOAD" - else if Nat_big_num.equal pt elf_pt_dynamic then - "DYNAMIC" - else if Nat_big_num.equal pt elf_pt_interp then - "INTERP" - else if Nat_big_num.equal pt elf_pt_note then - "NOTE" - else if Nat_big_num.equal pt elf_pt_shlib then - "SHLIB" - else if Nat_big_num.equal pt elf_pt_phdr then - "PHDR" - else if Nat_big_num.equal pt elf_pt_tls then - "TLS" - else if Nat_big_num.greater_equal pt elf_pt_loos && Nat_big_num.less_equal pt elf_pt_hios then - os pt - else if Nat_big_num.greater_equal pt elf_pt_loproc && Nat_big_num.less_equal pt elf_pt_hiproc then - proc pt - else - "Undefined or invalid segment type") - -(** Segments permission flags *) - -(** Execute bit *) -let elf_pf_x : Nat_big_num.num= (Nat_big_num.of_int 1) -(** Write bit *) -let elf_pf_w : Nat_big_num.num= (Nat_big_num.of_int 2) -(** Read bit *) -let elf_pf_r : Nat_big_num.num= (Nat_big_num.of_int 4) -(** The following two bit ranges are reserved for OS- and processor-specific - * flags respectively. - *) -let elf_pf_maskos : Nat_big_num.num= (Nat_big_num.of_int 267386880) (* 0x0ff00000 *) -let elf_pf_maskproc : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 4)(Nat_big_num.of_int 1006632960)) (* 0xf0000000 *) - -(** [exact_permission_of_permission m]: ELF has two interpretations of a RWX-style - * permission bit [m], an exact permission and an allowable permission. These - * permissions allow us to interpret a flag as an upper bound for behaviour and - * an ABI-compliant implementation can choose to interpret the flag [m] as either. - * - * In the exact interpretation, the upper bound is exactly the natural interpretation - * of the flag. This is encoded in [exact_permission_of_permission], which is - * a glorified identity function, though included for completeness. - *) -(*val exact_permissions_of_permission : natural -> error natural*) -let exact_permissions_of_permission m:(Nat_big_num.num)error= - (if Nat_big_num.equal m(Nat_big_num.of_int 0) then - return(Nat_big_num.of_int 0) - else if Nat_big_num.equal m elf_pf_x then - return(Nat_big_num.of_int 1) - else if Nat_big_num.equal m elf_pf_w then - return(Nat_big_num.of_int 2) - else if Nat_big_num.equal m elf_pf_r then - return(Nat_big_num.of_int 4) - else if Nat_big_num.equal m (Nat_big_num.add elf_pf_x elf_pf_w) then - return(Nat_big_num.of_int 3) - else if Nat_big_num.equal m (Nat_big_num.add elf_pf_x elf_pf_r) then - return(Nat_big_num.of_int 5) - else if Nat_big_num.equal m (Nat_big_num.add elf_pf_w elf_pf_r) then - return(Nat_big_num.of_int 6) - else if Nat_big_num.equal m (Nat_big_num.add (Nat_big_num.add elf_pf_x elf_pf_r) elf_pf_w) then - return(Nat_big_num.of_int 7) - else - fail "exact_permission_of_permission: invalid permission flag") - -(** [allowable_permission_of_permission m]: ELF has two interpretations of a RWX-style - * permission bit [m], an exact permission and an allowable permission. These - * permissions allow us to interpret a flag as an upper bound for behaviour and - * an ABI-compliant implementation can choose to interpret the flag [m] as either. - * - * In the allowable interpretation, the upper bound is more lax than the natural - * interpretation of the flag. - *) -(*val allowable_permissions_of_permission : natural -> error natural*) -let allowable_permissions_of_permission m:(Nat_big_num.num)error= - (if Nat_big_num.equal m(Nat_big_num.of_int 0) then - return(Nat_big_num.of_int 0) - else if Nat_big_num.equal m elf_pf_x then - return(Nat_big_num.of_int 5) - else if Nat_big_num.equal m elf_pf_w then - return(Nat_big_num.of_int 7) - else if Nat_big_num.equal m elf_pf_r then - return(Nat_big_num.of_int 5) - else if Nat_big_num.equal m (Nat_big_num.add elf_pf_x elf_pf_w) then - return(Nat_big_num.of_int 7) - else if Nat_big_num.equal m (Nat_big_num.add elf_pf_x elf_pf_r) then - return(Nat_big_num.of_int 5) - else if Nat_big_num.equal m (Nat_big_num.add elf_pf_w elf_pf_r) then - return(Nat_big_num.of_int 7) - else if Nat_big_num.equal m (Nat_big_num.add (Nat_big_num.add elf_pf_x elf_pf_r) elf_pf_w) then - return(Nat_big_num.of_int 7) - else - fail "exact_permission_of_permission: invalid permission flag") - -(** [string_of_elf_segment_permissions m] produces a string-based representation - * of an ELF segment's permission field. - * TODO: expand this as is needed by the validation tests. - *) -(*val string_of_elf_segment_permissions : natural -> string*) -let string_of_elf_segment_permissions m:string= - (if Nat_big_num.equal m(Nat_big_num.of_int 0) then - " " - else if Nat_big_num.equal m elf_pf_x then - " E" - else if Nat_big_num.equal m elf_pf_w then - " W " - else if Nat_big_num.equal m elf_pf_r then - "R " - else if Nat_big_num.equal m (Nat_big_num.add elf_pf_x elf_pf_w) then - " WE" - else if Nat_big_num.equal m (Nat_big_num.add elf_pf_x elf_pf_r) then - "R E" - else if Nat_big_num.equal m (Nat_big_num.add elf_pf_w elf_pf_r) then - "RW " - else if Nat_big_num.equal m (Nat_big_num.add (Nat_big_num.add elf_pf_x elf_pf_r) elf_pf_w) then - "RWE" - else - "Invalid permisssion flag") - -(** Program header table entry type *) - -(** Type [elf32_program_header_table_entry] encodes a program header table entry - * for 32-bit platforms. Each entry describes a segment in an executable or - * shared object file. - *) -type elf32_program_header_table_entry = - { elf32_p_type : Uint32.uint32 (** Type of the segment *) - ; elf32_p_offset : Uint32.uint32 (** Offset from beginning of file for segment *) - ; elf32_p_vaddr : Uint32.uint32 (** Virtual address for segment in memory *) - ; elf32_p_paddr : Uint32.uint32 (** Physical address for segment *) - ; elf32_p_filesz : Uint32.uint32 (** Size of segment in file, in bytes *) - ; elf32_p_memsz : Uint32.uint32 (** Size of segment in memory image, in bytes *) - ; elf32_p_flags : Uint32.uint32 (** Segment flags *) - ; elf32_p_align : Uint32.uint32 (** Segment alignment memory for memory and file *) - } - -(** [compare_elf32_program_header_table_entry ent1 ent2] is an ordering-comparison - * function on program header table entries suitable for constructing sets, - * finite maps, and other ordered data types with. - *) -(*val compare_elf32_program_header_table_entry : elf32_program_header_table_entry -> - elf32_program_header_table_entry -> ordering*) -let compare_elf32_program_header_table_entry h1 h2:int= - (lexicographic_compare Nat_big_num.compare [Nat_big_num.of_string (Uint32.to_string h1.elf32_p_type); - Nat_big_num.of_string (Uint32.to_string h1.elf32_p_offset); - Nat_big_num.of_string (Uint32.to_string h1.elf32_p_vaddr); - Nat_big_num.of_string (Uint32.to_string h1.elf32_p_paddr); - Nat_big_num.of_string (Uint32.to_string h1.elf32_p_filesz); - Nat_big_num.of_string (Uint32.to_string h1.elf32_p_memsz); - Nat_big_num.of_string (Uint32.to_string h1.elf32_p_flags); - Nat_big_num.of_string (Uint32.to_string h1.elf32_p_align)] - [Nat_big_num.of_string (Uint32.to_string h2.elf32_p_type); - Nat_big_num.of_string (Uint32.to_string h2.elf32_p_offset); - Nat_big_num.of_string (Uint32.to_string h2.elf32_p_vaddr); - Nat_big_num.of_string (Uint32.to_string h2.elf32_p_paddr); - Nat_big_num.of_string (Uint32.to_string h2.elf32_p_filesz); - Nat_big_num.of_string (Uint32.to_string h2.elf32_p_memsz); - Nat_big_num.of_string (Uint32.to_string h2.elf32_p_flags); - Nat_big_num.of_string (Uint32.to_string h2.elf32_p_align)]) - -let instance_Basic_classes_Ord_Elf_program_header_table_elf32_program_header_table_entry_dict:(elf32_program_header_table_entry)ord_class= ({ - - compare_method = compare_elf32_program_header_table_entry; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(compare_elf32_program_header_table_entry f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (compare_elf32_program_header_table_entry f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(compare_elf32_program_header_table_entry f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (compare_elf32_program_header_table_entry f1 f2)(Pset.from_list compare [1; 0])))}) - -(** Type [elf64_program_header_table_entry] encodes a program header table entry - * for 64-bit platforms. Each entry describes a segment in an executable or - * shared object file. - *) -type elf64_program_header_table_entry = - { elf64_p_type : Uint32.uint32 (** Type of the segment *) - ; elf64_p_flags : Uint32.uint32 (** Segment flags *) - ; elf64_p_offset : Uint64.uint64 (** Offset from beginning of file for segment *) - ; elf64_p_vaddr : Uint64.uint64 (** Virtual address for segment in memory *) - ; elf64_p_paddr : Uint64.uint64 (** Physical address for segment *) - ; elf64_p_filesz : Uint64.uint64 (** Size of segment in file, in bytes *) - ; elf64_p_memsz : Uint64.uint64 (** Size of segment in memory image, in bytes *) - ; elf64_p_align : Uint64.uint64 (** Segment alignment memory for memory and file *) - } - -(** [compare_elf64_program_header_table_entry ent1 ent2] is an ordering-comparison - * function on program header table entries suitable for constructing sets, - * finite maps, and other ordered data types with. - *) -(*val compare_elf64_program_header_table_entry : elf64_program_header_table_entry -> - elf64_program_header_table_entry -> ordering*) -let compare_elf64_program_header_table_entry h1 h2:int= - (lexicographic_compare Nat_big_num.compare [Nat_big_num.of_string (Uint32.to_string h1.elf64_p_type); - Nat_big_num.of_string (Uint64.to_string h1.elf64_p_offset); - Ml_bindings.nat_big_num_of_uint64 h1.elf64_p_vaddr; - Ml_bindings.nat_big_num_of_uint64 h1.elf64_p_paddr; - Ml_bindings.nat_big_num_of_uint64 h1.elf64_p_filesz; - Ml_bindings.nat_big_num_of_uint64 h1.elf64_p_memsz; - Nat_big_num.of_string (Uint32.to_string h1.elf64_p_flags); - Ml_bindings.nat_big_num_of_uint64 h1.elf64_p_align] - [Nat_big_num.of_string (Uint32.to_string h2.elf64_p_type); - Nat_big_num.of_string (Uint64.to_string h2.elf64_p_offset); - Ml_bindings.nat_big_num_of_uint64 h2.elf64_p_vaddr; - Ml_bindings.nat_big_num_of_uint64 h2.elf64_p_paddr; - Ml_bindings.nat_big_num_of_uint64 h2.elf64_p_filesz; - Ml_bindings.nat_big_num_of_uint64 h2.elf64_p_memsz; - Nat_big_num.of_string (Uint32.to_string h2.elf64_p_flags); - Ml_bindings.nat_big_num_of_uint64 h2.elf64_p_align]) - -let instance_Basic_classes_Ord_Elf_program_header_table_elf64_program_header_table_entry_dict:(elf64_program_header_table_entry)ord_class= ({ - - compare_method = compare_elf64_program_header_table_entry; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(compare_elf64_program_header_table_entry f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (compare_elf64_program_header_table_entry f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(compare_elf64_program_header_table_entry f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (compare_elf64_program_header_table_entry f1 f2)(Pset.from_list compare [1; 0])))}) - - -(** [string_of_elf32_program_header_table_entry os proc et] produces a string - * representation of a 32-bit program header table entry using [os] and [proc] - * to render OS- and processor-specific entries. - *) -(*val string_of_elf32_program_header_table_entry : (natural -> string) -> (natural -> string) -> elf32_program_header_table_entry -> string*) -let string_of_elf32_program_header_table_entry os proc entry:string= - (unlines [ -("\t" ^ ("Segment type: " ^ string_of_segment_type os proc (Nat_big_num.of_string (Uint32.to_string entry.elf32_p_type)))) - ; ("\t" ^ ("Offset: " ^ Uint32.to_string entry.elf32_p_offset)) - ; ("\t" ^ ("Virtual address: " ^ Uint32.to_string entry.elf32_p_vaddr)) - ; ("\t" ^ ("Physical address: " ^ Uint32.to_string entry.elf32_p_paddr)) - ; ("\t" ^ ("Segment size (bytes): " ^ Uint32.to_string entry.elf32_p_filesz)) - ; ("\t" ^ ("Segment size in memory image (bytes): " ^ Uint32.to_string entry.elf32_p_memsz)) - ; ("\t" ^ ("Flags: " ^ Uint32.to_string entry.elf32_p_flags)) - ; ("\t" ^ ("Alignment: " ^ Uint32.to_string entry.elf32_p_align)) - ]) - -(** [string_of_elf64_program_header_table_entry os proc et] produces a string - * representation of a 64-bit program header table entry using [os] and [proc] - * to render OS- and processor-specific entries. - *) -(*val string_of_elf64_program_header_table_entry : (natural -> string) -> (natural -> string) -> elf64_program_header_table_entry -> string*) -let string_of_elf64_program_header_table_entry os proc entry:string= - (unlines [ -("\t" ^ ("Segment type: " ^ string_of_segment_type os proc (Nat_big_num.of_string (Uint32.to_string entry.elf64_p_type)))) - ; ("\t" ^ ("Offset: " ^ Uint64.to_string entry.elf64_p_offset)) - ; ("\t" ^ ("Virtual address: " ^ Uint64.to_string entry.elf64_p_vaddr)) - ; ("\t" ^ ("Physical address: " ^ Uint64.to_string entry.elf64_p_paddr)) - ; ("\t" ^ ("Segment size (bytes): " ^ Uint64.to_string entry.elf64_p_filesz)) - ; ("\t" ^ ("Segment size in memory image (bytes): " ^ Uint64.to_string entry.elf64_p_memsz)) - ; ("\t" ^ ("Flags: " ^ Uint32.to_string entry.elf64_p_flags)) - ; ("\t" ^ ("Alignment: " ^ Uint64.to_string entry.elf64_p_align)) - ]) - -(** [string_of_elf32_program_header_table_entry_default et] produces a string representation - * of table entry [et] where OS- and processor-specific entries are replaced with - * default strings. - *) -(*val string_of_elf32_program_header_table_entry_default : elf32_program_header_table_entry -> string*) -let string_of_elf32_program_header_table_entry_default:elf32_program_header_table_entry ->string= - (string_of_elf32_program_header_table_entry - ((fun y->"*Default OS specific print*")) - ((fun y->"*Default processor specific print*"))) - -(** [string_of_elf64_program_header_table_entry_default et] produces a string representation - * of table entry [et] where OS- and processor-specific entries are replaced with - * default strings. - *) -(*val string_of_elf64_program_header_table_entry_default : elf64_program_header_table_entry -> string*) -let string_of_elf64_program_header_table_entry_default:elf64_program_header_table_entry ->string= - (string_of_elf64_program_header_table_entry - ((fun y->"*Default OS specific print*")) - ((fun y->"*Default processor specific print*"))) - -let instance_Show_Show_Elf_program_header_table_elf32_program_header_table_entry_dict:(elf32_program_header_table_entry)show_class= ({ - - show_method = string_of_elf32_program_header_table_entry_default}) - -let instance_Show_Show_Elf_program_header_table_elf64_program_header_table_entry_dict:(elf64_program_header_table_entry)show_class= ({ - - show_method = string_of_elf64_program_header_table_entry_default}) - -(** Parsing and blitting *) - -(** [bytes_of_elf32_program_header_table_entry ed ent] blits a 32-bit program - * header table entry [ent] into a byte sequence assuming endianness [ed]. - *) -(*val bytes_of_elf32_program_header_table_entry : endianness -> elf32_program_header_table_entry -> byte_sequence*) -let bytes_of_elf32_program_header_table_entry endian entry:byte_sequence= - (Byte_sequence.from_byte_lists [ - bytes_of_elf32_word endian entry.elf32_p_type - ; bytes_of_elf32_off endian entry.elf32_p_offset - ; bytes_of_elf32_addr endian entry.elf32_p_vaddr - ; bytes_of_elf32_addr endian entry.elf32_p_paddr - ; bytes_of_elf32_word endian entry.elf32_p_filesz - ; bytes_of_elf32_word endian entry.elf32_p_memsz - ; bytes_of_elf32_word endian entry.elf32_p_flags - ; bytes_of_elf32_word endian entry.elf32_p_align - ]) - -(** [bytes_of_elf64_program_header_table_entry ed ent] blits a 64-bit program - * header table entry [ent] into a byte sequence assuming endianness [ed]. - *) -(*val bytes_of_elf64_program_header_table_entry : endianness -> elf64_program_header_table_entry -> byte_sequence*) -let bytes_of_elf64_program_header_table_entry endian entry:byte_sequence= - (Byte_sequence.from_byte_lists [ - bytes_of_elf64_word endian entry.elf64_p_type - ; bytes_of_elf64_word endian entry.elf64_p_flags - ; bytes_of_elf64_off endian entry.elf64_p_offset - ; bytes_of_elf64_addr endian entry.elf64_p_vaddr - ; bytes_of_elf64_addr endian entry.elf64_p_paddr - ; bytes_of_elf64_xword endian entry.elf64_p_filesz - ; bytes_of_elf64_xword endian entry.elf64_p_memsz - ; bytes_of_elf64_xword endian entry.elf64_p_align - ]) - -(** [read_elf32_program_header_table_entry endian bs0] reads an ELF32 program header table - * entry from byte sequence [bs0] assuming endianness [endian]. If [bs0] is larger - * than necessary, the excess is returned from the function, too. - * Fails if the entry cannot be read. - *) -(*val read_elf32_program_header_table_entry : endianness -> byte_sequence -> - error (elf32_program_header_table_entry * byte_sequence)*) -let read_elf32_program_header_table_entry endian bs:(elf32_program_header_table_entry*byte_sequence)error= - (read_elf32_word endian bs >>= (fun (typ, bs) -> - read_elf32_off endian bs >>= (fun (offset, bs) -> - read_elf32_addr endian bs >>= (fun (vaddr, bs) -> - read_elf32_addr endian bs >>= (fun (paddr, bs) -> - read_elf32_word endian bs >>= (fun (filesz, bs) -> - read_elf32_word endian bs >>= (fun (memsz, bs) -> - read_elf32_word endian bs >>= (fun (flags, bs) -> - read_elf32_word endian bs >>= (fun (align, bs) -> - return ({ elf32_p_type = typ; elf32_p_offset = offset; - elf32_p_vaddr = vaddr; elf32_p_paddr = paddr; - elf32_p_filesz = filesz; elf32_p_memsz = memsz; - elf32_p_flags = flags; elf32_p_align = align }, bs)))))))))) - -(** [read_elf64_program_header_table_entry endian bs0] reads an ELF64 program header table - * entry from byte sequence [bs0] assuming endianness [endian]. If [bs0] is larger - * than necessary, the excess is returned from the function, too. - * Fails if the entry cannot be read. - *) -(*val read_elf64_program_header_table_entry : endianness -> byte_sequence -> - error (elf64_program_header_table_entry * byte_sequence)*) -let read_elf64_program_header_table_entry endian bs:(elf64_program_header_table_entry*byte_sequence)error= - (read_elf64_word endian bs >>= (fun (typ, bs) -> - read_elf64_word endian bs >>= (fun (flags, bs) -> - read_elf64_off endian bs >>= (fun (offset, bs) -> - read_elf64_addr endian bs >>= (fun (vaddr, bs) -> - read_elf64_addr endian bs >>= (fun (paddr, bs) -> - read_elf64_xword endian bs >>= (fun (filesz, bs) -> - read_elf64_xword endian bs >>= (fun (memsz, bs) -> - read_elf64_xword endian bs >>= (fun (align, bs) -> - return ({ elf64_p_type = typ; elf64_p_offset = offset; - elf64_p_vaddr = vaddr; elf64_p_paddr = paddr; - elf64_p_filesz = filesz; elf64_p_memsz = memsz; - elf64_p_flags = flags; elf64_p_align = align }, bs)))))))))) - -(** Program header table type *) - -(** Type [elf32_program_header_table] represents a program header table for 32-bit - * ELF files. A program header table is an array (implemented as a list, here) - * of program header table entries. - *) -type elf32_program_header_table = elf32_program_header_table_entry - list - -(** Type [elf64_program_header_table] represents a program header table for 64-bit - * ELF files. A program header table is an array (implemented as a list, here) - * of program header table entries. - *) -type elf64_program_header_table = elf64_program_header_table_entry - list - -(** [bytes_of_elf32_program_header_table ed tbl] blits an ELF32 program header - * table into a byte sequence assuming endianness [ed]. - *) -let bytes_of_elf32_program_header_table endian tbl:byte_sequence= - (Byte_sequence.concat0 (Lem_list.map (bytes_of_elf32_program_header_table_entry endian) tbl)) - -(** [bytes_of_elf64_program_header_table ed tbl] blits an ELF64 program header - * table into a byte sequence assuming endianness [ed]. - *) -let bytes_of_elf64_program_header_table endian tbl:byte_sequence= - (Byte_sequence.concat0 (Lem_list.map (bytes_of_elf64_program_header_table_entry endian) tbl)) - -(** [read_elf32_program_header_table' endian bs0] reads an ELF32 program header table from - * byte_sequence [bs0] assuming endianness [endian]. The byte_sequence [bs0] is assumed - * to have exactly the correct size for the table. For internal use, only. Use - * [read_elf32_program_header_table] below instead. - *) -let rec read_elf32_program_header_table' endian bs0:((elf32_program_header_table_entry)list)error= - (if Nat_big_num.equal (Byte_sequence.length0 bs0)(Nat_big_num.of_int 0) then - return [] - else - read_elf32_program_header_table_entry endian bs0 >>= (fun (entry, bs1) -> - read_elf32_program_header_table' endian bs1 >>= (fun tail -> - return (entry::tail)))) - -(** [read_elf64_program_header_table' endian bs0] reads an ELF64 program header table from - * byte_sequence [bs0] assuming endianness [endian]. The byte_sequence [bs0] is assumed - * to have exactly the correct size for the table. For internal use, only. Use - * [read_elf32_program_header_table] below instead. - *) -let rec read_elf64_program_header_table' endian bs0:((elf64_program_header_table_entry)list)error= - (if Nat_big_num.equal (Byte_sequence.length0 bs0)(Nat_big_num.of_int 0) then - return [] - else - read_elf64_program_header_table_entry endian bs0 >>= (fun (entry, bs1) -> - read_elf64_program_header_table' endian bs1 >>= (fun tail -> - return (entry::tail)))) - -(** [read_elf32_program_header_table table_size endian bs0] reads an ELF32 program header - * table from byte_sequence [bs0] assuming endianness [endian] based on the size (in bytes) passed in via [table_size]. - * This [table_size] argument should be equal to the number of entries in the - * table multiplied by the fixed entry size. Bitstring [bs0] may be larger than - * necessary, in which case the excess is returned. - *) -(*val read_elf32_program_header_table : natural -> endianness -> byte_sequence -> - error (elf32_program_header_table * byte_sequence)*) -let read_elf32_program_header_table table_size endian bs0:((elf32_program_header_table_entry)list*byte_sequence)error= - (partition0 table_size bs0 >>= (fun (eat, rest) -> - read_elf32_program_header_table' endian eat >>= (fun table -> - return (table, rest)))) - -(** [read_elf64_program_header_table table_size endian bs0] reads an ELF64 program header - * table from byte_sequence [bs0] assuming endianness [endian] based on the size (in bytes) passed in via [table_size]. - * This [table_size] argument should be equal to the number of entries in the - * table multiplied by the fixed entry size. Bitstring [bs0] may be larger than - * necessary, in which case the excess is returned. - *) -(*val read_elf64_program_header_table : natural -> endianness -> byte_sequence -> - error (elf64_program_header_table * byte_sequence)*) -let read_elf64_program_header_table table_size endian bs0:((elf64_program_header_table_entry)list*byte_sequence)error= - (partition0 table_size bs0 >>= (fun (eat, rest) -> - read_elf64_program_header_table' endian eat >>= (fun table -> - return (table, rest)))) - -(** The [pht_print_bundle] type is used to tidy up other type signatures. Some of the - * top-level string_of_ functions require six or more functions passed to them, - * which quickly gets out of hand. This type is used to reduce that complexity. - * The first component of the type is an OS specific print function, the second is - * a processor specific print function. - *) -type pht_print_bundle = (Nat_big_num.num -> string) * (Nat_big_num.num -> string) - -(** [string_of_elf32_program_header_table os proc tbl] produces a string representation - * of program header table [tbl] using [os] and [proc] to render OS- and processor- - * specific entries. - *) -(*val string_of_elf32_program_header_table : pht_print_bundle -> elf32_program_header_table -> string*) -let string_of_elf32_program_header_table (os, proc) tbl:string= - (unlines (Lem_list.map (string_of_elf32_program_header_table_entry os proc) tbl)) - -(** [string_of_elf64_program_header_table os proc tbl] produces a string representation - * of program header table [tbl] using [os] and [proc] to render OS- and processor- - * specific entries. - *) -(*val string_of_elf64_program_header_table : pht_print_bundle -> elf64_program_header_table -> string*) -let string_of_elf64_program_header_table (os, proc) tbl:string= - (unlines (Lem_list.map (string_of_elf64_program_header_table_entry os proc) tbl)) - -(** Static/dynamic linkage *) - -(** [get_elf32_dynamic_linked pht] tests whether an ELF32 file is a dynamically - * linked object by traversing the program header table and attempting to find - * a header describing a segment with the name of an associated interpreter. - * Returns [true] if any such header is found, [false] --- indicating static - * linkage --- otherwise. - *) -(*val get_elf32_dynamic_linked : elf32_program_header_table -> bool*) -let get_elf32_dynamic_linked pht:bool= - (List.exists (fun p -> Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string p.elf32_p_type)) elf_pt_interp) pht) - -(** [get_elf64_dynamic_linked pht] tests whether an ELF64 file is a dynamically - * linked object by traversing the program header table and attempting to find - * a header describing a segment with the name of an associated interpreter. - * Returns [true] if any such header is found, [false] --- indicating static - * linkage --- otherwise. - *) -(*val get_elf64_dynamic_linked : elf64_program_header_table -> bool*) -let get_elf64_dynamic_linked pht:bool= - (List.exists (fun p -> Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string p.elf64_p_type)) elf_pt_interp) pht) - -(** [get_elf32_static_linked] is a utility function defined as the inverse - * of [get_elf32_dynamic_linked]. - *) -(*val get_elf32_static_linked : elf32_program_header_table -> bool*) -let get_elf32_static_linked pht:bool= - (not (get_elf32_dynamic_linked pht)) - -(** [get_elf64_static_linked] is a utility function defined as the inverse - * of [get_elf64_dynamic_linked]. - *) -(*val get_elf64_static_linked : elf64_program_header_table -> bool*) -let get_elf64_static_linked pht:bool= - (not (get_elf64_dynamic_linked pht)) - -(** [get_elf32_requested_interpreter ent bs0] extracts the requested interpreter - * of a dynamically linkable ELF file from that file's program header table - * entry of type PT_INTERP, [ent]. Interpreter string is extracted from byte - * sequence [bs0]. - * Fails if [ent] is not of type PT_INTERP, or if transcription otherwise fails. - *) -(*val get_elf32_requested_interpreter : elf32_program_header_table_entry -> - byte_sequence -> error string*) -let get_elf32_requested_interpreter pent bs0:(string)error= - (if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string pent.elf32_p_type)) elf_pt_interp then - let off = (Nat_big_num.of_string (Uint32.to_string pent.elf32_p_offset)) in - let siz = (Nat_big_num.of_string (Uint32.to_string pent.elf32_p_filesz)) in - Byte_sequence.offset_and_cut off ( Nat_big_num.sub_nat siz(Nat_big_num.of_int 1)) bs0 >>= (fun cut -> - return (Byte_sequence.string_of_byte_sequence cut)) - else - fail "get_elf32_requested_interpreter: not an INTERP segment header") - -(** [get_elf64_requested_interpreter ent bs0] extracts the requested interpreter - * of a dynamically linkable ELF file from that file's program header table - * entry of type PT_INTERP, [ent]. Interpreter string is extracted from byte - * sequence [bs0]. - * Fails if [ent] is not of type PT_INTERP, or if transcription otherwise fails. - *) -(*val get_elf64_requested_interpreter : elf64_program_header_table_entry -> - byte_sequence -> error string*) -let get_elf64_requested_interpreter pent bs0:(string)error= - (if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string pent.elf64_p_type)) elf_pt_interp then - let off = (Nat_big_num.of_string (Uint64.to_string pent.elf64_p_offset)) in - let siz = (Ml_bindings.nat_big_num_of_uint64 pent.elf64_p_filesz) in - Byte_sequence.offset_and_cut off ( Nat_big_num.sub_nat siz(Nat_big_num.of_int 1)) bs0 >>= (fun cut -> - return (Byte_sequence.string_of_byte_sequence cut)) - else - fail "get_elf64_requested_interpreter: not an INTERP segment header") diff --git a/lib/ocaml_rts/linksem/elf_relocation.ml b/lib/ocaml_rts/linksem/elf_relocation.ml deleted file mode 100644 index 65a77ef8..00000000 --- a/lib/ocaml_rts/linksem/elf_relocation.ml +++ /dev/null @@ -1,312 +0,0 @@ -(*Generated by Lem from elf_relocation.lem.*) -(** [elf_relocation] formalises types, functions and other definitions for working - * with ELF relocation and relocation with addend entries. - *) - -open Lem_basic_classes -open Lem_num -open Lem_list -(*import Set*) - -open Endianness -open Byte_sequence -open Error - -open Lem_string -open Show -open Missing_pervasives - -open Elf_types_native_uint - -(** ELF relocation records *) - -(** [elf32_relocation] is a simple relocation record (without addend). - *) -type elf32_relocation = - { elf32_r_offset : Uint32.uint32 (** Address at which to relocate *) - ; elf32_r_info : Uint32.uint32 (** Symbol table index/type of relocation to apply *) - } - -(** [elf32_relocation_a] is a relocation record with addend. - *) -type elf32_relocation_a = - { elf32_ra_offset : Uint32.uint32 (** Address at which to relocate *) - ; elf32_ra_info : Uint32.uint32 (** Symbol table index/type of relocation to apply *) - ; elf32_ra_addend : Int32.t (** Addend used to compute value to be stored *) - } - -(** [elf64_relocation] is a simple relocation record (without addend). - *) -type elf64_relocation = - { elf64_r_offset : Uint64.uint64 (** Address at which to relocate *) - ; elf64_r_info : Uint64.uint64 (** Symbol table index/type of relocation to apply *) - } - -(** [elf64_relocation_a] is a relocation record with addend. - *) -type elf64_relocation_a = - { elf64_ra_offset : Uint64.uint64 (** Address at which to relocate *) - ; elf64_ra_info : Uint64.uint64 (** Symbol table index/type of relocation to apply *) - ; elf64_ra_addend : Int64.t (** Addend used to compute value to be stored *) - } - -(** [elf64_relocation_a_compare r1 r2] is an ordering comparison function for - * relocation with addend records suitable for constructing sets, finite map - * and other ordered data structures. - * NB: we exclusively use elf64_relocation_a in range tags, regardless of what - * file/reloc the info came from, so only this one needs an Ord instance. - *) -(*val elf64_relocation_a_compare : elf64_relocation_a -> elf64_relocation_a -> - ordering*) -let elf64_relocation_a_compare ent1 ent2:int= - (tripleCompare Nat_big_num.compare Nat_big_num.compare Nat_big_num.compare (Ml_bindings.nat_big_num_of_uint64 ent1.elf64_ra_offset, Ml_bindings.nat_big_num_of_uint64 ent1.elf64_ra_info, - Nat_big_num.of_int64 ent1.elf64_ra_addend) - (Ml_bindings.nat_big_num_of_uint64 ent2.elf64_ra_offset, Ml_bindings.nat_big_num_of_uint64 ent2.elf64_ra_info, - Nat_big_num.of_int64 ent2.elf64_ra_addend)) - -let instance_Basic_classes_Ord_Elf_relocation_elf64_relocation_a_dict:(elf64_relocation_a)ord_class= ({ - - compare_method = elf64_relocation_a_compare; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(elf64_relocation_a_compare f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (elf64_relocation_a_compare f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(elf64_relocation_a_compare f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (elf64_relocation_a_compare f1 f2)(Pset.from_list compare [1; 0])))}) - -(** Extracting useful information *) - -(** [extract_elf32_relocation_r_sym w] computes the symbol table index associated with - * an ELF32 relocation(a) entry. - * [w] here is the [r_info] member of the [elf32_relocation(a)] type. - *) -(*val extract_elf32_relocation_r_sym : elf32_word -> natural*) -let extract_elf32_relocation_r_sym w:Nat_big_num.num= - (Nat_big_num.of_string (Uint32.to_string (Uint32.shift_right w( 8)))) - -(** [extract_elf64_relocation_r_sym w] computes the symbol table index associated with - * an ELF64 relocation(a) entry. - * [w] here is the [r_info] member of the [elf64_relocation(a)] type. - *) -(*val extract_elf64_relocation_r_sym : elf64_xword -> natural*) -let extract_elf64_relocation_r_sym w:Nat_big_num.num= - (Ml_bindings.nat_big_num_of_uint64 (Uint64.shift_right w( 32))) - -(** [extract_elf32_relocation_r_type w] computes the symbol type associated with an ELF32 - * relocation(a) entry. - * [w] here is the [r_info] member of the [elf32_relocation(a)] type. - *) -(*val extract_elf32_relocation_r_type : elf32_word -> natural*) -let extract_elf32_relocation_r_type w:Nat_big_num.num= (Nat_big_num.modulus - (Nat_big_num.of_string (Uint32.to_string w))(Nat_big_num.of_int 256)) - -(** [extract_elf64_relocation_r_type w] computes the symbol type associated with an ELF64 - * relocation(a) entry. - * [w] here is the [r_info] member of the [elf64_relocation(a)] type. - *) -(*val extract_elf64_relocation_r_type : elf64_xword -> natural*) -let extract_elf64_relocation_r_type w:Nat_big_num.num= - (let magic = (Nat_big_num.sub_nat ( Nat_big_num.mul(Nat_big_num.of_int 65536)(Nat_big_num.of_int 65536))(Nat_big_num.of_int 1)) in (* 0xffffffffL *) - Ml_bindings.nat_big_num_of_uint64 (Uint64.logand w (Uint64.of_string (Nat_big_num.to_string magic)))) - -(* Accessors *) - -(*val get_elf32_relocation_r_sym : elf32_relocation -> natural*) -let get_elf32_relocation_r_sym r:Nat_big_num.num= - (extract_elf32_relocation_r_sym r.elf32_r_info) - -(*val get_elf32_relocation_a_sym : elf32_relocation_a -> natural*) -let get_elf32_relocation_a_sym r:Nat_big_num.num= - (extract_elf32_relocation_r_sym r.elf32_ra_info) - -(*val get_elf64_relocation_sym : elf64_relocation -> natural*) -let get_elf64_relocation_sym r:Nat_big_num.num= - (extract_elf64_relocation_r_sym r.elf64_r_info) - -(*val get_elf64_relocation_a_sym : elf64_relocation_a -> natural*) -let get_elf64_relocation_a_sym r:Nat_big_num.num= - (extract_elf64_relocation_r_sym r.elf64_ra_info) - -(*val get_elf32_relocation_type : elf32_relocation -> natural*) -let get_elf32_relocation_type r:Nat_big_num.num= - (extract_elf32_relocation_r_type r.elf32_r_info) - -(*val get_elf32_relocation_a_type : elf32_relocation_a -> natural*) -let get_elf32_relocation_a_type r:Nat_big_num.num= - (extract_elf32_relocation_r_type r.elf32_ra_info) - -(*val get_elf64_relocation_type : elf64_relocation -> natural*) -let get_elf64_relocation_type r:Nat_big_num.num= - (extract_elf64_relocation_r_type r.elf64_r_info) - -(*val get_elf64_relocation_a_type : elf64_relocation_a -> natural*) -let get_elf64_relocation_a_type r:Nat_big_num.num= - (extract_elf64_relocation_r_type r.elf64_ra_info) - - -(** Reading relocation entries *) - -(** [read_elf32_relocation ed bs0] parses an [elf32_relocation] record from - * byte sequence [bs0] assuming endianness [ed]. The suffix of [bs0] remaining - * after parsing is also returned. - * Fails if the relocation record cannot be parsed. - *) -(*val read_elf32_relocation : endianness -> byte_sequence -> - error (elf32_relocation * byte_sequence)*) -let read_elf32_relocation endian bs:(elf32_relocation*byte_sequence)error= - (read_elf32_addr endian bs >>= (fun (r_offset, bs) -> - read_elf32_word endian bs >>= (fun (r_info, bs) -> - return ({ elf32_r_offset = r_offset; elf32_r_info = r_info }, bs)))) - -(** [read_elf64_relocation ed bs0] parses an [elf64_relocation] record from - * byte sequence [bs0] assuming endianness [ed]. The suffix of [bs0] remaining - * after parsing is also returned. - * Fails if the relocation record cannot be parsed. - *) -(*val read_elf64_relocation : endianness -> byte_sequence -> - error (elf64_relocation * byte_sequence)*) -let read_elf64_relocation endian bs:(elf64_relocation*byte_sequence)error= - (read_elf64_addr endian bs >>= (fun (r_offset, bs) -> - read_elf64_xword endian bs >>= (fun (r_info, bs) -> - return ({ elf64_r_offset = r_offset; elf64_r_info = r_info }, bs)))) - -(** [read_elf32_relocation_a ed bs0] parses an [elf32_relocation_a] record from - * byte sequence [bs0] assuming endianness [ed]. The suffix of [bs0] remaining - * after parsing is also returned. - * Fails if the relocation record cannot be parsed. - *) -(*val read_elf32_relocation_a : endianness -> byte_sequence -> - error (elf32_relocation_a * byte_sequence)*) -let read_elf32_relocation_a endian bs:(elf32_relocation_a*byte_sequence)error= - (read_elf32_addr endian bs >>= (fun (r_offset, bs) -> - read_elf32_word endian bs >>= (fun (r_info, bs) -> - read_elf32_sword endian bs >>= (fun (r_addend, bs) -> - return ({ elf32_ra_offset = r_offset; elf32_ra_info = r_info; - elf32_ra_addend = r_addend }, bs))))) - -(** [read_elf64_relocation_a ed bs0] parses an [elf64_relocation_a] record from - * byte sequence [bs0] assuming endianness [ed]. The suffix of [bs0] remaining - * after parsing is also returned. - * Fails if the relocation record cannot be parsed. - *) -(*val read_elf64_relocation_a : endianness -> byte_sequence -> error (elf64_relocation_a * byte_sequence)*) -let read_elf64_relocation_a endian bs:(elf64_relocation_a*byte_sequence)error= - (read_elf64_addr endian bs >>= (fun (r_offset, bs) -> - read_elf64_xword endian bs >>= (fun (r_info, bs) -> - read_elf64_sxword endian bs >>= (fun (r_addend, bs) -> - return ({ elf64_ra_offset = r_offset; elf64_ra_info = r_info; - elf64_ra_addend = r_addend }, bs))))) - -(** [read_elf32_relocation_section' ed bs0] parses a list of [elf32_relocation] - * records from byte sequence [bs0], which is assumed to have the exact size - * required, assuming endianness [ed]. - * Fails if any of the records cannot be parsed. - *) -(*val read_elf32_relocation_section' : endianness -> byte_sequence -> - error (list elf32_relocation)*) -let rec read_elf32_relocation_section' endian bs0:((elf32_relocation)list)error= - (if Nat_big_num.equal (Byte_sequence.length0 bs0)(Nat_big_num.of_int 0) then - return [] - else - read_elf32_relocation endian bs0 >>= (fun (entry, bs1) -> - read_elf32_relocation_section' endian bs1 >>= (fun tail -> - return (entry::tail)))) - -(** [read_elf64_relocation_section' ed bs0] parses a list of [elf64_relocation] - * records from byte sequence [bs0], which is assumed to have the exact size - * required, assuming endianness [ed]. - * Fails if any of the records cannot be parsed. - *) -(*val read_elf64_relocation_section' : endianness -> byte_sequence -> - error (list elf64_relocation)*) -let rec read_elf64_relocation_section' endian bs0:((elf64_relocation)list)error= - (if Nat_big_num.equal (Byte_sequence.length0 bs0)(Nat_big_num.of_int 0) then - return [] - else - read_elf64_relocation endian bs0 >>= (fun (entry, bs1) -> - read_elf64_relocation_section' endian bs1 >>= (fun tail -> - return (entry::tail)))) - -(** [read_elf32_relocation_a_section' ed bs0] parses a list of [elf32_relocation_a] - * records from byte sequence [bs0], which is assumed to have the exact size - * required, assuming endianness [ed]. - * Fails if any of the records cannot be parsed. - *) -(*val read_elf32_relocation_a_section' : endianness -> byte_sequence -> - error (list elf32_relocation_a)*) -let rec read_elf32_relocation_a_section' endian bs0:((elf32_relocation_a)list)error= - (if Nat_big_num.equal (Byte_sequence.length0 bs0)(Nat_big_num.of_int 0) then - return [] - else - read_elf32_relocation_a endian bs0 >>= (fun (entry, bs1) -> - read_elf32_relocation_a_section' endian bs1 >>= (fun tail -> - return (entry::tail)))) - -(** [read_elf64_relocation_a_section' ed bs0] parses a list of [elf64_relocation_a] - * records from byte sequence [bs0], which is assumed to have the exact size - * required, assuming endianness [ed]. - * Fails if any of the records cannot be parsed. - *) -(*val read_elf64_relocation_a_section' : endianness -> byte_sequence -> - error (list elf64_relocation_a)*) -let rec read_elf64_relocation_a_section' endian bs0:((elf64_relocation_a)list)error= - (if Nat_big_num.equal (Byte_sequence.length0 bs0)(Nat_big_num.of_int 0) then - return [] - else - read_elf64_relocation_a endian bs0 >>= (fun (entry, bs1) -> - read_elf64_relocation_a_section' endian bs1 >>= (fun tail -> - return (entry::tail)))) - -(** [read_elf32_relocation_section sz ed bs0] reads in a list of [elf32_relocation] - * records from a prefix of [bs0] of size [sz] assuming endianness [ed]. The - * suffix of [bs0] remaining after parsing is also returned. - * Fails if any of the records cannot be parsed or if the length of [bs0] is - * less than [sz]. - *) -(*val read_elf32_relocation_section : natural -> endianness -> byte_sequence - -> error (list elf32_relocation * byte_sequence)*) -let read_elf32_relocation_section table_size endian bs0:((elf32_relocation)list*byte_sequence)error= - (partition0 table_size bs0 >>= (fun (eat, rest) -> - read_elf32_relocation_section' endian eat >>= (fun entries -> - return (entries, rest)))) - -(** [read_elf64_relocation_section sz ed bs0] reads in a list of [elf64_relocation] - * records from a prefix of [bs0] of size [sz] assuming endianness [ed]. The - * suffix of [bs0] remaining after parsing is also returned. - * Fails if any of the records cannot be parsed or if the length of [bs0] is - * less than [sz]. - *) -(*val read_elf64_relocation_section : natural -> endianness -> byte_sequence - -> error (list elf64_relocation * byte_sequence)*) -let read_elf64_relocation_section table_size endian bs0:((elf64_relocation)list*byte_sequence)error= - (partition0 table_size bs0 >>= (fun (eat, rest) -> - read_elf64_relocation_section' endian eat >>= (fun entries -> - return (entries, rest)))) - -(** [read_elf32_relocation_a_section sz ed bs0] reads in a list of [elf32_relocation_a] - * records from a prefix of [bs0] of size [sz] assuming endianness [ed]. The - * suffix of [bs0] remaining after parsing is also returned. - * Fails if any of the records cannot be parsed or if the length of [bs0] is - * less than [sz]. - *) -(*val read_elf32_relocation_a_section : natural -> endianness -> byte_sequence -> - error (list elf32_relocation_a * byte_sequence)*) -let read_elf32_relocation_a_section table_size endian bs0:((elf32_relocation_a)list*byte_sequence)error= - (partition0 table_size bs0 >>= (fun (eat, rest) -> - read_elf32_relocation_a_section' endian eat >>= (fun entries -> - return (entries, rest)))) - -(** [read_elf64_relocation_a_section sz ed bs0] reads in a list of [elf64_relocation_a] - * records from a prefix of [bs0] of size [sz] assuming endianness [ed]. The - * suffix of [bs0] remaining after parsing is also returned. - * Fails if any of the records cannot be parsed or if the length of [bs0] is - * less than [sz]. - *) -(*val read_elf64_relocation_a_section : natural -> endianness -> byte_sequence -> - error (list elf64_relocation_a * byte_sequence)*) -let read_elf64_relocation_a_section table_size endian bs0:((elf64_relocation_a)list*byte_sequence)error= - (partition0 table_size bs0 >>= (fun (eat, rest) -> - read_elf64_relocation_a_section' endian eat >>= (fun entries -> - return (entries, rest)))) diff --git a/lib/ocaml_rts/linksem/elf_section_header_table.ml b/lib/ocaml_rts/linksem/elf_section_header_table.ml deleted file mode 100644 index b750c103..00000000 --- a/lib/ocaml_rts/linksem/elf_section_header_table.ml +++ /dev/null @@ -1,1187 +0,0 @@ -(*Generated by Lem from elf_section_header_table.lem.*) -(** [elf_section_header_table] provides types, functions and other definitions - * for working with section header tables and their entries. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_function -open Lem_list -open Lem_map -open Lem_maybe -open Lem_num -open Lem_string - -open Byte_sequence -open Error -open Missing_pervasives -open Show - -open Endianness -open String_table - -open Elf_header -open Elf_types_native_uint -open Elf_program_header_table - -(** Special section indices. *) - -(** See elf_header.lem for shn_undef *) - -(** [shn_loreserve]: this specifies the lower bound of the range of reserved - * indices. - *) -let shn_loreserve : Nat_big_num.num= (Nat_big_num.of_int 65280) (* 0xff00 *) -(** [shn_loproc]: start of the range reserved for processor-specific semantics. - *) -let shn_loproc : Nat_big_num.num= (Nat_big_num.of_int 65280) (* 0xff00 *) -(** [shn_hiproc]: end of the range reserved for processor-specific semantics. - *) -let shn_hiproc : Nat_big_num.num= (Nat_big_num.of_int 65311) (* 0xff1f *) -(** [shn_loos]: start of the range reserved for operating system-specific - * semantics. - *) -let shn_loos : Nat_big_num.num= (Nat_big_num.of_int 65312) (* 0xff20 *) -(** [shn_hios]: end of the range reserved for operating system-specific - * semantics. - *) -let shn_hios : Nat_big_num.num= (Nat_big_num.of_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 : Nat_big_num.num= (Nat_big_num.of_int 65521) (* 0xfff1 *) -(** [shn_common]: symbols defined relative to this index are common symbols, - * such as unallocated C external variables. - *) -let shn_common : Nat_big_num.num= (Nat_big_num.of_int 65522) (* 0xfff2 *) - -(** See elf_header.lem for shn_xindex. *) - -(** [shn_hireserve]: specifies the upper-bound of reserved values. - *) -let shn_hireserve : Nat_big_num.num= (Nat_big_num.of_int 65535) (* 0xffff *) - -(** [string_of_special_section_index m] produces a string-based representation - * of a section header entry's special section index, [m]. - *) -(*val string_of_special_section_index : natural -> string*) -let string_of_special_section_index i:string= - (if Nat_big_num.equal i shn_undef then - "SHN_UNDEF" - else if Nat_big_num.equal i shn_loreserve then - "SHN_LORESERVE" - else if Nat_big_num.greater_equal i shn_loproc && Nat_big_num.less_equal i shn_hiproc then - "SHN_PROCESSOR_SPECIFIC" - else if Nat_big_num.greater_equal i shn_loos && Nat_big_num.less_equal i shn_hios then - "SHN_OS_SPECIFIC" - else if Nat_big_num.equal i shn_abs then - "SHN_ABS" - else if Nat_big_num.equal i shn_common then - "SHN_COMMON" - else if Nat_big_num.equal i shn_xindex then - "SHN_XINDEX" - else if Nat_big_num.equal i shn_hireserve then - "SHN_HIRESERVE" - else - "SHN UNDEFINED") - -(** Section types. *) - -(** Marks the section header as being inactive. *) -let sht_null : Nat_big_num.num= (Nat_big_num.of_int 0) -(** Section holds information defined by the program. *) -let sht_progbits : Nat_big_num.num= (Nat_big_num.of_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 : Nat_big_num.num= (Nat_big_num.of_int 2) -let sht_dynsym : Nat_big_num.num= (Nat_big_num.of_int 11) -(** Section holds a string table *) -let sht_strtab : Nat_big_num.num= (Nat_big_num.of_int 3) -(** Section holds relocation entries with explicit addends. An object file may - * have multiple section of this type. - *) -let sht_rela : Nat_big_num.num= (Nat_big_num.of_int 4) -(** Section holds a symbol hash table. An object file may only have a single - * hash table. - *) -let sht_hash : Nat_big_num.num= (Nat_big_num.of_int 5) -(** Section holds information for dynamic linking. An object file may only have - * a single dynamic section. - *) -let sht_dynamic : Nat_big_num.num= (Nat_big_num.of_int 6) -(** Section holds information that marks the file in some way. *) -let sht_note : Nat_big_num.num= (Nat_big_num.of_int 7) -(** Section occupies no space in the file but otherwise resembles a progbits - * section. - *) -let sht_nobits : Nat_big_num.num= (Nat_big_num.of_int 8) -(** Section holds relocation entries without explicit addends. An object file - * may have multiple section of this type. - *) -let sht_rel : Nat_big_num.num= (Nat_big_num.of_int 9) -(** Section type is reserved but has an unspecified meaning. *) -let sht_shlib : Nat_big_num.num= (Nat_big_num.of_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 : Nat_big_num.num= (Nat_big_num.of_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 : Nat_big_num.num= (Nat_big_num.of_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 : Nat_big_num.num= (Nat_big_num.of_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 : Nat_big_num.num= (Nat_big_num.of_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. - * - * FIXME: Lem bug as [int] type used throughout Lem codebase, rather than - * [BigInt.t], so Lem chokes on these large constants below, hence the weird - * way in which they are written. - *) -let sht_symtab_shndx : Nat_big_num.num= (Nat_big_num.of_int 18) - -(** The following ranges are reserved solely for OS-, processor- and user- - * specific semantics, respectively. - *) -let sht_loos : Nat_big_num.num= (Nat_big_num.mul (Nat_big_num.mul (Nat_big_num.mul(Nat_big_num.of_int 3)(Nat_big_num.of_int 1024))(Nat_big_num.of_int 1024))(Nat_big_num.of_int 512)) (* 1610612736 (* 0x60000000 *) *) -let sht_hios : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 469762047)(Nat_big_num.of_int 4))(Nat_big_num.of_int 3)) (* 1879048191 (* 0x6fffffff *) *) -let sht_loproc : Nat_big_num.num= ( Nat_big_num.mul(Nat_big_num.of_int 469762048)(Nat_big_num.of_int 4)) (* 1879048192 (* 0x70000000 *) *) -let sht_hiproc : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 536870911)(Nat_big_num.of_int 4))(Nat_big_num.of_int 3)) (* 2147483647 (* 0x7fffffff *) *) -let sht_louser : Nat_big_num.num= ( Nat_big_num.mul(Nat_big_num.of_int 536870912)(Nat_big_num.of_int 4)) (* 2147483648 (* 0x80000000 *) *) -let sht_hiuser : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 603979775)(Nat_big_num.of_int 4))(Nat_big_num.of_int 3)) (* 2415919103 (* 0x8fffffff *) *) - -(** [string_of_section_type os proc user i] produces a string-based representation - * of section type [i]. Some section types are defined by ABI-specific supplements - * in reserved ranges, in which case the functions [os], [proc] and [user] are - * used to produce the string. - *) -(*val string_of_section_type : (natural -> string) -> (natural -> string) -> - (natural -> string) -> natural -> string*) -let string_of_section_type os proc user i:string= - (if Nat_big_num.equal i sht_null then - "NULL" - else if Nat_big_num.equal i sht_progbits then - "PROGBITS" - else if Nat_big_num.equal i sht_symtab then - "SYMTAB" - else if Nat_big_num.equal i sht_strtab then - "STRTAB" - else if Nat_big_num.equal i sht_rela then - "RELA" - else if Nat_big_num.equal i sht_hash then - "HASH" - else if Nat_big_num.equal i sht_dynamic then - "DYNAMIC" - else if Nat_big_num.equal i sht_note then - "NOTE" - else if Nat_big_num.equal i sht_nobits then - "NOBITS" - else if Nat_big_num.equal i sht_rel then - "REL" - else if Nat_big_num.equal i sht_shlib then - "SHLIB" - else if Nat_big_num.equal i sht_dynsym then - "DYNSYM" - else if Nat_big_num.equal i sht_init_array then - "INIT_ARRAY" - else if Nat_big_num.equal i sht_fini_array then - "FINI_ARRAY" - else if Nat_big_num.equal i sht_preinit_array then - "PREINIT_ARRAY" - else if Nat_big_num.equal i sht_group then - "GROUP" - else if Nat_big_num.equal i sht_symtab_shndx then - "SYMTAB_SHNDX" - else if Nat_big_num.greater_equal i sht_loos && Nat_big_num.less_equal i sht_hios then - os i - else if Nat_big_num.greater_equal i sht_loproc && Nat_big_num.less_equal i sht_hiproc then - proc i - else if Nat_big_num.greater_equal i sht_louser && Nat_big_num.less_equal i sht_hiuser then - user i - else - "Undefined or invalid section type") - -(** Section flag numeric values. *) - -(** The section contains data that should be writable during program execution. - *) -let shf_write : Nat_big_num.num= (Nat_big_num.of_int 1) -(** The section occupies memory during program execution. - *) -let shf_alloc : Nat_big_num.num= (Nat_big_num.of_int 2) -(** The section contains executable instructions. - *) -let shf_execinstr : Nat_big_num.num= (Nat_big_num.of_int 4) -(** The data in the section may be merged to reduce duplication. Each section - * is compared based on name, type and flags set with sections with identical - * values at run time being mergeable. - *) -let shf_merge : Nat_big_num.num= (Nat_big_num.of_int 16) -(** The section contains null-terminated character strings. - *) -let shf_strings : Nat_big_num.num= (Nat_big_num.of_int 32) -(** The [info] field of this section header contains a section header table - * index. - *) -let shf_info_link : Nat_big_num.num= (Nat_big_num.of_int 64) -(** Adds special link ordering for link editors. - *) -let shf_link_order : Nat_big_num.num= (Nat_big_num.of_int 128) -(** This section requires special OS-specific processing beyond the standard - * link rules. - *) -let shf_os_nonconforming : Nat_big_num.num= (Nat_big_num.of_int 256) -(** This section is a member (potentially the only member) of a link group. - *) -let shf_group : Nat_big_num.num= (Nat_big_num.of_int 512) -(** This section contains Thread Local Storage (TLS) meaning that each thread of - * execution has its own instance of this data. - *) -let shf_tls : Nat_big_num.num= (Nat_big_num.of_int 1024) -(** This section contains compressed data. Compressed data may not be marked as - * allocatable. - *) -let shf_compressed : Nat_big_num.num= (Nat_big_num.of_int 2048) -(** All bits included in these masks are reserved for OS and processor specific - * semantics respectively. - *) -let shf_mask_os : Nat_big_num.num= (Nat_big_num.of_int 267386880) (* 0x0ff00000 *) -let shf_mask_proc : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 4)(Nat_big_num.of_int 1006632960)) (* 0xf0000000 *) - -(** [string_of_section_flags os proc f] produces a string based representation - * of section flag [f]. Some section flags are defined by the ABI and are in - * reserved ranges, in which case the flag string is produced by functions - * [os] and [proc]. - * TODO: add more as validation tests require them. - *) -(*val string_of_section_flags : (natural -> string) -> (natural -> string) -> - natural -> string*) -let string_of_section_flags os proc f:string= - (if Nat_big_num.equal f shf_write then - "W" - else if Nat_big_num.equal f shf_alloc then - " A" - else if Nat_big_num.equal f shf_execinstr then - " X" - else if Nat_big_num.equal f (Nat_big_num.add shf_alloc shf_execinstr) then - " AX" - else if Nat_big_num.equal f (Nat_big_num.add shf_write shf_alloc) then - " WA" - else if Nat_big_num.equal f shf_merge then - " M " - else if Nat_big_num.equal f (Nat_big_num.add shf_merge shf_alloc) then - " AM" - else if Nat_big_num.equal f (Nat_big_num.add (Nat_big_num.add shf_merge shf_alloc) shf_strings) then - "AMS" - else if Nat_big_num.equal f (Nat_big_num.add (Nat_big_num.add shf_alloc shf_execinstr) shf_group) then - "AXG" - else if Nat_big_num.equal f shf_strings then - " S" - else if Nat_big_num.equal f (Nat_big_num.add shf_merge shf_strings) then - " MS" - else if Nat_big_num.equal f shf_tls then - " T" - else if Nat_big_num.equal f (Nat_big_num.add shf_tls shf_alloc) then - " AT" - else if Nat_big_num.equal f (Nat_big_num.add (Nat_big_num.add shf_write shf_alloc) shf_tls) then - "WAT" - else if Nat_big_num.equal f shf_info_link then - " I" - else if Nat_big_num.equal f (Nat_big_num.add shf_alloc shf_info_link) then - " AI" - else - " ") - -(** Section compression. *) - -(** Type [elf32_compression_header] provides information about the compression and - * decompression of compressed sections. All compressed sections on ELF32 begin - * with an [elf32_compression_header] entry. - *) -type elf32_compression_header = - { elf32_chdr_type : Uint32.uint32 (** Specifies the compression algorithm *) - ; elf32_chdr_size : Uint32.uint32 (** Size in bytes of the uncompressed data *) - ; elf32_chdr_addralign : Uint32.uint32 (** Specifies the required alignment of the uncompressed data *) - } - -(** Type [elf64_compression_header] provides information about the compression and - * decompression of compressed sections. All compressed sections on ELF64 begin - * with an [elf64_compression_header] entry. - *) -type elf64_compression_header = - { elf64_chdr_type : Uint32.uint32 (** Specified the compression algorithm *) - ; elf64_chdr_reserved : Uint32.uint32 (** Reserved. *) - ; elf64_chdr_size : Uint64.uint64 (** Size in bytes of the uncompressed data *) - ; elf64_chdr_addralign : Uint64.uint64 (** Specifies the required alignment of the uncompressed data *) - } - -(** This section is compressed with the ZLIB algorithm. The compressed data begins - * at the first byte immediately following the end of the compression header. - *) -let elfcompress_zlib : Nat_big_num.num= (Nat_big_num.of_int 1) - -(** Values in these ranges are reserved for OS-specific semantics. - *) -let elfcompress_loos : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 4)(Nat_big_num.of_int 402653184)) (* 0x60000000 *) -let elfcompress_hios : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 939524095))(Nat_big_num.of_int 1)) (* 0x6fffffff *) - -(** Values in these ranges are reserved for processor-specific semantics. - *) -let elfcompress_loproc : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 4)(Nat_big_num.of_int 469762048)) (* 0x70000000 *) -let elfcompress_hiproc : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 1073741823))(Nat_big_num.of_int 1)) (* 0x7fffffff *) - -(** [read_elf32_compression_header ed bs0] reads an [elf32_compression_header] - * entry from byte sequence [bs0], interpreting [bs0] with endianness [ed]. - * Also returns the suffix of [bs0] after reading in the compression header. - * Fails if the header cannot be read. - *) -(*val read_elf32_compression_header : endianness -> byte_sequence -> - error (elf32_compression_header * byte_sequence)*) -let read_elf32_compression_header ed bs0:(elf32_compression_header*byte_sequence)error= - (read_elf32_word ed bs0 >>= (fun (typ, bs1) -> - read_elf32_word ed bs1 >>= (fun (siz, bs2) -> - read_elf32_word ed bs2 >>= (fun (ali, bs3) -> - return ({ elf32_chdr_type = typ; elf32_chdr_size = siz; - elf32_chdr_addralign = ali }, bs3))))) - -(** [read_elf64_compression_header ed bs0] reads an [elf64_compression_header] - * entry from byte sequence [bs0], interpreting [bs0] with endianness [ed]. - * Also returns the suffix of [bs0] after reading in the compression header. - * Fails if the header cannot be read. - *) -(*val read_elf64_compression_header : endianness -> byte_sequence -> - error (elf64_compression_header * byte_sequence)*) -let read_elf64_compression_header ed bs0:(elf64_compression_header*byte_sequence)error= - (read_elf64_word ed bs0 >>= (fun (typ, bs1) -> - read_elf64_word ed bs1 >>= (fun (res, bs2) -> - read_elf64_xword ed bs2 >>= (fun (siz, bs3) -> - read_elf64_xword ed bs3 >>= (fun (ali, bs4) -> - return ({ elf64_chdr_type = typ; elf64_chdr_reserved = res; - elf64_chdr_size = siz; elf64_chdr_addralign = ali }, bs4)))))) - -(** Section header table entry type. *) - -(** [elf32_section_header_table_entry] is the type of entries in the section - * header table in 32-bit ELF files. Each entry in the table details a section - * in the body of the ELF file. - *) -type elf32_section_header_table_entry = - { elf32_sh_name : Uint32.uint32 (** Name of the section *) - ; elf32_sh_type : Uint32.uint32 (** Type of the section and its semantics *) - ; elf32_sh_flags : Uint32.uint32 (** Flags associated with the section *) - ; elf32_sh_addr : Uint32.uint32 (** Address of first byte of section in memory image *) - ; elf32_sh_offset : Uint32.uint32 (** Offset from beginning of file of first byte of section *) - ; elf32_sh_size : Uint32.uint32 (** Section size in bytes *) - ; elf32_sh_link : Uint32.uint32 (** Section header table index link *) - ; elf32_sh_info : Uint32.uint32 (** Extra information, contents depends on type of section *) - ; elf32_sh_addralign : Uint32.uint32 (** Alignment constraints for section *) - ; elf32_sh_entsize : Uint32.uint32 (** Size of each entry in table, if section is one *) - } - -let elf32_null_section_header:elf32_section_header_table_entry= - ({ elf32_sh_name = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf32_sh_type = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf32_sh_flags = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf32_sh_addr = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf32_sh_offset = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf32_sh_size = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf32_sh_link = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf32_sh_info = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf32_sh_addralign = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf32_sh_entsize = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - }) - -(** [compare_elf32_section_header_table_entry ent1 ent2] is an ordering comparison - * function on section header table entries suitable for use in constructing - * sets, finite maps and other ordered data types. - *) -(*val compare_elf32_section_header_table_entry : elf32_section_header_table_entry -> - elf32_section_header_table_entry -> ordering*) -let compare_elf32_section_header_table_entry h1 h2:int= - (lexicographic_compare Nat_big_num.compare - [Nat_big_num.of_string (Uint32.to_string h1.elf32_sh_name); - Nat_big_num.of_string (Uint32.to_string h1.elf32_sh_type); - Nat_big_num.of_string (Uint32.to_string h1.elf32_sh_flags); - Nat_big_num.of_string (Uint32.to_string h1.elf32_sh_addr); - Nat_big_num.of_string (Uint32.to_string h1.elf32_sh_offset); - Nat_big_num.of_string (Uint32.to_string h1.elf32_sh_size); - Nat_big_num.of_string (Uint32.to_string h1.elf32_sh_link); - Nat_big_num.of_string (Uint32.to_string h1.elf32_sh_info); - Nat_big_num.of_string (Uint32.to_string h1.elf32_sh_addralign); - Nat_big_num.of_string (Uint32.to_string h1.elf32_sh_entsize)] - [Nat_big_num.of_string (Uint32.to_string h2.elf32_sh_name); - Nat_big_num.of_string (Uint32.to_string h2.elf32_sh_type); - Nat_big_num.of_string (Uint32.to_string h2.elf32_sh_flags); - Nat_big_num.of_string (Uint32.to_string h2.elf32_sh_addr); - Nat_big_num.of_string (Uint32.to_string h2.elf32_sh_offset); - Nat_big_num.of_string (Uint32.to_string h2.elf32_sh_size); - Nat_big_num.of_string (Uint32.to_string h2.elf32_sh_link); - Nat_big_num.of_string (Uint32.to_string h2.elf32_sh_info); - Nat_big_num.of_string (Uint32.to_string h2.elf32_sh_addralign); - Nat_big_num.of_string (Uint32.to_string h2.elf32_sh_entsize)]) - -let instance_Basic_classes_Ord_Elf_section_header_table_elf32_section_header_table_entry_dict:(elf32_section_header_table_entry)ord_class= ({ - - compare_method = compare_elf32_section_header_table_entry; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(compare_elf32_section_header_table_entry f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (compare_elf32_section_header_table_entry f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(compare_elf32_section_header_table_entry f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (compare_elf32_section_header_table_entry f1 f2)(Pset.from_list compare [1; 0])))}) - -(** [elf64_section_header_table_entry] is the type of entries in the section - * header table in 64-bit ELF files. Each entry in the table details a section - * in the body of the ELF file. - *) -type elf64_section_header_table_entry = - { elf64_sh_name : Uint32.uint32 (** Name of the section *) - ; elf64_sh_type : Uint32.uint32 (** Type of the section and its semantics *) - ; elf64_sh_flags : Uint64.uint64 (** Flags associated with the section *) - ; elf64_sh_addr : Uint64.uint64 (** Address of first byte of section in memory image *) - ; elf64_sh_offset : Uint64.uint64 (** Offset from beginning of file of first byte of section *) - ; elf64_sh_size : Uint64.uint64 (** Section size in bytes *) - ; elf64_sh_link : Uint32.uint32 (** Section header table index link *) - ; elf64_sh_info : Uint32.uint32 (** Extra information, contents depends on type of section *) - ; elf64_sh_addralign : Uint64.uint64 (** Alignment constraints for section *) - ; elf64_sh_entsize : Uint64.uint64 (** Size of each entry in table, if section is one *) - } - -let elf64_null_section_header:elf64_section_header_table_entry= - ({ elf64_sh_name = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_sh_type = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_sh_flags = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_sh_addr = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_sh_offset = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_sh_size = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_sh_link = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_sh_info = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_sh_addralign = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_sh_entsize = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - }) - -(** [compare_elf64_section_header_table_entry ent1 ent2] is an ordering comparison - * function on section header table entries suitable for use in constructing - * sets, finite maps and other ordered data types. - *) -(*val compare_elf64_section_header_table_entry : elf64_section_header_table_entry -> - elf64_section_header_table_entry -> ordering*) -let compare_elf64_section_header_table_entry h1 h2:int= - (lexicographic_compare Nat_big_num.compare - [Nat_big_num.of_string (Uint32.to_string h1.elf64_sh_name); - Nat_big_num.of_string (Uint32.to_string h1.elf64_sh_type); - Ml_bindings.nat_big_num_of_uint64 h1.elf64_sh_flags; - Ml_bindings.nat_big_num_of_uint64 h1.elf64_sh_addr; - Nat_big_num.of_string (Uint64.to_string h1.elf64_sh_offset); - Ml_bindings.nat_big_num_of_uint64 h1.elf64_sh_size; - Nat_big_num.of_string (Uint32.to_string h1.elf64_sh_link); - Nat_big_num.of_string (Uint32.to_string h1.elf64_sh_info); - Ml_bindings.nat_big_num_of_uint64 h1.elf64_sh_addralign; - Ml_bindings.nat_big_num_of_uint64 h1.elf64_sh_entsize] - [Nat_big_num.of_string (Uint32.to_string h2.elf64_sh_name); - Nat_big_num.of_string (Uint32.to_string h2.elf64_sh_type); - Ml_bindings.nat_big_num_of_uint64 h2.elf64_sh_flags; - Ml_bindings.nat_big_num_of_uint64 h2.elf64_sh_addr; - Nat_big_num.of_string (Uint64.to_string h2.elf64_sh_offset); - Ml_bindings.nat_big_num_of_uint64 h2.elf64_sh_size; - Nat_big_num.of_string (Uint32.to_string h2.elf64_sh_link); - Nat_big_num.of_string (Uint32.to_string h2.elf64_sh_info); - Ml_bindings.nat_big_num_of_uint64 h2.elf64_sh_addralign; - Ml_bindings.nat_big_num_of_uint64 h2.elf64_sh_entsize]) - -let instance_Basic_classes_Ord_Elf_section_header_table_elf64_section_header_table_entry_dict:(elf64_section_header_table_entry)ord_class= ({ - - compare_method = compare_elf64_section_header_table_entry; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(compare_elf64_section_header_table_entry f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (compare_elf64_section_header_table_entry f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(compare_elf64_section_header_table_entry f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (compare_elf64_section_header_table_entry f1 f2)(Pset.from_list compare [1; 0])))}) - -(** Section header table type *) - -(** Type [elf32_section_header_table] represents a section header table for 32-bit - * ELF files. A section header table is an array (implemented as a list, here) - * of section header table entries. - *) -type elf32_section_header_table = elf32_section_header_table_entry - list - -(** Type [elf64_section_header_table] represents a section header table for 64-bit - * ELF files. A section header table is an array (implemented as a list, here) - * of section header table entries. - *) -type elf64_section_header_table = elf64_section_header_table_entry - list - -(** Parsing and blitting *) - -(** [bytes_of_elf32_section_header_table_entry ed ent] blits [ent] to a byte sequence - * assuming endianness [ed]. - *) -(*val bytes_of_elf32_section_header_table_entry : endianness -> - elf32_section_header_table_entry -> byte_sequence*) -let bytes_of_elf32_section_header_table_entry endian entry:byte_sequence= - (Byte_sequence.from_byte_lists [ - bytes_of_elf32_word endian entry.elf32_sh_name - ; bytes_of_elf32_word endian entry.elf32_sh_type - ; bytes_of_elf32_word endian entry.elf32_sh_flags - ; bytes_of_elf32_addr endian entry.elf32_sh_addr - ; bytes_of_elf32_off endian entry.elf32_sh_offset - ; bytes_of_elf32_word endian entry.elf32_sh_size - ; bytes_of_elf32_word endian entry.elf32_sh_link - ; bytes_of_elf32_word endian entry.elf32_sh_info - ; bytes_of_elf32_word endian entry.elf32_sh_addralign - ; bytes_of_elf32_word endian entry.elf32_sh_entsize - ]) - -(** [read_elf32_section_header_table_entry ed bs0] reads a section header table - * entry from [bs0] assuming endianness [ed]. Also returns the suffix of [bs0] - * after parsing. Fails if the entry cannot be read. - *) -(*val read_elf32_section_header_table_entry : endianness -> byte_sequence -> - error (elf32_section_header_table_entry * byte_sequence)*) -let read_elf32_section_header_table_entry endian bs:(elf32_section_header_table_entry*byte_sequence)error= - (read_elf32_word endian bs >>= (fun (sh_name, bs) -> - read_elf32_word endian bs >>= (fun (sh_type, bs) -> - read_elf32_word endian bs >>= (fun (sh_flags, bs) -> - read_elf32_addr endian bs >>= (fun (sh_addr, bs) -> - read_elf32_off endian bs >>= (fun (sh_offset, bs) -> - read_elf32_word endian bs >>= (fun (sh_size, bs) -> - read_elf32_word endian bs >>= (fun (sh_link, bs) -> - read_elf32_word endian bs >>= (fun (sh_info, bs) -> - read_elf32_word endian bs >>= (fun (sh_addralign, bs) -> - read_elf32_word endian 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 }, bs)))))))))))) - -(** [bytes_of_elf64_section_header_table_entry ed ent] blits [ent] to a byte sequence - * assuming endianness [ed]. - *) -(*val bytes_of_elf64_section_header_table_entry : endianness -> - elf64_section_header_table_entry -> byte_sequence*) -let bytes_of_elf64_section_header_table_entry endian entry:byte_sequence= - (Byte_sequence.from_byte_lists [ - bytes_of_elf64_word endian entry.elf64_sh_name - ; bytes_of_elf64_word endian entry.elf64_sh_type - ; bytes_of_elf64_xword endian entry.elf64_sh_flags - ; bytes_of_elf64_addr endian entry.elf64_sh_addr - ; bytes_of_elf64_off endian entry.elf64_sh_offset - ; bytes_of_elf64_xword endian entry.elf64_sh_size - ; bytes_of_elf64_word endian entry.elf64_sh_link - ; bytes_of_elf64_word endian entry.elf64_sh_info - ; bytes_of_elf64_xword endian entry.elf64_sh_addralign - ; bytes_of_elf64_xword endian entry.elf64_sh_entsize - ]) - -(** [read_elf64_section_header_table_entry ed bs0] reads a section header table - * entry from [bs0] assuming endianness [ed]. Also returns the suffix of [bs0] - * after parsing. Fails if the entry cannot be read. - *) -(*val read_elf64_section_header_table_entry : endianness -> byte_sequence -> - error (elf64_section_header_table_entry * byte_sequence)*) -let read_elf64_section_header_table_entry endian bs:(elf64_section_header_table_entry*byte_sequence)error= - (read_elf64_word endian bs >>= (fun (sh_name, bs) -> - read_elf64_word endian bs >>= (fun (sh_type, bs) -> - read_elf64_xword endian bs >>= (fun (sh_flags, bs) -> - read_elf64_addr endian bs >>= (fun (sh_addr, bs) -> - read_elf64_off endian bs >>= (fun (sh_offset, bs) -> - read_elf64_xword endian bs >>= (fun (sh_size, bs) -> - read_elf64_word endian bs >>= (fun (sh_link, bs) -> - read_elf64_word endian bs >>= (fun (sh_info, bs) -> - read_elf64_xword endian bs >>= (fun (sh_addralign, bs) -> - read_elf64_xword endian bs >>= (fun (sh_entsize, bs) -> - return ({ elf64_sh_name = sh_name; elf64_sh_type = sh_type; - elf64_sh_flags = sh_flags; elf64_sh_addr = sh_addr; - elf64_sh_offset = sh_offset; elf64_sh_size = sh_size; - elf64_sh_link = sh_link; elf64_sh_info = sh_info; - elf64_sh_addralign = sh_addralign; elf64_sh_entsize = sh_entsize }, bs)))))))))))) - -(** [bytes_of_elf32_section_header_table ed tbl] blits section header table [tbl] - * to a byte sequence assuming endianness [ed]. - *) -(*val bytes_of_elf32_section_header_table : endianness -> - elf32_section_header_table -> byte_sequence*) -let bytes_of_elf32_section_header_table endian tbl:byte_sequence= - (Byte_sequence.concat0 (Lem_list.map (bytes_of_elf32_section_header_table_entry endian) tbl)) - -(** [bytes_of_elf64_section_header_table ed tbl] blits section header table [tbl] - * to a byte sequence assuming endianness [ed]. - *) -(*val bytes_of_elf64_section_header_table : endianness -> - elf64_section_header_table -> byte_sequence*) -let bytes_of_elf64_section_header_table endian tbl:byte_sequence= - (Byte_sequence.concat0 (Lem_list.map (bytes_of_elf64_section_header_table_entry endian) tbl)) - -(** [read_elf32_section_header_table' ed bs0] parses an ELF32 section header table - * from byte sequence [bs0] assuming endianness [ed]. Assumes [bs0] is of the - * exact length required to parse the entire table. - * Fails if any of the section header table entries cannot be parsed. - *) -(*val read_elf32_section_header_table' : endianness -> byte_sequence -> - error elf32_section_header_table*) -let rec read_elf32_section_header_table' endian bs0:((elf32_section_header_table_entry)list)error= - (if Nat_big_num.equal (Byte_sequence.length0 bs0)(Nat_big_num.of_int 0) then - return [] - else - read_elf32_section_header_table_entry endian bs0 >>= (fun (entry, bs1) -> - read_elf32_section_header_table' endian bs1 >>= (fun tail -> - return (entry::tail)))) - -(** [read_elf64_section_header_table' ed bs0] parses an ELF64 section header table - * from byte sequence [bs0] assuming endianness [ed]. Assumes [bs0] is of the - * exact length required to parse the entire table. - * Fails if any of the section header table entries cannot be parsed. - *) -(*val read_elf64_section_header_table' : endianness -> byte_sequence -> - error elf64_section_header_table*) -let rec read_elf64_section_header_table' endian bs0:((elf64_section_header_table_entry)list)error= - (if Nat_big_num.equal (Byte_sequence.length0 bs0)(Nat_big_num.of_int 0) then - return [] - else - read_elf64_section_header_table_entry endian bs0 >>= (fun (entry, bs1) -> - read_elf64_section_header_table' endian bs1 >>= (fun tail -> - return (entry::tail)))) - -(** [read_elf32_section_header_table sz ed bs0] parses an ELF32 section header - * table from a [sz] sized prefix of byte sequence [bs0] assuming endianness - * [ed]. The suffix of [bs0] remaining after parsing is also returned. - * Fails if any of the section header entries cannot be parsed or if [sz] is - * greater than the length of [bs0]. - *) -(*val read_elf32_section_header_table : natural -> endianness -> byte_sequence -> - error (elf32_section_header_table * byte_sequence)*) -let read_elf32_section_header_table table_size endian bs0:((elf32_section_header_table_entry)list*byte_sequence)error= - (partition0 table_size bs0 >>= (fun (eat, rest) -> - read_elf32_section_header_table' endian eat >>= (fun entries -> - return (entries, rest)))) - - -(** [read_elf64_section_header_table sz ed bs0] parses an ELF64 section header - * table from a [sz] sized prefix of byte sequence [bs0] assuming endianness - * [ed]. The suffix of [bs0] remaining after parsing is also returned. - * Fails if any of the section header entries cannot be parsed or if [sz] is - * greater than the length of [bs0]. - *) -(*val read_elf64_section_header_table : natural -> endianness -> byte_sequence -> - error (elf64_section_header_table * byte_sequence)*) -let read_elf64_section_header_table table_size endian bs0:((elf64_section_header_table_entry)list*byte_sequence)error= - (partition0 table_size bs0 >>= (fun (eat, rest) -> - read_elf64_section_header_table' endian eat >>= (fun entries -> - return (entries, rest)))) - - -(** Correctness criteria *) - -(** TODO: what is going on here? *) -(*val elf32_size_correct : elf32_section_header_table_entry -> - elf32_section_header_table -> bool*) -let elf32_size_correct hdr tbl:bool= - (let m = (Nat_big_num.of_string (Uint32.to_string hdr.elf32_sh_size)) in - if Nat_big_num.equal m(Nat_big_num.of_int 0) then - true - else Nat_big_num.equal - m (Nat_big_num.of_int (List.length tbl))) - - -(** TODO: what is going on here? *) -(*val elf64_size_correct : elf64_section_header_table_entry -> - elf64_section_header_table -> bool*) -let elf64_size_correct hdr tbl:bool= - (let m = (Ml_bindings.nat_big_num_of_uint64 hdr.elf64_sh_size) in - if Nat_big_num.equal m(Nat_big_num.of_int 0) then - true - else Nat_big_num.equal - m (Nat_big_num.of_int (List.length tbl))) - - -(** [is_elf32_addr_addralign_correct ent] checks whether an internal address - * alignment constraint is met on section header table [ent]. - * TODO: needs tweaking to add in power-of-two constraint, too. - *) -(*val is_elf32_addr_addralign_correct : elf32_section_header_table_entry -> bool*) -let is_elf32_addr_addralign_correct ent:bool= - (let align = (Nat_big_num.of_string (Uint32.to_string ent.elf32_sh_addralign)) in - let addr = (Nat_big_num.of_string (Uint32.to_string ent.elf32_sh_addr)) in - if Nat_big_num.equal (Nat_big_num.modulus addr align)(Nat_big_num.of_int 0) then Nat_big_num.equal - align(Nat_big_num.of_int 0) || Nat_big_num.equal align(Nat_big_num.of_int 1) (* TODO: or a power of two *) - else - false) - -(** [is_elf64_addr_addralign_correct ent] checks whether an internal address - * alignment constraint is met on section header table [ent]. - * TODO: needs tweaking to add in power-of-two constraint, too. - *) -(*val is_elf64_addr_addralign_correct : elf64_section_header_table_entry -> bool*) -let is_elf64_addr_addralign_correct ent:bool= - (let align = (Ml_bindings.nat_big_num_of_uint64 ent.elf64_sh_addralign) in - let addr = (Ml_bindings.nat_big_num_of_uint64 ent.elf64_sh_addr) in - if Nat_big_num.equal (Nat_big_num.modulus addr align)(Nat_big_num.of_int 0) then Nat_big_num.equal - align(Nat_big_num.of_int 0) || Nat_big_num.equal align(Nat_big_num.of_int 1) (* TODO: or a power of two *) - else - false) - -(** [is_valid_elf32_section_header_table sht] checks whether all entries of - * section header table [sht] are valid. - *) -(*val is_valid_elf32_section_header_table : elf32_section_header_table -> bool*) -let is_valid_elf32_section_header_table tbl:bool= - ((match tbl with - | [] -> true - | x::xs -> Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string x.elf32_sh_name))(Nat_big_num.of_int 0) && (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string x.elf32_sh_type)) sht_null && (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string x.elf32_sh_flags))(Nat_big_num.of_int 0) && (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string x.elf32_sh_addr))(Nat_big_num.of_int 0) && (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string x.elf32_sh_offset))(Nat_big_num.of_int 0) && (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string x.elf32_sh_info))(Nat_big_num.of_int 0) && (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string x.elf32_sh_addralign))(Nat_big_num.of_int 0) && (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string x.elf32_sh_entsize))(Nat_big_num.of_int 0) && - elf32_size_correct x tbl))))))) - (* XXX: more correctness criteria in time *) - )) - -(** [is_valid_elf64_section_header_table sht] checks whether all entries of - * section header table [sht] are valid. - *) -(*val is_valid_elf64_section_header_table : elf64_section_header_table -> bool*) -let is_valid_elf64_section_header_table tbl:bool= - ((match tbl with - | [] -> true - | x::xs -> Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string x.elf64_sh_name))(Nat_big_num.of_int 0) && (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string x.elf64_sh_type)) sht_null && (Nat_big_num.equal -(Ml_bindings.nat_big_num_of_uint64 x.elf64_sh_flags)(Nat_big_num.of_int 0) && (Nat_big_num.equal -(Ml_bindings.nat_big_num_of_uint64 x.elf64_sh_addr)(Nat_big_num.of_int 0) && (Nat_big_num.equal -(Nat_big_num.of_string (Uint64.to_string x.elf64_sh_offset))(Nat_big_num.of_int 0) && (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string x.elf64_sh_info))(Nat_big_num.of_int 0) && (Nat_big_num.equal -(Ml_bindings.nat_big_num_of_uint64 x.elf64_sh_addralign)(Nat_big_num.of_int 0) && (Nat_big_num.equal -(Ml_bindings.nat_big_num_of_uint64 x.elf64_sh_entsize)(Nat_big_num.of_int 0) && - elf64_size_correct x tbl))))))) - (* XXX: more correctness criteria in time *) - )) - -(** Pretty printing *) - -(** The [sht_print_bundle] type is used to tidy up other type signatures. Some of the - * top-level string_of_ functions require six or more functions passed to them, - * which quickly gets out of hand. This type is used to reduce that complexity. - * The first component of the type is an OS specific print function, the second is - * a processor specific print function. - *) -type sht_print_bundle = - (Nat_big_num.num -> string) * (Nat_big_num.num -> string) * (Nat_big_num.num -> string) - -(** [string_of_elf32_section_header_table_entry sht ent] produces a string - * representation of section header table entry [ent] using [sht], a - * [sht_print_bundle]. - * OCaml specific definition. - *) -(*val string_of_elf32_section_header_table_entry : sht_print_bundle -> - elf32_section_header_table_entry -> string*) -let string_of_elf32_section_header_table_entry (os, proc, user) entry:string= - (unlines [ -("\t" ^ ("Name: " ^ Uint32.to_string entry.elf32_sh_name)) - ; ("\t" ^ ("Type: " ^ string_of_section_type os proc user (Nat_big_num.of_string (Uint32.to_string entry.elf32_sh_type)))) - ; ("\t" ^ ("Flags: " ^ Uint32.to_string entry.elf32_sh_flags)) - ; ("\t" ^ ("Address: " ^ Uint32.to_string entry.elf32_sh_addr)) - ; ("\t" ^ ("Size: " ^ Uint32.to_string entry.elf32_sh_size)) - ]) - -(** [string_of_elf64_section_header_table_entry sht ent] produces a string - * representation of section header table entry [ent] using [sht], a - * [sht_print_bundle]. - * OCaml specific definition. - *) -(*val string_of_elf64_section_header_table_entry : sht_print_bundle -> - elf64_section_header_table_entry -> string*) -let string_of_elf64_section_header_table_entry (os, proc, user) entry:string= - (unlines [ -("\t" ^ ("Name: " ^ Uint32.to_string entry.elf64_sh_name)) - ; ("\t" ^ ("Type: " ^ string_of_section_type os proc user (Nat_big_num.of_string (Uint32.to_string entry.elf64_sh_type)))) - ; ("\t" ^ ("Flags: " ^ Uint64.to_string entry.elf64_sh_flags)) - ; ("\t" ^ ("Address: " ^ Uint64.to_string entry.elf64_sh_addr)) - ; ("\t" ^ ("Size: " ^ Uint64.to_string entry.elf64_sh_size)) - ]) - -(** [string_of_elf32_section_header_table_entry' sht stab ent] produces a string - * representation of section header table entry [ent] using [sht] and section - * header string table [stab] to print the name of the section header entry - * correctly. - * OCaml specific definition. - *) -(*val string_of_elf32_section_header_table_entry' : sht_print_bundle -> - string_table -> elf32_section_header_table_entry -> string*) -let string_of_elf32_section_header_table_entry' (os, proc, user) stbl entry:string= - (let name1 = -((match get_string_at (Nat_big_num.of_string (Uint32.to_string entry.elf32_sh_name)) stbl with - | Fail _ -> "Invalid index into string table" - | Success i -> i - )) - in - unlines [ -("\t" ^ ("Name: " ^ name1)) - ; ("\t" ^ ("Type: " ^ string_of_section_type os proc user (Nat_big_num.of_string (Uint32.to_string entry.elf32_sh_type)))) - ; ("\t" ^ ("Flags: " ^ Uint32.to_string entry.elf32_sh_flags)) - ; ("\t" ^ ("Address: " ^ Uint32.to_string entry.elf32_sh_addr)) - ; ("\t" ^ ("Size: " ^ Uint32.to_string entry.elf32_sh_size)) - ]) - -(** [string_of_elf64_section_header_table_entry' sht stab ent] produces a string - * representation of section header table entry [ent] using [sht] and section - * header string table [stab] to print the name of the section header entry - * correctly. - * OCaml specific definition. - *) -(*val string_of_elf64_section_header_table_entry' : sht_print_bundle -> - string_table -> elf64_section_header_table_entry -> string*) -let string_of_elf64_section_header_table_entry' (os, proc, user) stbl entry:string= - (let name1 = -((match get_string_at (Nat_big_num.of_string (Uint32.to_string entry.elf64_sh_name)) stbl with - | Fail _ -> "Invalid index into string table" - | Success i -> i - )) - in - unlines [ -("\t" ^ ("Name: " ^ name1)) - ; ("\t" ^ ("Type: " ^ string_of_section_type os proc user (Nat_big_num.of_string (Uint32.to_string entry.elf64_sh_type)))) - ; ("\t" ^ ("Flags: " ^ Uint64.to_string entry.elf64_sh_flags)) - ; ("\t" ^ ("Address: " ^ Uint64.to_string entry.elf64_sh_addr)) - ; ("\t" ^ ("Size: " ^ Uint64.to_string entry.elf64_sh_size)) - ]) - -(** The following defintions are default printing functions, with no ABI-specific - * functionality, in order to produce a [Show] instance for section header - * table entries. - *) - -(*val string_of_elf32_section_header_table_entry_default : elf32_section_header_table_entry -> string*) -let string_of_elf32_section_header_table_entry_default:elf32_section_header_table_entry ->string= - (string_of_elf32_section_header_table_entry - (((fun y->"*Default OS specific print*")), - ((fun y->"*Default processor specific print*")), - ((fun y->"*Default user specific print*")))) - -let instance_Show_Show_Elf_section_header_table_elf32_section_header_table_entry_dict:(elf32_section_header_table_entry)show_class= ({ - - show_method = string_of_elf32_section_header_table_entry_default}) - -(*val string_of_elf64_section_header_table_entry_default : elf64_section_header_table_entry -> string*) -let string_of_elf64_section_header_table_entry_default:elf64_section_header_table_entry ->string= - (string_of_elf64_section_header_table_entry - (((fun y->"*Default OS specific print*")), - ((fun y->"*Default processor specific print*")), - ((fun y->"*Default user specific print*")))) - -let instance_Show_Show_Elf_section_header_table_elf64_section_header_table_entry_dict:(elf64_section_header_table_entry)show_class= ({ - - show_method = string_of_elf64_section_header_table_entry_default}) - -(*val string_of_elf32_section_header_table : sht_print_bundle -> - elf32_section_header_table -> string*) -let string_of_elf32_section_header_table sht_bdl tbl:string= - (unlines (Lem_list.map (string_of_elf32_section_header_table_entry sht_bdl) tbl)) - -(*val string_of_elf32_section_header_table_default : elf32_section_header_table -> - string*) -let string_of_elf32_section_header_table_default:elf32_section_header_table ->string= - (string_of_elf32_section_header_table - (((fun y->"*Default OS specific print*")), - ((fun y->"*Default processor specific print*")), - ((fun y->"*Default user specific print*")))) - -(*val string_of_elf64_section_header_table : sht_print_bundle -> - elf64_section_header_table -> string*) -let string_of_elf64_section_header_table sht_bdl tbl:string= - (unlines (Lem_list.map (string_of_elf64_section_header_table_entry sht_bdl) tbl)) - -(*val string_of_elf64_section_header_table_default : elf64_section_header_table -> - string*) -let string_of_elf64_section_header_table_default:elf64_section_header_table ->string= - (string_of_elf64_section_header_table - (((fun y->"*Default OS specific print*")), - ((fun y->"*Default processor specific print*")), - ((fun y->"*Default user specific print*")))) - -(*val string_of_elf32_section_header_table' : sht_print_bundle -> string_table -> - elf32_section_header_table -> string*) -let string_of_elf32_section_header_table' sht_bdl stbl tbl:string= - (unlines (Lem_list.map (string_of_elf32_section_header_table_entry' sht_bdl stbl) tbl)) - -(*val string_of_elf64_section_header_table' : sht_print_bundle -> string_table -> - elf64_section_header_table -> string*) -let string_of_elf64_section_header_table' sht_bdl stbl tbl:string= - (unlines (Lem_list.map (string_of_elf64_section_header_table_entry' sht_bdl stbl) tbl)) - -(** Section to segment mappings *) - -(** [elf32_tbss_special shdr seg] implements the ELF_TBSS_SPECIAL macro from readelf: - * - * #define ELF_TBSS_SPECIAL(sec_hdr, segment) \ - * (((sec_hdr)->sh_flags & SHF_TLS) != 0 \ - * && (sec_hdr)->sh_type == SHT_NOBITS \ - * && (segment)->p_type != PT_TLS) - * - * From readelf source code, file [internal.h]. - * - *) -(*val is_elf32_tbss_special : elf32_section_header_table_entry -> elf32_program_header_table_entry -> bool*) -let is_elf32_tbss_special sec_hdr segment:bool= (not ((Uint32.logand sec_hdr.elf32_sh_flags (Uint32.of_string (Nat_big_num.to_string shf_tls))) = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0)))) && -(( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string sec_hdr.elf32_sh_type)) sht_nobits) && - ( not (Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string segment.elf32_p_type)) elf_pt_tls)))) - -(** [elf64_tbss_special shdr seg] implements the ELF_TBSS_SPECIAL macro from readelf: - * - * #define ELF_TBSS_SPECIAL(sec_hdr, segment) \ - * (((sec_hdr)->sh_flags & SHF_TLS) != 0 \ - * && (sec_hdr)->sh_type == SHT_NOBITS \ - * && (segment)->p_type != PT_TLS) - * - * From readelf source code, file [internal.h]. - * - *) -(*val is_elf64_tbss_special : elf64_section_header_table_entry -> elf64_program_header_table_entry -> bool*) -let is_elf64_tbss_special sec_hdr segment:bool= (not ((Uint64.logand sec_hdr.elf64_sh_flags (Uint64.of_string (Nat_big_num.to_string shf_tls))) = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0)))) && -(( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string sec_hdr.elf64_sh_type)) sht_nobits) && - ( not (Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string segment.elf64_p_type)) elf_pt_tls)))) - -(** [get_elf32_section_to_segment_mapping hdr sht pht isin stbl] computes the - * section to segment mapping for an ELF file using information in the section - * header table [sht], program header table [pht] and file header [hdr]. A - * string table [stbl] is taken to produce the string output. The test whether - * a section lies withing a segment is ABI specific, so [isin] is used to perform - * the test. - *) -(*val get_elf32_section_to_segment_mapping : elf32_header -> elf32_section_header_table -> elf32_program_header_table_entry -> - (elf32_header -> elf32_section_header_table_entry -> elf32_program_header_table_entry -> bool) -> - string_table -> error (list string)*) -let rec get_elf32_section_to_segment_mapping hdr sects pent isin stbl:((string)list)error= - ((match sects with - | [] -> return [] - | x::xs -> - if is_elf32_tbss_special x pent then - get_elf32_section_to_segment_mapping hdr xs pent isin stbl - else if not (isin hdr x pent) then - get_elf32_section_to_segment_mapping hdr xs pent isin stbl - else - let nm = (Nat_big_num.of_string (Uint32.to_string x.elf32_sh_name)) in - get_string_at nm stbl >>= (fun str -> - get_elf32_section_to_segment_mapping hdr xs pent isin stbl >>= (fun tl -> - return (str :: tl))) - )) - -(** [get_elf64_section_to_segment_mapping hdr sht pht isin stbl] computes the - * section to segment mapping for an ELF file using information in the section - * header table [sht], program header table [pht] and file header [hdr]. A - * string table [stbl] is taken to produce the string output. The test whether - * a section lies withing a segment is ABI specific, so [isin] is used to perform - * the test. - *) -(*val get_elf64_section_to_segment_mapping : elf64_header -> elf64_section_header_table -> elf64_program_header_table_entry -> - (elf64_header -> elf64_section_header_table_entry -> elf64_program_header_table_entry -> bool) -> - string_table -> error (list string)*) -let rec get_elf64_section_to_segment_mapping hdr sects pent isin stbl:((string)list)error= - ((match sects with - | [] -> return [] - | x::xs -> - if not (isin hdr x pent) then - get_elf64_section_to_segment_mapping hdr xs pent isin stbl - else if is_elf64_tbss_special x pent then - get_elf64_section_to_segment_mapping hdr xs pent isin stbl - else - let nm = (Nat_big_num.of_string (Uint32.to_string x.elf64_sh_name)) in - get_string_at nm stbl >>= (fun str -> - get_elf64_section_to_segment_mapping hdr xs pent isin stbl >>= (fun tl -> - return (str :: tl))) - )) - -(** Section groups *) - -(** This is a COMDAT group and may duplicate other COMDAT groups in other object - * files. - *) -let grp_comdat : Nat_big_num.num= (Nat_big_num.of_int 1) - -(** Any bits in the following mask ranges are reserved exclusively for OS and - * processor specific semantics, respectively. - *) -let grp_maskos : Nat_big_num.num= (Nat_big_num.of_int 267386880) (* 0x0ff00000 *) -let grp_maskproc : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 4)(Nat_big_num.of_int 1006632960)) (* 0xf0000000 *) - -(** [obtain_elf32_section_group_indices endian sht bs0] extracts all section header - * table indices of sections that are marked as being part of a section group. - *) -(*val obtain_elf32_section_group_indices : endianness -> elf32_section_header_table -> byte_sequence - -> error (list (natural * list elf32_word))*) -let obtain_elf32_section_group_indices endian sht bs0:((Nat_big_num.num*(Uint32.uint32)list)list)error= - (let filtered = (List.filter (fun ent -> Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string ent.elf32_sh_type)) sht_group) sht) - in - mapM (fun grp -> - let off = (Nat_big_num.of_string (Uint32.to_string grp.elf32_sh_offset)) in - let siz = (Nat_big_num.of_string (Uint32.to_string grp.elf32_sh_size)) in - let cnt = (Nat_big_num.div siz(Nat_big_num.of_int 4)) (* size of elf32_word in bytes *) in - Byte_sequence.offset_and_cut off siz bs0 >>= (fun rel -> - Error.repeatM' cnt rel (read_elf32_word endian) >>= (fun (mems, _) -> - (match mems with - | [] -> fail "obtain_elf32_section_group_indices: section group sections must consist of at least one elf32_word" - | x::xs -> - let flag = (Nat_big_num.of_string (Uint32.to_string x)) in - return (flag, xs) - ))) - ) filtered) - -(** [obtain_elf64_section_group_indices endian sht bs0] extracts all section header - * table indices of sections that are marked as being part of a section group. - *) -(*val obtain_elf64_section_group_indices : endianness -> elf64_section_header_table -> byte_sequence - -> error (list (natural * list elf64_word))*) -let obtain_elf64_section_group_indices endian sht bs0:((Nat_big_num.num*(Uint32.uint32)list)list)error= - (let filtered = (List.filter (fun ent -> Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string ent.elf64_sh_type)) sht_group) sht) - in - mapM (fun grp -> - let off = (Nat_big_num.of_string (Uint64.to_string grp.elf64_sh_offset)) in - let siz = (Ml_bindings.nat_big_num_of_uint64 grp.elf64_sh_size) in - let cnt = (Nat_big_num.div siz(Nat_big_num.of_int 4)) (* size of elf64_word in bytes *) in - Byte_sequence.offset_and_cut off siz bs0 >>= (fun rel -> - Error.repeatM' cnt rel (read_elf64_word endian) >>= (fun (mems, _) -> - (match mems with - | [] -> fail "obtain_elf64_section_group_indices: section group sections must consist of at least one elf64_word" - | x::xs -> - let flag = (Nat_big_num.of_string (Uint32.to_string x)) in - return (flag, xs) - ))) - ) filtered) - -(** [obtain_elf32_tls_template sht] extracts the TLS template (i.e. all sections - * in section header table [sht] that have their TLS flag bit set). - *) -(*val obtain_elf32_tls_template : elf32_section_header_table -> elf32_section_header_table*) -let obtain_elf32_tls_template sht:(elf32_section_header_table_entry)list= - (List.filter (fun ent -> - let flags = (Nat_big_num.of_string (Uint32.to_string ent.elf32_sh_flags)) in not (Nat_big_num.equal (Nat_big_num.bitwise_and flags shf_tls)(Nat_big_num.of_int 0))) sht) - -(** [obtain_elf64_tls_template sht] extracts the TLS template (i.e. all sections - * in section header table [sht] that have their TLS flag bit set). - *) -(*val obtain_elf64_tls_template : elf64_section_header_table -> elf64_section_header_table*) -let obtain_elf64_tls_template sht:(elf64_section_header_table_entry)list= - (List.filter (fun ent -> - let flags = (Ml_bindings.nat_big_num_of_uint64 ent.elf64_sh_flags) in not (Nat_big_num.equal (Nat_big_num.bitwise_and flags shf_tls)(Nat_big_num.of_int 0))) sht) - -(** [obtain_elf32_hash_table endian sht bs0] extracts a hash table from an ELF file - * providing a section of type SHT_HASH exists in section header table [sht]. - * Extraction is from byte sequence [bs0] assuming endianness [endian]. The - * return type represents the number of buckets, the number of chains, the buckets - * and finally the chains. - *) -(*val obtain_elf32_hash_table : endianness -> elf32_section_header_table -> byte_sequence -> - error (elf32_word * elf32_word * list elf32_word * list elf32_word)*) -let obtain_elf32_hash_table endian sht bs0:(Uint32.uint32*Uint32.uint32*(Uint32.uint32)list*(Uint32.uint32)list)error= - (let filtered = (List.filter (fun ent -> Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string ent.elf32_sh_type)) sht_hash) sht) - in - (match filtered with - | [] -> fail "obtain_elf32_hash_table: no section header table entry of type sht_hash" - | [x] -> - let siz = (Nat_big_num.of_string (Uint32.to_string x.elf32_sh_size)) in - let off = (Nat_big_num.of_string (Uint32.to_string x.elf32_sh_offset)) in - Byte_sequence.offset_and_cut siz off bs0 >>= (fun rel -> - read_elf32_word endian rel >>= (fun (nbucket, rel) -> - read_elf32_word endian rel >>= (fun (nchain, rel) -> - Error.repeatM' (Nat_big_num.of_string (Uint32.to_string nbucket)) rel (read_elf32_word endian) >>= (fun (buckets, rel) -> - Error.repeatM' (Nat_big_num.of_string (Uint32.to_string nchain)) rel (read_elf32_word endian) >>= (fun (chain, _) -> - return (nbucket, nchain, buckets, chain)))))) - | _ -> fail "obtain_elf32_hash_table: multiple section header table entries of type sht_hash" - )) - -(** [obtain_elf64_hash_table endian sht bs0] extracts a hash table from an ELF file - * providing a section of type SHT_HASH exists in section header table [sht]. - * Extraction is from byte sequence [bs0] assuming endianness [endian]. The - * return type represents the number of buckets, the number of chains, the buckets - * and finally the chains. - *) -(*val obtain_elf64_hash_table : endianness -> elf64_section_header_table -> byte_sequence -> - error (elf64_word * elf64_word * list elf64_word * list elf64_word)*) -let obtain_elf64_hash_table endian sht bs0:(Uint32.uint32*Uint32.uint32*(Uint32.uint32)list*(Uint32.uint32)list)error= - (let filtered = (List.filter (fun ent -> Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string ent.elf64_sh_type)) sht_hash) sht) - in - (match filtered with - | [] -> fail "obtain_elf64_hash_table: no section header table entry of type sht_hash" - | [x] -> - let siz = (Ml_bindings.nat_big_num_of_uint64 x.elf64_sh_size) in - let off = (Nat_big_num.of_string (Uint64.to_string x.elf64_sh_offset)) in - Byte_sequence.offset_and_cut siz off bs0 >>= (fun rel -> - read_elf64_word endian rel >>= (fun (nbucket, rel) -> - read_elf64_word endian rel >>= (fun (nchain, rel) -> - Error.repeatM' (Nat_big_num.of_string (Uint32.to_string nbucket)) rel (read_elf64_word endian) >>= (fun (buckets, rel) -> - Error.repeatM' (Nat_big_num.of_string (Uint32.to_string nchain)) rel (read_elf64_word endian) >>= (fun (chain, _) -> - return (nbucket, nchain, buckets, chain)))))) - | _ -> fail "obtain_elf64_hash_table: multiple section header table entries of type sht_hash" - )) - -(** Special sections *) - -(** [construct_special_sections] contains a finite map from section name (as - * a string) to the expected attributes and flags expected of that section, - * as specified in the ELF specification. - * NOTE: some of these are overriden by the ABI. - *) -(*val elf_special_sections : Map.map string (natural * natural)*) -let elf_special_sections:((string),(Nat_big_num.num*Nat_big_num.num))Pmap.map= - (Lem_map.fromList (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) [ - (".bss", (sht_nobits, Nat_big_num.add shf_alloc shf_write)) - ; (".comment", (sht_progbits,Nat_big_num.of_int 0)) - ; (".data", (sht_progbits, Nat_big_num.add shf_alloc shf_write)) - ; (".data1", (sht_progbits, Nat_big_num.add shf_alloc shf_write)) - ; (".debug", (sht_progbits,Nat_big_num.of_int 0)) - (* ; (".dynamic", (sht_dynamic, ?)) *) - ; (".dynstr", (sht_strtab, shf_alloc)) - ; (".dynsym", (sht_dynsym, shf_alloc)) - ; (".fini", (sht_progbits, Nat_big_num.add shf_alloc shf_execinstr)) - ; (".fini_array", (sht_fini_array, Nat_big_num.add shf_alloc shf_write)) - (* ; (".got", (sht_progbits, ?)) *) - ; (".hash", (sht_hash, shf_alloc)) - ; (".init", (sht_progbits, Nat_big_num.add shf_alloc shf_execinstr)) - ; (".init_array", (sht_init_array, Nat_big_num.add shf_alloc shf_write)) - (* ; (".interp", (sht_progbits, ?)) *) - ; (".line", (sht_progbits,Nat_big_num.of_int 0)) - ; (".note", (sht_note,Nat_big_num.of_int 0)) - (* ; (".plt", (sht_progbits, ?)) *) - ; (".preinit_array", (sht_preinit_array, Nat_big_num.add shf_alloc shf_write)) - (* ; (".relname", (sht_rel, ?)) *) - (* ; (".relaname", (sht_rela, ?)) *) - ; (".rodata", (sht_progbits, shf_alloc)) - ; (".rodata1", (sht_progbits, shf_alloc)) - ; (".shstrtab", (sht_strtab,Nat_big_num.of_int 0)) - (* ; (".strtab", (sht_strtab, ?)) *) - (* ; (".symtab", (sht_symtab, ?)) *) - (* ; (".symtab_shndx", (sht_symtab_shndx, ?)) *) - ; (".tbss", (sht_nobits, Nat_big_num.add (Nat_big_num.add shf_alloc shf_write) shf_tls)) - ; (".tdata", (sht_progbits, Nat_big_num.add (Nat_big_num.add shf_alloc shf_write) shf_tls)) - ; (".tdata1", (sht_progbits, Nat_big_num.add (Nat_big_num.add shf_alloc shf_write) shf_tls)) - ; (".text", (sht_progbits, Nat_big_num.add shf_alloc shf_execinstr)) - ]) diff --git a/lib/ocaml_rts/linksem/elf_symbol_table.ml b/lib/ocaml_rts/linksem/elf_symbol_table.ml deleted file mode 100644 index fc8dc068..00000000 --- a/lib/ocaml_rts/linksem/elf_symbol_table.ml +++ /dev/null @@ -1,563 +0,0 @@ -(*Generated by Lem from elf_symbol_table.lem.*) -(** [elf_symbol_table] provides types, functions and other definitions for - * working with ELF symbol tables. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_list -open Lem_maybe -open Lem_num -open Lem_string -open Lem_tuple -(*import Set*) - -open Byte_sequence -open Error -open Missing_pervasives -open Show - -open Elf_header -open Elf_types_native_uint -open Endianness -open String_table - -(** Undefined symbol index *) - -let stn_undef : Nat_big_num.num= (Nat_big_num.of_int 0) - -(** Symbol binding *) - -(** Local symbols are not visible outside of the object file containing their - * definition. - *) -let stb_local : Nat_big_num.num= (Nat_big_num.of_int 0) - -(** Global symbols are visible to all object files being combined. - *) -let stb_global : Nat_big_num.num= (Nat_big_num.of_int 1) - -(** Weak symbols resemble global symbols but their definitions have lower - * precedence. - *) -let stb_weak : Nat_big_num.num= (Nat_big_num.of_int 2) - -(** Values in the following range have reserved OS specific semantics. - *) -let stb_loos : Nat_big_num.num= (Nat_big_num.of_int 10) -let stb_hios : Nat_big_num.num= (Nat_big_num.of_int 12) - -(** Values in the following range have reserved processor specific semantics. - *) -let stb_loproc : Nat_big_num.num= (Nat_big_num.of_int 13) -let stb_hiproc : Nat_big_num.num= (Nat_big_num.of_int 15) - -(** string_of_symbol_binding b os proc] produces a string representation of - * binding [m] using printing functions [os] and [proc] for OS- and processor- - * specific values respectively. - * OCaml specific definition. - *) -(*val string_of_symbol_binding : natural -> (natural -> string) -> (natural -> string) -> string*) -let string_of_symbol_binding m os proc:string= - (if Nat_big_num.equal m stb_local then - "LOCAL" - else if Nat_big_num.equal m stb_global then - "GLOBAL" - else if Nat_big_num.equal m stb_weak then - "WEAK" - else if Nat_big_num.greater_equal m stb_loos && Nat_big_num.less_equal m stb_hios then - os m - else if Nat_big_num.greater_equal m stb_loproc && Nat_big_num.less_equal m stb_hiproc then - proc m - else - "Invalid symbol binding") - -(** Symbol types *) - -(** The symbol's type is not specified. - *) -let stt_notype : Nat_big_num.num= (Nat_big_num.of_int 0) - -(** The symbol is associated with a data object such as a variable. - *) -let stt_object : Nat_big_num.num= (Nat_big_num.of_int 1) - -(** The symbol is associated with a function or other executable code. - *) -let stt_func : Nat_big_num.num= (Nat_big_num.of_int 2) - -(** The symbol is associated with a section. - *) -let stt_section : Nat_big_num.num= (Nat_big_num.of_int 3) - -(** Conventionally the symbol's value gives the name of the source file associated - * with the object file. - *) -let stt_file : Nat_big_num.num= (Nat_big_num.of_int 4) - -(** The symbol is an uninitialised common block. - *) -let stt_common : Nat_big_num.num= (Nat_big_num.of_int 5) - -(** The symbol specified a Thread Local Storage (TLS) entity. - *) -let stt_tls : Nat_big_num.num= (Nat_big_num.of_int 6) - -(** Values in the following range are reserved solely for OS-specific semantics. - *) -let stt_loos : Nat_big_num.num= (Nat_big_num.of_int 10) -let stt_hios : Nat_big_num.num= (Nat_big_num.of_int 12) - -(** Values in the following range are reserved solely for processor-specific - * semantics. - *) -let stt_loproc : Nat_big_num.num= (Nat_big_num.of_int 13) -let stt_hiproc : Nat_big_num.num= (Nat_big_num.of_int 15) - -(** [string_of_symbol_type sym os proc] produces a string representation of - * symbol type [m] using [os] and [proc] to pretty-print values reserved for - * OS- and processor-specific functionality. - *) -(*val string_of_symbol_type : natural -> (natural -> string) -> (natural -> string) -> string*) -let string_of_symbol_type m os proc:string= - (if Nat_big_num.equal m stt_notype then - "NOTYPE" - else if Nat_big_num.equal m stt_object then - "OBJECT" - else if Nat_big_num.equal m stt_func then - "FUNC" - else if Nat_big_num.equal m stt_section then - "SECTION" - else if Nat_big_num.equal m stt_file then - "FILE" - else if Nat_big_num.equal m stt_common then - "COMMON" - else if Nat_big_num.equal m stt_tls then - "TLS" - else if Nat_big_num.greater_equal m stt_loos && Nat_big_num.less_equal m stt_hios then - os m - else if Nat_big_num.greater_equal m stt_loproc && Nat_big_num.less_equal m stt_hiproc then - proc m - else - "Invalid symbol type") - -(** Symbol visibility *) - -(** The visibility of the symbol is as specified by the symbol's binding type. - *) -let stv_default : Nat_big_num.num= (Nat_big_num.of_int 0) - -(** The meaning of this visibility may be defined by processor supplements to - * further constrain hidden symbols. - *) -let stv_internal : Nat_big_num.num= (Nat_big_num.of_int 1) - -(** The symbol's name is not visible in other components. - *) -let stv_hidden : Nat_big_num.num= (Nat_big_num.of_int 2) - -(** The symbol is visible in other components but not pre-emptable. That is, - * references to the symbol in the same component resolve to this symbol even - * if other symbols of the same name in other components would normally be - * resolved to instead if we followed the normal rules of symbol resolution. - *) -let stv_protected : Nat_big_num.num= (Nat_big_num.of_int 3) - -(** [string_of_symbol_visibility m] produces a string representation of symbol - * visibility [m]. - *) -(*val string_of_symbol_visibility : natural -> string*) -let string_of_symbol_visibility m:string= - (if Nat_big_num.equal m stv_default then - "DEFAULT" - else if Nat_big_num.equal m stv_internal then - "INTERNAL" - else if Nat_big_num.equal m stv_hidden then - "HIDDEN" - else if Nat_big_num.equal m stv_protected then - "PROTECTED" - else - "Invalid symbol visibility") - -(** Symbol table entry type *) - -(** [elf32_symbol_table_entry] is an entry in a symbol table. - *) -type elf32_symbol_table_entry = - { elf32_st_name : Uint32.uint32 (** Index into the object file's string table *) - ; elf32_st_value : Uint32.uint32 (** Gives the value of the associated symbol *) - ; elf32_st_size : Uint32.uint32 (** Size of the associated symbol *) - ; elf32_st_info : Uint32.uint32 (** Specifies the symbol's type and binding attributes *) - ; elf32_st_other : Uint32.uint32 (** Currently specifies the symbol's visibility *) - ; elf32_st_shndx : Uint32.uint32 (** Section header index symbol is defined with respect to *) - } - -(** [elf32_symbol_table_entry_compare ent1 ent2] is an ordering-comparison function - * for symbol table entries suitable for constructing sets, finite maps and other - * ordered data structures from. - *) -(*val elf32_symbol_table_entry_compare : elf32_symbol_table_entry -> - elf32_symbol_table_entry -> ordering*) -let elf32_symbol_table_entry_compare ent1 ent2:int= - (sextupleCompare Nat_big_num.compare Nat_big_num.compare Nat_big_num.compare Nat_big_num.compare Nat_big_num.compare Nat_big_num.compare (Nat_big_num.of_string (Uint32.to_string ent1.elf32_st_name), Nat_big_num.of_string (Uint32.to_string ent1.elf32_st_value), - Nat_big_num.of_string (Uint32.to_string ent1.elf32_st_size), Nat_big_num.of_string (Uint32.to_string ent1.elf32_st_info), - Nat_big_num.of_string (Uint32.to_string ent1.elf32_st_other), Nat_big_num.of_string (Uint32.to_string ent1.elf32_st_shndx)) - (Nat_big_num.of_string (Uint32.to_string ent2.elf32_st_name), Nat_big_num.of_string (Uint32.to_string ent2.elf32_st_value), - Nat_big_num.of_string (Uint32.to_string ent2.elf32_st_size), Nat_big_num.of_string (Uint32.to_string ent2.elf32_st_info), - Nat_big_num.of_string (Uint32.to_string ent2.elf32_st_other), Nat_big_num.of_string (Uint32.to_string ent2.elf32_st_shndx))) - -let instance_Basic_classes_Ord_Elf_symbol_table_elf32_symbol_table_entry_dict:(elf32_symbol_table_entry)ord_class= ({ - - compare_method = elf32_symbol_table_entry_compare; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(elf32_symbol_table_entry_compare f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (elf32_symbol_table_entry_compare f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(elf32_symbol_table_entry_compare f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (elf32_symbol_table_entry_compare f1 f2)(Pset.from_list compare [1; 0])))}) - -(** [elf64_symbol_table_entry] is an entry in a symbol table. - *) -type elf64_symbol_table_entry = - { elf64_st_name : Uint32.uint32 (** Index into the object file's string table *) - ; elf64_st_info : Uint32.uint32 (** Specifies the symbol's type and binding attributes *) - ; elf64_st_other : Uint32.uint32 (** Currently specifies the symbol's visibility *) - ; elf64_st_shndx : Uint32.uint32 (** Section header index symbol is defined with respect to *) - ; elf64_st_value : Uint64.uint64 (** Gives the value of the associated symbol *) - ; elf64_st_size : Uint64.uint64 (** Size of the associated symbol *) - } - -(** [elf64_symbol_table_entry_compare ent1 ent2] is an ordering-comparison function - * for symbol table entries suitable for constructing sets, finite maps and other - * ordered data structures from. - *) -(*val elf64_symbol_table_entry_compare : elf64_symbol_table_entry -> elf64_symbol_table_entry -> - ordering*) -let elf64_symbol_table_entry_compare ent1 ent2:int= - (sextupleCompare Nat_big_num.compare Nat_big_num.compare Nat_big_num.compare Nat_big_num.compare Nat_big_num.compare Nat_big_num.compare (Nat_big_num.of_string (Uint32.to_string ent1.elf64_st_name), Ml_bindings.nat_big_num_of_uint64 ent1.elf64_st_value, - Ml_bindings.nat_big_num_of_uint64 ent1.elf64_st_size, Nat_big_num.of_string (Uint32.to_string ent1.elf64_st_info), - Nat_big_num.of_string (Uint32.to_string ent1.elf64_st_other), Nat_big_num.of_string (Uint32.to_string ent1.elf64_st_shndx)) - (Nat_big_num.of_string (Uint32.to_string ent2.elf64_st_name), Ml_bindings.nat_big_num_of_uint64 ent2.elf64_st_value, - Ml_bindings.nat_big_num_of_uint64 ent2.elf64_st_size, Nat_big_num.of_string (Uint32.to_string ent2.elf64_st_info), - Nat_big_num.of_string (Uint32.to_string ent2.elf64_st_other), Nat_big_num.of_string (Uint32.to_string ent2.elf64_st_shndx))) - -let instance_Basic_classes_Ord_Elf_symbol_table_elf64_symbol_table_entry_dict:(elf64_symbol_table_entry)ord_class= ({ - - compare_method = elf64_symbol_table_entry_compare; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(elf64_symbol_table_entry_compare f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (elf64_symbol_table_entry_compare f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(elf64_symbol_table_entry_compare f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (elf64_symbol_table_entry_compare f1 f2)(Pset.from_list compare [1; 0])))}) - -type elf32_symbol_table = elf32_symbol_table_entry - list - -type elf64_symbol_table = elf64_symbol_table_entry - list - -(** Extraction of symbol table data *) - -(* Functions below common to 32- and 64-bit! *) - -(** [extract_symbol_binding u] extracts a symbol table entry's symbol binding. [u] - * in this case is the [elfXX_st_info] field from a symbol table entry. - *) -(*val extract_symbol_binding : unsigned_char -> natural*) -let extract_symbol_binding entry:Nat_big_num.num= - (Nat_big_num.of_string (Uint32.to_string (Uint32.shift_right entry( 4)))) - -(** [extract_symbol_type u] extracts a symbol table entry's symbol type. [u] - * in this case is the [elfXX_st_info] field from a symbol table entry. - *) -(*val extract_symbol_type : unsigned_char -> natural*) -let extract_symbol_type entry:Nat_big_num.num= - (Nat_big_num.of_string (Uint32.to_string (Uint32.logand entry (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 15)))))) (* 0xf *) - -(** [get_symbol_info u] extracts a symbol table entry's symbol info. [u] - * in this case is the [elfXX_st_info] field from a symbol table entry. - *) -(*val make_symbol_info : natural -> natural -> unsigned_char*) -let make_symbol_info binding1 symtype:Uint32.uint32= - (Uint32.add - (Uint32.shift_left (Uint32.of_string (Nat_big_num.to_string binding1))( 4)) - (Uint32.logand (Uint32.of_string (Nat_big_num.to_string symtype)) - (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 15))))) (*0xf*) - -(** [get_symbol_visibility u] extracts a symbol table entry's symbol visibility. [u] - * in this case is the [elfXX_st_other] field from a symbol table entry. - *) -(*val get_symbol_visibility : unsigned_char -> natural*) -let get_symbol_visibility info:Nat_big_num.num= - (Nat_big_num.of_string (Uint32.to_string (Uint32.logand info (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 3)))))) (* 0x3*) - -(** [make_symbol_other m] converts a natural [m] to an unsigned char suitable - * for use in a symbol table entry's "other" field. - * XXX: WHY? - *) -(*val make_symbol_other : natural -> unsigned_char*) -let make_symbol_other visibility:Uint32.uint32= - (Uint32.of_string (Nat_big_num.to_string visibility)) - -(** [is_elf32_shndx_too_large ent] tests whether the symbol table entry's - * [shndx] field is equal to SHN_XINDEX, in which case the real value is stored - * elsewhere. - *) -(*val is_elf32_shndx_too_large : elf32_symbol_table_entry -> bool*) -let is_elf32_shndx_too_large syment:bool= (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string syment.elf32_st_shndx)) shn_xindex) - -(** [is_elf64_shndx_too_large ent] tests whether the symbol table entry's - * [shndx] field is equal to SHN_XINDEX, in which case the real value is stored - * elsewhere. - *) -(*val is_elf64_shndx_too_large : elf64_symbol_table_entry -> bool*) -let is_elf64_shndx_too_large syment:bool= (Nat_big_num.equal -(Nat_big_num.of_string (Uint32.to_string syment.elf64_st_shndx)) shn_xindex) - -(** NULL tests *) - -(** [is_elf32_null_entry ent] tests whether [ent] is a null symbol table entry, - * i.e. all fields set to [0]. - *) -(*val is_elf32_null_entry : elf32_symbol_table_entry -> bool*) -let is_elf32_null_entry ent:bool= (Nat_big_num.equal - (Nat_big_num.of_string (Uint32.to_string ent.elf32_st_name))(Nat_big_num.of_int 0) - && (( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string ent.elf32_st_value))(Nat_big_num.of_int 0)) - && (( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string ent.elf32_st_size))(Nat_big_num.of_int 0)) - && (( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string ent.elf32_st_info))(Nat_big_num.of_int 0)) - && (( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string ent.elf32_st_other))(Nat_big_num.of_int 0)) - && ( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string ent.elf32_st_shndx))(Nat_big_num.of_int 0))))))) - -(** [is_elf64_null_entry ent] tests whether [ent] is a null symbol table entry, - * i.e. all fields set to [0]. - *) -(*val is_elf64_null_entry : elf64_symbol_table_entry -> bool*) -let is_elf64_null_entry ent:bool= (Nat_big_num.equal - (Nat_big_num.of_string (Uint32.to_string ent.elf64_st_name))(Nat_big_num.of_int 0) - && (( Nat_big_num.equal(Ml_bindings.nat_big_num_of_uint64 ent.elf64_st_value)(Nat_big_num.of_int 0)) - && (( Nat_big_num.equal(Ml_bindings.nat_big_num_of_uint64 ent.elf64_st_size)(Nat_big_num.of_int 0)) - && (( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string ent.elf64_st_info))(Nat_big_num.of_int 0)) - && (( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string ent.elf64_st_other))(Nat_big_num.of_int 0)) - && ( Nat_big_num.equal(Nat_big_num.of_string (Uint32.to_string ent.elf64_st_shndx))(Nat_big_num.of_int 0))))))) - -(** Printing symbol table entries *) - -type symtab_print_bundle = - (Nat_big_num.num -> string) * (Nat_big_num.num -> string) - -(** [string_of_elf32_symbol_table_entry ent] produces a string based representation - * of symbol table entry [ent]. - *) -(*val string_of_elf32_symbol_table_entry : elf32_symbol_table_entry -> string*) -let string_of_elf32_symbol_table_entry entry:string= - (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)) - ]) - -(** [string_of_elf64_symbol_table_entry ent] produces a string based representation - * of symbol table entry [ent]. - *) -(*val string_of_elf64_symbol_table_entry : elf64_symbol_table_entry -> string*) -let string_of_elf64_symbol_table_entry entry:string= - (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)) - ]) - -(** [string_of_elf32_symbol_table stbl] produces a string based representation - * of symbol table [stbl]. - *) -(*val string_of_elf32_symbol_table : elf32_symbol_table -> string*) -let string_of_elf32_symbol_table symtab:string= - (unlines (Lem_list.map string_of_elf32_symbol_table_entry symtab)) - -(** [elf64_null_symbol_table_entry] is the null symbol table entry, with all - * fields set to zero. - *) -(*val elf64_null_symbol_table_entry : elf64_symbol_table_entry*) -let elf64_null_symbol_table_entry:elf64_symbol_table_entry= - ({ elf64_st_name = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_st_info = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_st_other = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_st_shndx = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_st_value = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_st_size = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - }) - -(*val string_of_elf64_symbol_table : elf64_symbol_table -> string*) -let string_of_elf64_symbol_table symtab:string= - (unlines (Lem_list.map string_of_elf64_symbol_table_entry symtab)) - -let instance_Show_Show_Elf_symbol_table_elf32_symbol_table_entry_dict:(elf32_symbol_table_entry)show_class= ({ - - show_method = string_of_elf32_symbol_table_entry}) - -let instance_Show_Show_Elf_symbol_table_elf64_symbol_table_entry_dict:(elf64_symbol_table_entry)show_class= ({ - - show_method = string_of_elf64_symbol_table_entry}) - -(** Reading in symbol table (entries) *) - -(** [read_elf32_symbol_table_entry endian bs0] reads an ELF symbol table entry - * record from byte sequence [bs0] assuming endianness [endian], returning the - * remainder of the byte sequence. Fails if the byte sequence is not long enough. - *) -(*val read_elf32_symbol_table_entry : endianness -> byte_sequence -> - error (elf32_symbol_table_entry * byte_sequence)*) -let read_elf32_symbol_table_entry endian bs0:(elf32_symbol_table_entry*byte_sequence)error= - (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 bytes_of_elf32_symbol_table_entry : endianness -> - elf32_symbol_table_entry -> byte_sequence*) -let bytes_of_elf32_symbol_table_entry endian entry:byte_sequence= - (Byte_sequence.from_byte_lists [ - bytes_of_elf32_word endian entry.elf32_st_name - ; bytes_of_elf32_addr endian entry.elf32_st_value - ; bytes_of_elf32_word endian entry.elf32_st_size - ; bytes_of_unsigned_char entry.elf32_st_info - ; bytes_of_unsigned_char entry.elf32_st_other - ; bytes_of_elf32_half endian entry.elf32_st_shndx - ]) - -(** [read_elf64_symbol_table_entry endian bs0] reads an ELF symbol table entry - * record from byte sequence [bs0] assuming endianness [endian], returning the - * remainder of the byte sequence. Fails if the byte sequence is not long enough. - *) -(*val read_elf64_symbol_table_entry : endianness -> byte_sequence -> - error (elf64_symbol_table_entry * byte_sequence)*) -let read_elf64_symbol_table_entry endian bs0:(elf64_symbol_table_entry*byte_sequence)error= - (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 bytes_of_elf64_symbol_table_entry : endianness -> - elf64_symbol_table_entry -> byte_sequence*) -let bytes_of_elf64_symbol_table_entry endian entry:byte_sequence= - (Byte_sequence.from_byte_lists [ - bytes_of_elf64_word endian entry.elf64_st_name - ; bytes_of_unsigned_char entry.elf64_st_info - ; bytes_of_unsigned_char entry.elf64_st_other - ; bytes_of_elf64_half endian entry.elf64_st_shndx - ; bytes_of_elf64_addr endian entry.elf64_st_value - ; bytes_of_elf64_xword endian entry.elf64_st_size - ]) - -(** [read_elf32_symbol_table endian bs0] reads a symbol table from byte sequence - * [bs0] assuming endianness [endian]. Assumes [bs0]'s length modulo the size - * of a symbol table entry is 0. Fails otherwise. - *) -(*val read_elf32_symbol_table : endianness -> byte_sequence -> error elf32_symbol_table*) -let rec read_elf32_symbol_table endian bs0:((elf32_symbol_table_entry)list)error= - (if Nat_big_num.equal (Byte_sequence.length0 bs0)(Nat_big_num.of_int 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)))) - -(** [read_elf64_symbol_table endian bs0] reads a symbol table from byte sequence - * [bs0] assuming endianness [endian]. Assumes [bs0]'s length modulo the size - * of a symbol table entry is 0. Fails otherwise. - *) -(*val read_elf64_symbol_table : endianness -> byte_sequence -> error elf64_symbol_table*) -let rec read_elf64_symbol_table endian bs0:((elf64_symbol_table_entry)list)error= - (if Nat_big_num.equal (Byte_sequence.length0 bs0)(Nat_big_num.of_int 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)))) - -(** Association map of symbol name, symbol type, symbol size, symbol address - * and symbol binding. - * A PPCMemism. - *) -type symbol_address_map - = (string * (Nat_big_num.num * Nat_big_num.num * Nat_big_num.num * Nat_big_num.num)) list - -(** [get_elf32_symbol_image_address symtab stbl] extracts the symbol address map - * from the symbol table [symtab] using the string table [stbl]. - * A PPCMemism. - *) -(*val get_elf32_symbol_image_address : elf32_symbol_table -> string_table -> - error symbol_address_map*) -let get_elf32_symbol_image_address symtab strtab:((string*(Nat_big_num.num*Nat_big_num.num*Nat_big_num.num*Nat_big_num.num))list)error= - (mapM (fun entry -> - let name1 = (Nat_big_num.of_string (Uint32.to_string entry.elf32_st_name)) in - let addr = (Nat_big_num.of_string (Uint32.to_string entry.elf32_st_value)) in - let size2 = (Nat_big_num.mul (Nat_big_num.of_string (Uint32.to_string entry.elf32_st_size))(Nat_big_num.of_int 8)) in - let typ = (extract_symbol_type entry.elf32_st_info) in - let bnd = (extract_symbol_binding entry.elf32_st_info) in - String_table.get_string_at name1 strtab >>= (fun str -> - return (str, (typ, size2, addr, bnd))) - ) symtab) - -(** [get_elf64_symbol_image_address symtab stbl] extracts the symbol address map - * from the symbol table [symtab] using the string table [stbl]. - * A PPCMemism. - *) -(*val get_elf64_symbol_image_address : elf64_symbol_table -> string_table -> - error symbol_address_map*) -let get_elf64_symbol_image_address symtab strtab:((string*(Nat_big_num.num*Nat_big_num.num*Nat_big_num.num*Nat_big_num.num))list)error= - (mapM (fun entry -> - let name1 = (Nat_big_num.of_string (Uint32.to_string entry.elf64_st_name)) in - let addr = (Ml_bindings.nat_big_num_of_uint64 entry.elf64_st_value) in - let size2 = (Ml_bindings.nat_big_num_of_uint64 entry.elf64_st_size) in - let typ = (extract_symbol_type entry.elf64_st_info) in - let bnd = (extract_symbol_binding entry.elf64_st_info) in - String_table.get_string_at name1 strtab >>= (fun str -> - return (str, (typ, size2, addr, bnd))) - ) symtab) - -(** [get_el32_symbol_type ent] extracts the symbol type from symbol table entry - * [ent]. - *) -(*val get_elf32_symbol_type : elf32_symbol_table_entry -> natural*) -let get_elf32_symbol_type syment:Nat_big_num.num= (extract_symbol_type syment.elf32_st_info) - -(** [get_el64_symbol_type ent] extracts the symbol type from symbol table entry - * [ent]. - *) -(*val get_elf64_symbol_type : elf64_symbol_table_entry -> natural*) -let get_elf64_symbol_type syment:Nat_big_num.num= (extract_symbol_type syment.elf64_st_info) - -(** [get_el32_symbol_binding ent] extracts the symbol binding from symbol table entry - * [ent]. - *) -(*val get_elf32_symbol_binding : elf32_symbol_table_entry -> natural*) -let get_elf32_symbol_binding syment:Nat_big_num.num= (extract_symbol_binding syment.elf32_st_info) - -(** [get_el64_symbol_binding ent] extracts the symbol binding from symbol table entry - * [ent]. - *) -(*val get_elf64_symbol_binding : elf64_symbol_table_entry -> natural*) -let get_elf64_symbol_binding syment:Nat_big_num.num= (extract_symbol_binding syment.elf64_st_info) diff --git a/lib/ocaml_rts/linksem/elf_types_native_uint.ml b/lib/ocaml_rts/linksem/elf_types_native_uint.ml deleted file mode 100644 index d6874fd4..00000000 --- a/lib/ocaml_rts/linksem/elf_types_native_uint.ml +++ /dev/null @@ -1,706 +0,0 @@ -(*Generated by Lem from elf_types_native_uint.lem.*) -open Lem_basic_classes -open Lem_bool -open Lem_num -open Lem_string -open Lem_assert_extra - -open Endianness - -open Byte_sequence -open Error -open Missing_pervasives -open Show - -(** unsigned char type and bindings *) - -(*type unsigned_char*) - -(** [string_of_unsigned_char uc] provides a string representation of unsigned - * char [uc] (in base 10). - *) -(*val string_of_unsigned_char : unsigned_char -> string*) - -(** [natural_of_unsigned_char uc] converts an unsigned char [uc] into a natural. - *) -(*val natural_of_unsigned_char : unsigned_char -> natural*) - -(** [unsigned_char_of_natural i] converts a [natural] into an unsigned char, wrapping - * around if the size of the nat exceeds the storage capacity of an unsigned - * char. - *) -(*val unsigned_char_of_natural : natural -> unsigned_char*) - -(** [unsigned_char_land uc0 uc1] bitwise ANDs two unsigned chars, [uc0] and [uc1] - * together. - *) -(*val unsigned_char_land : unsigned_char -> unsigned_char -> unsigned_char*) - -(** [unsigned_char_lor uc0 uc1] bitwise OR two unsigned chars, [uc0] and [uc1] - * together. - *) -(*val unsigned_char_lor : unsigned_char -> unsigned_char -> unsigned_char*) - -(** [unsigned_char_lshift uc n] performs a left bitshift of [n] places on unsigned - * char [uc]. - *) -(*val unsigned_char_lshift : unsigned_char -> nat -> unsigned_char*) - -(** [unsigned_char_rshift uc n] performs a right bitshift of [n] places on unsigned - * char [uc]. - *) -(*val unsigned_char_rshift : unsigned_char -> nat -> unsigned_char*) - -(** [unsigned_char_plus uc0 uc1] adds two unsigned chars, [uc0] and [uc1]. - *) -(*val unsigned_char_plus : unsigned_char -> unsigned_char -> unsigned_char*) - -(*val unsigned_char_of_byte : byte -> unsigned_char*) - -let natural_of_byte b:Nat_big_num.num= -(Nat_big_num.of_string (Uint32.to_string (Uint32.of_int (Char.code b)))) - -(** [read_unsigned_char end bs0] reads an unsigned char from byte_sequence [bs0] - * assuming endianness [end]. Returns the unsigned char and the remainder of - * the byte_sequence. Fails if an unsigned char cannot be read from the byte_sequence, - * e.g. if [bs0] is too small. - *) -(*val read_unsigned_char : endianness -> byte_sequence -> error (unsigned_char * byte_sequence)*) -let read_unsigned_char endian bs0:(Uint32.uint32*byte_sequence)error= - (Byte_sequence.read_char bs0 >>= (fun (u1, bs1) -> - return (Uint32.of_int (Char.code u1), bs1))) - -(*val byte_of_unsigned_char : unsigned_char -> byte*) - -(*val bytes_of_unsigned_char : unsigned_char -> list byte*) -let bytes_of_unsigned_char u:(char)list= ([Char.chr (Uint32.to_int u)]) - -(*val equal_unsigned_char : unsigned_char -> unsigned_char -> bool*) - -let instance_Basic_classes_Eq_Elf_types_native_uint_unsigned_char_dict:(Uint32.uint32)eq_class= ({ - - isEqual_method = (=); - - isInequal_method = (fun l r->not (l = r))}) - -let instance_Show_Show_Elf_types_native_uint_unsigned_char_dict:(Uint32.uint32)show_class= ({ - - show_method = Uint32.to_string}) - -(** ELF address type: - * 4 byte unsigned type on 32-bit architectures. - * 8 byte unsigned type on 64-bit architectures. - *) - -(*type elf32_addr*) - -(*val string_of_elf32_addr : elf32_addr -> string*) - -(*val natural_of_elf32_addr : elf32_addr -> natural*) - -(*val elf32_addr_of_natural : natural -> elf32_addr*) - -(*val elf32_addr_of_quad : byte -> byte -> byte -> byte -> elf32_addr*) - -(*val read_elf32_addr : endianness -> byte_sequence -> error (elf32_addr * byte_sequence)*) -let read_elf32_addr endian bs0:(Uint32.uint32*byte_sequence)error= - ((match endian with - | Little -> - Byte_sequence.read_4_bytes_le bs0 >>= (fun ((b1, b2, b3, b4), bs1) -> - return (Uint32_wrapper.of_quad_native b4 b3 b2 b1, bs1)) - | Big -> - Byte_sequence.read_4_bytes_be bs0 >>= (fun ((b1, b2, b3, b4), bs1) -> - return (Uint32_wrapper.of_quad_native b4 b3 b2 b1, bs1)) - )) - -(*val equal_elf32_addr : elf32_addr -> elf32_addr -> bool*) - -(*val quad_of_elf32_addr : elf32_addr -> (byte * byte * byte * byte)*) - -(*val bytes_of_elf32_addr : endianness -> elf32_addr -> list byte*) -let bytes_of_elf32_addr endian w:(char)list= - ((match endian with - | Little -> - let (b0, b1, b2, b3) = (Uint32_wrapper.to_bytes_native w) in - [b0; b1; b2; b3] - | Big -> - let (b0, b1, b2, b3) = (Uint32_wrapper.to_bytes_native w) in - [b3; b2; b1; b0] - )) - -let instance_Basic_classes_Eq_Elf_types_native_uint_elf32_addr_dict:(Uint32.uint32)eq_class= ({ - - isEqual_method = (=); - - isInequal_method = (fun l r->not (l = r))}) - -let instance_Show_Show_Elf_types_native_uint_elf32_addr_dict:(Uint32.uint32)show_class= ({ - - show_method = Uint32.to_string}) - -(** elf64_addr type and bindings *) - -(*type elf64_addr*) - -(*val string_of_elf64_addr : elf64_addr -> string*) - -(*val natural_of_elf64_addr : elf64_addr -> natural*) - -(*val elf64_addr_of_natural : natural -> elf64_addr*) - -(*val elf64_addr_of_oct : byte -> byte -> byte -> byte -> byte -> byte -> byte -> byte -> elf64_addr*) - -(*val read_elf64_addr : endianness -> byte_sequence -> error (elf64_addr * byte_sequence)*) -let read_elf64_addr endian bs0:(Uint64.uint64*byte_sequence)error= - ((match endian with - | Little -> - Byte_sequence.read_8_bytes_le bs0 >>= (fun ((b1, b2, b3, b4, b5, b6, b7, b8), bs1) -> - return (Uint64_wrapper.of_oct_native b8 b7 b6 b5 b4 b3 b2 b1, bs1)) - | Big -> - Byte_sequence.read_8_bytes_be bs0 >>= (fun ((b1, b2, b3, b4, b5, b6, b7, b8), bs1) -> - return (Uint64_wrapper.of_oct_native b8 b7 b6 b5 b4 b3 b2 b1, bs1)) - )) - -(*val equal_elf64_addr : elf64_addr -> elf64_addr -> bool*) - -(*val oct_of_elf64_addr : elf64_addr -> (byte * byte * byte * byte * byte * byte * byte * byte)*) - -(*val bytes_of_elf64_addr : endianness -> elf64_addr -> list byte*) -let bytes_of_elf64_addr endian w:(char)list= - ((match endian with - | Little -> - let (b0, b1, b2, b3, b4, b5, b6, b7) = (Uint64_wrapper.to_bytes_native w) in - [b0; b1; b2; b3; b4; b5; b6; b7] - | Big -> - let (b0, b1, b2, b3, b4, b5, b6, b7) = (Uint64_wrapper.to_bytes_native w) in - [b7; b6; b5; b4; b3; b2; b1; b0] - )) - -(*val elf64_addr_minus : elf64_addr -> elf64_addr -> elf64_addr*) - -(*val elf64_addr_rshift : elf64_addr -> nat -> elf64_addr*) - -(*val elf64_addr_lshift : elf64_addr -> nat -> elf64_addr*) - -(*val elf64_addr_land : elf64_addr -> elf64_addr -> elf64_addr*) - -(*val elf64_addr_lor : elf64_addr -> elf64_addr -> elf64_addr*) - -let instance_Basic_classes_Eq_Elf_types_native_uint_elf64_addr_dict:(Uint64.uint64)eq_class= ({ - - isEqual_method = (=); - - isInequal_method = (fun l r->not (l = r))}) - -let instance_Show_Show_Elf_types_native_uint_elf64_addr_dict:(Uint64.uint64)show_class= ({ - - show_method = Uint64.to_string}) - -(** ELF half word type: - * 2 byte unsigned type on 32-bit architectures. - * 2 byte unsigned type on 64-bit architectures. - *) - -(*type elf32_half*) - -(*val string_of_elf32_half : elf32_half -> string*) - -(*val elf32_half_of_dual : byte -> byte -> elf32_half*) - -(*val read_elf32_half : endianness -> byte_sequence -> error (elf32_half * byte_sequence)*) -let read_elf32_half endian bs0:(Uint32.uint32*byte_sequence)error= - ((match endian with - | Little -> - Byte_sequence.read_2_bytes_le bs0 >>= (fun ((b1, b2), bs1) -> - return (Uint32_wrapper.of_dual_native b2 b1, bs1)) - | Big -> - Byte_sequence.read_2_bytes_be bs0 >>= (fun ((b1, b2), bs1) -> - return (Uint32_wrapper.of_dual_native b2 b1, bs1)) - )) - -(*val natural_of_elf32_half : elf32_half -> natural*) - -(*val equal_elf32_half : elf32_half -> elf32_half -> bool*) - -(*val dual_of_elf32_half : elf32_half -> (byte * byte)*) - -(*val bytes_of_elf32_half : endianness -> elf32_half -> list byte*) -let bytes_of_elf32_half endian h:(char)list= - ((match endian with - | Little -> - let (b0, b1) = (Uint32_wrapper.to_dual_bytes_native h) in - [b0; b1] - | Big -> - let (b0, b1) = (Uint32_wrapper.to_dual_bytes_native h) in - [b1; b0] - )) - -let instance_Basic_classes_Eq_Elf_types_native_uint_elf32_half_dict:(Uint32.uint32)eq_class= ({ - - isEqual_method = (=); - - isInequal_method = (fun l r->not (l = r))}) - -let instance_Show_Show_Elf_types_native_uint_elf32_half_dict:(Uint32.uint32)show_class= ({ - - show_method = Uint32.to_string}) - -(** elf64_half type and bindings *) - -(*type elf64_half*) - -(*val string_of_elf64_half : elf64_half -> string*) - -(*val elf64_half_of_dual : byte -> byte -> elf64_half*) - -(*val read_elf64_half : endianness -> byte_sequence -> error (elf64_half * byte_sequence)*) -let read_elf64_half endian bs0:(Uint32.uint32*byte_sequence)error= - ((match endian with - | Big -> - Byte_sequence.read_2_bytes_be bs0 >>= (fun ((b1, b2), bs1) -> - return (Uint32_wrapper.of_dual_native b2 b1, bs1)) - | Little -> - Byte_sequence.read_2_bytes_le bs0 >>= (fun ((b1, b2), bs1) -> - return (Uint32_wrapper.of_dual_native b2 b1, bs1)) - )) - -(*val natural_of_elf64_half : elf64_half -> natural*) - -(*val elf64_half_of_natural : natural -> elf64_half*) - -(*val equal_elf64_half : elf64_half -> elf64_half -> bool*) - -(*val dual_of_elf64_half : elf64_half -> (byte * byte)*) - -(*val bytes_of_elf64_half : endianness -> elf64_half -> list byte*) -let bytes_of_elf64_half endian w:(char)list= - ((match endian with - | Big -> - let (b0, b1) = (Uint32_wrapper.to_dual_bytes_native w) in - [b1; b0] - | Little -> - let (b0, b1) = (Uint32_wrapper.to_dual_bytes_native w) in - [b0; b1] - )) - -let instance_Basic_classes_Eq_Elf_types_native_uint_elf64_half_dict:(Uint32.uint32)eq_class= ({ - - isEqual_method = (=); - - isInequal_method = (fun l r->not (l = r))}) - -let instance_Show_Show_Elf_types_native_uint_elf64_half_dict:(Uint32.uint32)show_class= ({ - - show_method = Uint32.to_string}) - -(* -instance (Ord elf64_half) - let compare = - let (<) = - let (<=) = - let (>) = - let (>=) = -end -*) - -(** ELF offset type: - * 4 byte unsigned type on 32-bit architectures. - * 8 byte unsigned type on 64-bit architectures. - *) - -(*type elf32_off*) - -(*val string_of_elf32_off : elf32_off -> string*) - -(*val natural_of_elf32_off : elf32_off -> natural*) - -(*val elf32_off_of_natural : natural -> elf32_off*) - -(*val elf32_off_of_quad : byte -> byte -> byte -> byte -> elf32_off*) - -(*val read_elf32_off : endianness -> byte_sequence -> error (elf32_off * byte_sequence)*) -let read_elf32_off endian bs0:(Uint32.uint32*byte_sequence)error= - ((match endian with - | Little -> - Byte_sequence.read_4_bytes_le bs0 >>= (fun ((b1, b2, b3, b4), bs1) -> - return (Uint32_wrapper.of_quad_native b4 b3 b2 b1, bs1)) - | Big -> - Byte_sequence.read_4_bytes_be bs0 >>= (fun ((b1, b2, b3, b4), bs1) -> - return (Uint32_wrapper.of_quad_native b4 b3 b2 b1, bs1)) - )) - -(*val equal_elf32_off : elf32_off -> elf32_off -> bool*) - -(*val quad_of_elf32_off : elf32_off -> (byte * byte * byte * byte)*) - -(*val bytes_of_elf32_off : endianness -> elf32_off -> list byte*) -let bytes_of_elf32_off endian w:(char)list= - ((match endian with - | Little -> - let (b0, b1, b2, b3) = (Uint32_wrapper.to_bytes_native w) in - [b0; b1; b2; b3] - | Big -> - let (b0, b1, b2, b3) = (Uint32_wrapper.to_bytes_native w) in - [b3; b2; b1; b0] - )) - -let instance_Basic_classes_Eq_Elf_types_native_uint_elf32_off_dict:(Uint32.uint32)eq_class= ({ - - isEqual_method = (=); - - isInequal_method = (fun l r->not (l = r))}) - -let instance_Show_Show_Elf_types_native_uint_elf32_off_dict:(Uint32.uint32)show_class= ({ - - show_method = Uint32.to_string}) - -(** elf64_off type and bindings *) - -(*type elf64_off*) - -(*val string_of_elf64_off : elf64_off -> string*) - -(*val natural_of_elf64_off : elf64_off -> natural*) - -(*val elf64_off_of_natural : natural -> elf64_off*) - -(*val elf64_off_of_oct : byte -> byte -> byte -> byte -> byte -> byte -> byte -> byte -> elf64_off*) - -(*val read_elf64_off : endianness -> byte_sequence -> error (elf64_off * byte_sequence)*) -let read_elf64_off endian bs0:(Uint64.uint64*byte_sequence)error= - ((match endian with - | Little -> - Byte_sequence.read_8_bytes_le bs0 >>= (fun ((b1, b2, b3, b4, b5, b6, b7, b8), bs1) -> - return (Uint64_wrapper.of_oct_native b8 b7 b6 b5 b4 b3 b2 b1, bs1)) - | Big -> - Byte_sequence.read_8_bytes_be bs0 >>= (fun ((b1, b2, b3, b4, b5, b6, b7, b8), bs1) -> - return (Uint64_wrapper.of_oct_native b8 b7 b6 b5 b4 b3 b2 b1, bs1)) - )) - -(*val equal_elf64_off : elf64_off -> elf64_off -> bool*) - -(*val oct_of_elf64_off : elf64_off -> (byte * byte * byte * byte * byte * byte * byte * byte)*) - -(*val bytes_of_elf64_off : endianness -> elf64_off -> list byte*) -let bytes_of_elf64_off endian w:(char)list= - ((match endian with - | Little -> - let (b0, b1, b2, b3, b4, b5, b6, b7) = (Uint64_wrapper.to_bytes_native w) in - [b0; b1; b2; b3; b4; b5; b6; b7] - | Big -> - let (b0, b1, b2, b3, b4, b5, b6, b7) = (Uint64_wrapper.to_bytes_native w) in - [b7; b6; b5; b4; b3; b2; b1; b0] - )) - -let instance_Basic_classes_Eq_Elf_types_native_uint_elf64_off_dict:(Uint64.uint64)eq_class= ({ - - isEqual_method = (=); - - isInequal_method = (fun l r->not (l = r))}) - -let instance_Show_Show_Elf_types_native_uint_elf64_off_dict:(Uint64.uint64)show_class= ({ - - show_method = Uint64.to_string}) - -(** ELF word type: - * 4 byte unsigned type on 32-bit architectures. - * 4 byte unsigned type on 64-bit architectures. - *) - -(*type elf32_word*) - -(*val string_of_elf32_word : elf32_word -> string*) - -(*val natural_of_elf32_word : elf32_word -> natural*) - -(*val elf32_word_of_natural : natural -> elf32_word*) - -(*val elf32_word_land : elf32_word -> elf32_word -> elf32_word*) - -(*val elf32_word_rshift : elf32_word -> nat -> elf32_word*) - -(*val elf32_word_of_quad : byte -> byte -> byte -> byte -> elf32_word*) - -(*val read_elf32_word : endianness -> byte_sequence -> error (elf32_word * byte_sequence)*) -let read_elf32_word endian bs0:(Uint32.uint32*byte_sequence)error= - ((match endian with - | Little -> - Byte_sequence.read_4_bytes_le bs0 >>= (fun ((b1, b2, b3, b4), bs1) -> - return (Uint32_wrapper.of_quad_native b4 b3 b2 b1, bs1)) - | Big -> - Byte_sequence.read_4_bytes_be bs0 >>= (fun ((b1, b2, b3, b4), bs1) -> - return (Uint32_wrapper.of_quad_native b4 b3 b2 b1, bs1)) - )) - -(*val unsigned_char_of_elf32_word : elf32_word -> unsigned_char*) - -(*val equal_elf32_word : elf32_word -> elf32_word -> bool*) - -(*val quad_of_elf32_word : elf32_word -> (byte * byte * byte * byte)*) - -(*val bytes_of_elf32_word : endianness -> elf32_word -> list byte*) -let bytes_of_elf32_word endian w:(char)list= - ((match endian with - | Little -> - let (b0, b1, b2, b3) = (Uint32_wrapper.to_bytes_native w) in - [b0; b1; b2; b3] - | Big -> - let (b0, b1, b2, b3) = (Uint32_wrapper.to_bytes_native w) in - [b3; b2; b1; b0] - )) - -let instance_Basic_classes_Eq_Elf_types_native_uint_elf32_word_dict:(Uint32.uint32)eq_class= ({ - - isEqual_method = (=); - - isInequal_method = (fun l r->not (l = r))}) - -let instance_Show_Show_Elf_types_native_uint_elf32_word_dict:(Uint32.uint32)show_class= ({ - - show_method = Uint32.to_string}) - -(** elf64_word type and bindings *) - -(*type elf64_word*) - -(*val string_of_elf64_word : elf64_word -> string*) - -(*val natural_of_elf64_word : elf64_word -> natural*) - -(*val elf64_word_of_natural : natural -> elf64_word*) - -(*val elf64_word_land : elf64_word -> elf64_word -> elf64_word*) - -(*val elf64_word_of_quad : byte -> byte -> byte -> byte -> elf64_word*) - -(*val read_elf64_word : endianness -> byte_sequence -> error (elf64_word * byte_sequence)*) -let read_elf64_word endian bs0:(Uint32.uint32*byte_sequence)error= - ((match endian with - | Little -> - Byte_sequence.read_4_bytes_le bs0 >>= (fun ((b1, b2, b3, b4), bs1) -> - return (Uint32_wrapper.of_quad_native b4 b3 b2 b1, bs1)) - | Big -> - Byte_sequence.read_4_bytes_be bs0 >>= (fun ((b1, b2, b3, b4), bs1) -> - return (Uint32_wrapper.of_quad_native b4 b3 b2 b1, bs1)) - )) - -(*val equal_elf64_word : elf64_word -> elf64_word -> bool*) - -(*val quad_of_elf64_word : elf64_word -> (byte * byte * byte * byte)*) - -(*val bytes_of_elf64_word : endianness -> elf64_word -> list byte*) -let bytes_of_elf64_word endian w:(char)list= - ((match endian with - | Little -> - let (b0, b1, b2, b3) = (Uint32_wrapper.to_bytes_native w) in - [b0; b1; b2; b3] - | Big -> - let (b0, b1, b2, b3) = (Uint32_wrapper.to_bytes_native w) in - [b3; b2; b1; b0] - )) - -let instance_Basic_classes_Eq_Elf_types_native_uint_elf64_word_dict:(Uint32.uint32)eq_class= ({ - - isEqual_method = (=); - - isInequal_method = (fun l r->not (l = r))}) - -let instance_Show_Show_Elf_types_native_uint_elf64_word_dict:(Uint32.uint32)show_class= ({ - - show_method = Uint32.to_string}) - -(** ELF signed word type: - * 4 byte signed type on 32-bit architectures. - * 4 byte signed type on 64-bit architectures. - *) - -(*type elf32_sword*) - -(*val string_of_elf32_sword : elf32_sword -> string*) - -(*val integer_of_elf32_sword : elf32_sword -> integer*) - -(*val elf32_sword_of_quad : byte -> byte -> byte -> byte -> elf32_sword*) - -(*val read_elf32_sword : endianness -> byte_sequence -> error (elf32_sword * byte_sequence)*) -let read_elf32_sword endian bs0:(Int32.t*byte_sequence)error= - ((match endian with - | Little -> - Byte_sequence.read_4_bytes_le bs0 >>= (fun ((b1, b2, b3, b4), bs1) -> - return (Ml_bindings.int32_of_quad b4 b3 b2 b1, bs1)) - | Big -> - Byte_sequence.read_4_bytes_be bs0 >>= (fun ((b1, b2, b3, b4), bs1) -> - return (Ml_bindings.int32_of_quad b4 b3 b2 b1, bs1)) - )) - -(*val quad_of_elf32_sword : elf32_sword -> (byte * byte * byte * byte)*) - -(*val bytes_of_elf32_sword : endianness -> elf32_sword -> list byte*) -let bytes_of_elf32_sword endian w:(char)list= - ((match endian with - | Little -> - let (b0, b1, b2, b3) = (Ml_bindings.bytes_of_int32 w) in - [b0; b1; b2; b3] - | Big -> - let (b0, b1, b2, b3) = (Ml_bindings.bytes_of_int32 w) in - [b3; b2; b1; b0] - )) - -let instance_Show_Show_Elf_types_native_uint_elf32_sword_dict:(Int32.t)show_class= ({ - - show_method = Int32.to_string}) - -(** elf64_sword type and bindings *) - -(*type elf64_sword*) - -(*val string_of_elf64_sword : elf64_sword -> string*) - -(*val integer_of_elf64_sword : elf64_sword -> integer*) - -(*val elf64_sword_of_quad : byte -> byte -> byte -> byte -> elf64_sword*) - -(*val read_elf64_sword : endianness -> byte_sequence -> error (elf64_sword * byte_sequence)*) -let read_elf64_sword endian bs0:(Int32.t*byte_sequence)error= - ((match endian with - | Little -> - Byte_sequence.read_4_bytes_le bs0 >>= (fun ((b1, b2, b3, b4), bs1) -> - return (Ml_bindings.int32_of_quad b4 b3 b2 b1, bs1)) - | Big -> - Byte_sequence.read_4_bytes_be bs0 >>= (fun ((b1, b2, b3, b4), bs1) -> - return (Ml_bindings.int32_of_quad b4 b3 b2 b1, bs1)) - )) - -(*val quad_of_elf64_sword : elf64_sword -> (byte * byte * byte * byte)*) - -(*val bytes_of_elf64_sword : endianness -> elf64_sword -> list byte*) -let bytes_of_elf64_sword endian w:(char)list= - ((match endian with - | Little -> - let (b0, b1, b2, b3) = (Ml_bindings.bytes_of_int32 w) in - [b0; b1; b2; b3] - | Big -> - let (b0, b1, b2, b3) = (Ml_bindings.bytes_of_int32 w) in - [b3; b2; b1; b0] - )) - -let instance_Show_Show_Elf_types_native_uint_elf64_sword_dict:(Int32.t)show_class= ({ - - show_method = Int32.to_string}) - -(** ELF extra wide word type: - * 8 byte unsigned type on 64-bit architectures. - *) - -(*type elf64_xword*) - -(*val string_of_elf64_xword : elf64_xword -> string*) - -(*val natural_of_elf64_xword : elf64_xword -> natural*) - -(*val elf64_xword_of_oct : byte -> byte -> byte -> byte -> byte -> byte -> byte -> byte -> elf64_xword*) - -(*val read_elf64_xword : endianness -> byte_sequence -> error (elf64_xword * byte_sequence)*) -let read_elf64_xword endian bs0:(Uint64.uint64*byte_sequence)error= - ((match endian with - | Little -> - Byte_sequence.read_8_bytes_le bs0 >>= (fun ((b1, b2, b3, b4, b5, b6, b7, b8), bs1) -> - return (Uint64_wrapper.of_oct_native b8 b7 b6 b5 b4 b3 b2 b1, bs1)) - | Big -> - Byte_sequence.read_8_bytes_be bs0 >>= (fun ((b1, b2, b3, b4, b5, b6, b7, b8), bs1) -> - return (Uint64_wrapper.of_oct_native b8 b7 b6 b5 b4 b3 b2 b1, bs1)) - )) - -(*val elf64_xword_rshift : elf64_xword -> nat -> elf64_xword*) - -(*val elf64_xword_lshift : elf64_xword -> nat -> elf64_xword*) - -(*val elf64_xword_land : elf64_xword -> elf64_xword -> elf64_xword*) - -(*val elf64_xword_lor : elf64_xword -> elf64_xword -> elf64_xword*) - -(*val elf64_xword_lxor : elf64_xword -> elf64_xword -> elf64_xword*) - -(*val elf64_xword_of_natural : natural -> elf64_xword*) - -(*val equal_elf64_xword : elf64_xword -> elf64_xword -> bool*) - -(*val oct_of_elf64_xword : elf64_xword -> (byte * byte * byte * byte * byte * byte * byte * byte)*) - -(*val bytes_of_elf64_xword : endianness -> elf64_xword -> list byte*) -let bytes_of_elf64_xword endian x:(char)list= - ((match endian with - | Little -> - let (b0, b1, b2, b3, b4, b5, b6, b7) = (Uint64_wrapper.to_bytes_native x) in - [b0; b1; b2; b3; b4; b5; b6; b7] - | Big -> - let (b0, b1, b2, b3, b4, b5, b6, b7) = (Uint64_wrapper.to_bytes_native x) in - [b7; b6; b5; b4; b3; b2; b1; b0] - )) - -let instance_Basic_classes_Eq_Elf_types_native_uint_elf64_xword_dict:(Uint64.uint64)eq_class= ({ - - isEqual_method = (=); - - isInequal_method = (fun l r->not (l = r))}) - -let instance_Show_Show_Elf_types_native_uint_elf64_xword_dict:(Uint64.uint64)show_class= ({ - - show_method = Uint64.to_string}) - -(** ELF signed extra wide word type: - * 8 byte signed type on 64-bit architectures. - *) - -(*type elf64_sxword*) - -(*val string_of_elf64_sxword : elf64_sxword -> string*) - -(*val integer_of_elf64_sxword : elf64_sxword -> integer*) - -(*val elf64_sxword_of_integer : integer -> elf64_sxword*) - -(*val elf64_sxword_of_oct : byte -> byte -> byte -> byte -> byte -> byte -> byte -> byte -> elf64_sxword*) - -(*val read_elf64_sxword : endianness -> byte_sequence -> error (elf64_sxword * byte_sequence)*) -let read_elf64_sxword endian bs0:(Int64.t*byte_sequence)error= - ((match endian with - | Little -> - Byte_sequence.read_8_bytes_le bs0 >>= (fun ((b1, b2, b3, b4, b5, b6, b7, b8), bs1) -> - return (Ml_bindings.int64_of_oct b8 b7 b6 b5 b4 b3 b2 b1, bs1)) - | Big -> - Byte_sequence.read_8_bytes_be bs0 >>= (fun ((b1, b2, b3, b4, b5, b6, b7, b8), bs1) -> - return (Ml_bindings.int64_of_oct b8 b7 b6 b5 b4 b3 b2 b1, bs1)) - )) - -(*val oct_of_elf64_sxword : elf64_sxword -> (byte * byte * byte * byte * byte * byte * byte * byte)*) - -(*val bytes_of_elf64_sxword : endianness -> elf64_sxword -> list byte*) -let bytes_of_elf64_sxword endian w:(char)list= - ((match endian with - | Little -> - let (b0, b1, b2, b3, b4, b5, b6, b7) = (Ml_bindings.bytes_of_int64 w) in - [b0; b1; b2; b3; b4; b5; b6; b7] - | Big -> - let (b0, b1, b2, b3, b4, b5, b6, b7) = (Ml_bindings.bytes_of_int64 w) in - [b7; b6; b5; b4; b3; b2; b1; b0] - )) - -let instance_Show_Show_Elf_types_native_uint_elf64_sxword_dict:(Int64.t)show_class= ({ - - show_method = Int64.to_string}) - -(*val natural_land : natural -> natural -> natural*) -(*let natural_land m n:natural= - (* For Isabelle backend...*) - natural_of_elf64_xword (elf64_xword_land (elf64_xword_of_natural m) (elf64_xword_of_natural n))*) - -(*val natural_lor : natural -> natural -> natural*) -(*let natural_lor m n:natural= - (* For Isabelle backend...*) - natural_of_elf64_xword (elf64_xword_lor (elf64_xword_of_natural m) (elf64_xword_of_natural n))*) - -(*val natural_lxor : natural -> natural -> natural*) -(*let natural_lxor m n:natural= - (* For Isabelle backend...*) - natural_of_elf64_xword (elf64_xword_lxor (elf64_xword_of_natural m) (elf64_xword_of_natural n))*) diff --git a/lib/ocaml_rts/linksem/endianness.ml b/lib/ocaml_rts/linksem/endianness.ml deleted file mode 100644 index 2821fc6a..00000000 --- a/lib/ocaml_rts/linksem/endianness.ml +++ /dev/null @@ -1,35 +0,0 @@ -(*Generated by Lem from endianness.lem.*) -(** [endian.lem] defines a type for describing the endianness of an ELF file, - * and functions and other operations over that type. - *) - -open Lem_string -open Show - -(** Type [endianness] describes the endianness of an ELF file. This is deduced from - * the first few bytes (magic number, etc.) of the ELF header. - *) -type endianness - = Big (* Big endian *) - | Little (* Little endian *) - -(** [default_endianness] is a default endianness to use when reading in the ELF header - * before we have deduced from its entries what the rest of the file is encoded - * with. - *) -(*val default_endianness : endianness*) -let default_endianness:endianness= Little - -(** [string_of_endianness e] produces a string representation of the [endianness] value - * [e]. - *) -(*val string_of_endianness : endianness -> string*) -let string_of_endianness e:string= - ((match e with - | Big -> "Big" - | Little -> "Little" - )) - -let instance_Show_Show_Endianness_endianness_dict:(endianness)show_class= ({ - - show_method = string_of_endianness}) diff --git a/lib/ocaml_rts/linksem/error.ml b/lib/ocaml_rts/linksem/error.ml deleted file mode 100644 index 45f8a80b..00000000 --- a/lib/ocaml_rts/linksem/error.ml +++ /dev/null @@ -1,112 +0,0 @@ -(*Generated by Lem from error.lem.*) -open Lem_basic_classes -open Lem_list -open Lem_maybe -open Lem_num -open Lem_string -open Show - -(** [error] is a type used to represent potentially failing computations. [Success] - * marks a successful completion of a computation, whilst [Fail err] marks a failure, - * with [err] as the reason. - *) -type 'a error - = Success of 'a - | Fail of string - -(** [return] is the monadic lifting function for [error], representing a successful - * computation. - *) -(*val return : forall 'a. 'a -> error 'a*) -let return r = (Success r) - -(*val with_success : forall 'a 'b. error 'a -> 'b -> ('a -> 'b) -> 'b*) -let with_success err fl suc = -((match err with - | Success s -> suc s - | Fail err -> fl - )) - -(** [fail err] represents a failing computation, with error message [err]. - *) -(*val fail : forall 'a. string -> error 'a*) -let fail err = (Fail err) - -(** [(>>=)] is the monadic binding function for [error]. - *) -(*val >>= : forall 'a 'b. error 'a -> ('a -> error 'b) -> error 'b*) -let (>>=) x f = -((match x with - | Success s -> f s - | Fail err -> Fail err - )) - -(** [as_maybe e] drops an [error] value into a [maybe] value, throwing away - * error information. - *) - -(*val as_maybe : forall 'a. error 'a -> maybe 'a*) -let as_maybe e = -((match e with - | Fail err -> None - | Success s -> Some s - )) - -(** [repeatM count action] fails if [action] is a failing computation, or - * successfully produces a list [count] elements long, where each element is - * the value successfully returned by [action]. - *) -(*val repeatM : forall 'a. natural -> error 'a -> error (list 'a)*) -let rec repeatM count action = -(if Nat_big_num.equal count(Nat_big_num.of_int 0) then - return [] - else - action >>= (fun head -> - repeatM ( Nat_big_num.sub_nat count(Nat_big_num.of_int 1)) action >>= (fun tail -> - return (head::tail)))) - -(** [repeatM' count seed action] is a variant of [repeatM] that acts like [repeatM] - * apart from any successful result returns a tuple whose second component is [seed] - * and whose first component is the same as would be returned by [repeatM]. - *) -(*val repeatM' : forall 'a 'b. natural -> 'b -> ('b -> error ('a * 'b)) -> error ((list 'a) * 'b)*) -let rec repeatM' count seed action = -(if Nat_big_num.equal count(Nat_big_num.of_int 0) then - return ([], seed) - else - action seed >>= (fun (head, seed) -> - repeatM' ( Nat_big_num.sub_nat count(Nat_big_num.of_int 1)) seed action >>= (fun (tail, seed) -> - return ((head::tail), seed)))) - -(** [mapM f xs] maps [f] across [xs], failing if [f] fails on any element of [xs]. - *) -(*val mapM : forall 'a 'b. ('a -> error 'b) -> list 'a -> error (list 'b)*) -let rec mapM f xs = -((match xs with - | [] -> return [] - | x::xs -> - f x >>= (fun hd -> - mapM f xs >>= (fun tl -> - return (hd::tl))) - )) - -(*val foldM : forall 'a 'b. ('a -> 'b -> error 'a) -> 'a -> list 'b -> error 'a*) -let rec foldM f e xs = -((match xs with - | [] -> return e - | x::xs -> f e x >>= (fun res -> foldM f res xs) - )) - -(** [string_of_error err] produces a string representation of [err]. - *) -(*val string_of_error : forall 'a. Show 'a => error 'a -> string*) -let string_of_error dict_Show_Show_a e = -((match e with - | Fail err -> "Fail: " ^ err - | Success s -> dict_Show_Show_a.show_method s - )) - -let instance_Show_Show_Error_error_dict dict_Show_Show_a =({ - - show_method = - (string_of_error dict_Show_Show_a)}) diff --git a/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_abi.ml b/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_abi.ml deleted file mode 100644 index 7371547f..00000000 --- a/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_abi.ml +++ /dev/null @@ -1,131 +0,0 @@ -(*Generated by Lem from gnu_extensions/gnu_ext_abi.lem.*) -open Lem_basic_classes -open Lem_function -open Lem_string -open Lem_tuple -open Lem_bool -open Lem_list -open Lem_sorting -open Lem_num -open Lem_maybe -open Lem_assert_extra -open Show -open Missing_pervasives - -open Byte_sequence - -(* open import Abis *) - -open Elf_file -open Elf_header -open Elf_interpreted_segment -open Elf_interpreted_section -open Elf_program_header_table -open Elf_section_header_table -open Elf_symbol_table -open Elf_types_native_uint -open Elf_relocation -open Elf_types_native_uint -open Memory_image - -(** Optional, like [stt_func] but always points to a function or piece of - * executable code that takes no arguments and returns a function pointer. - *) -let stt_gnu_ifunc : Nat_big_num.num= (Nat_big_num.of_int 10) - -(*val gnu_extend: forall 'abifeature. abi 'abifeature -> abi 'abifeature*) -let gnu_extend a:'abifeature abi= - ({ is_valid_elf_header = (a.is_valid_elf_header) - ; make_elf_header = -( (* t -> entry -> shoff -> phoff -> phnum -> shnum -> shstrndx -> hdr *)fun t -> fun entry -> fun shoff -> fun phoff -> fun phnum -> fun shnum -> fun shstrndx -> - let unmod = (a.make_elf_header t entry shoff phoff phnum shnum shstrndx) - in - { elf64_ident = ((match unmod.elf64_ident with - i0 :: i1 :: i2 :: i3 :: i4 :: i5 :: i6 :: - _ :: _ :: i9 :: i10 :: i11 :: i12 :: i13 :: i14 :: i15 :: [] - -> [i0; i1; i2; i3; i4; i5; i6; - Uint32.of_string (Nat_big_num.to_string elf_osabi_gnu); - Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 1)); - i9; i10; i11; i12; i13; i14; i15] - )) - ; elf64_type = (Uint32.of_string (Nat_big_num.to_string t)) - ; elf64_machine = (unmod.elf64_machine) - ; elf64_version = (unmod.elf64_version) - ; elf64_entry = (unmod.elf64_entry) - ; elf64_phoff = (Uint64.of_string (Nat_big_num.to_string phoff)) - ; elf64_shoff = (Uint64.of_string (Nat_big_num.to_string shoff)) - ; elf64_flags = (unmod.elf64_flags) - ; elf64_ehsize = (unmod.elf64_ehsize) - ; elf64_phentsize= (unmod.elf64_phentsize) - ; elf64_phnum = (Uint32.of_string (Nat_big_num.to_string phnum)) - ; elf64_shentsize= (unmod.elf64_shentsize) - ; elf64_shnum = (Uint32.of_string (Nat_big_num.to_string shnum)) - ; elf64_shstrndx = (Uint32.of_string (Nat_big_num.to_string shstrndx)) - }) - ; reloc = (a.reloc) - ; section_is_special = (fun isec1 -> (fun img2 -> ( - a.section_is_special isec1 img2 - || ( -(Lem.option_equal (=)(Ml_bindings.string_prefix (Nat_big_num.of_int (String.length ".gnu.warning")) isec1.elf64_section_name_as_string) (Some(".gnu.warning")))) - (* FIXME: This is a slight abuse. The GNU linker's treatment of - * ".gnu.warning.*" section is not really a function of the output - * ABI -- it's a function of the input ABI, or arguably perhaps just - * of the linker itself. We have to do something to make sure these - * sections get silently processed separately from the usual linker - * control script, because otherwise our link map output doesn't match - * the GNU linker's. By declaring these sections "special" we achieve - * this by saying they don't participate in linking proper, just like - * ".symtab" and similar sections don't. HMM. I suppose this is - * okay, in that although a non-GNU linker might happily link these - * sections, arguably that is a failure to understand the input files. - * But the issue about it being a per-input-file property remains. - * Q. What does the GNU linker do if a reloc input file whose OSABI - * is *not* GNU contains a .gnu.warning.* section? That would be a fair - * test about whether looking at the input ABI is worth doing. *) - ))) - ; section_is_large = (a.section_is_large) - ; maxpagesize = (a.maxpagesize) - ; minpagesize = (a.minpagesize) - ; commonpagesize = (a.commonpagesize) - ; symbol_is_generated_by_linker = (a.symbol_is_generated_by_linker) - ; make_phdrs = (a.make_phdrs) (* FIXME: also make the GNU phdrs! *) - ; max_phnum = (Nat_big_num.add(Nat_big_num.of_int 1) a.max_phnum) (* FIXME: GNU_RELRO, GNU_STACK; what else? *) - ; guess_entry_point = (a.guess_entry_point) - ; pad_data = (a.pad_data) - ; pad_code = (a.pad_code) - ; generate_support = (fun input_fnames_and_imgs -> - let vanilla_support_img = (a.generate_support input_fnames_and_imgs) in - (* also generate .note.gnu.build-id *) - let new_by_range = (Pset.add (Some(".note.gnu.build-id", (Nat_big_num.of_int 0,Nat_big_num.of_int 24)), FileFeature(ElfSection(Nat_big_num.of_int 4 (* HACK: calculate this *), - { elf64_section_name =(Nat_big_num.of_int 0) (* ignored *) - ; elf64_section_type = sht_note - ; elf64_section_flags = shf_alloc - ; elf64_section_addr =(Nat_big_num.of_int 0) (* ignored -- covered by element *) - ; elf64_section_offset =(Nat_big_num.of_int 0) (* ignored -- will be replaced when file offsets are assigned *) - ; elf64_section_size =(Nat_big_num.of_int 24) (* ignored? NO, we use it in linker_script to avoid plumbing through the element record *) - ; elf64_section_link =(Nat_big_num.of_int 0) - ; elf64_section_info =(Nat_big_num.of_int 0) - ; elf64_section_align =(Nat_big_num.of_int 4) - ; elf64_section_entsize =(Nat_big_num.of_int 0) - ; elf64_section_body = Byte_sequence.empty (* ignored *) - ; elf64_section_name_as_string = ".note.gnu.build-id" - } - ))) vanilla_support_img.by_range) - in - { elements = (Pmap.add ".note.gnu.build-id" { - startpos = None - ; length1 = (Some(Nat_big_num.of_int 24)) - ; contents = ([]) - } (vanilla_support_img.elements)) - ; by_tag = (by_tag_from_by_range - (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) instance_Basic_classes_SetType_var_dict new_by_range) - ; by_range = new_by_range - }) - ; concretise_support = (a.concretise_support) - ; get_reloc_symaddr = (a.get_reloc_symaddr) - }) diff --git a/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_dynamic.ml b/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_dynamic.ml deleted file mode 100644 index e2957380..00000000 --- a/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_dynamic.ml +++ /dev/null @@ -1,531 +0,0 @@ -(*Generated by Lem from gnu_extensions/gnu_ext_dynamic.lem.*) -(** [gnu_ext_dynamic] contains GNU extension specific definitions related to the - * .dynamic section of an ELF file. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_num -open Lem_string - -open Error -open Show -open String_table - -open Elf_dynamic -open Elf_types_native_uint - -(** Additional dynamic entries, see LSB section 11.3.2.2. - * All values taken from elf.c from binutils and GLIBC as the LSB does not - * specify them. - * - * 98 #define OLD_DT_LOOS 0x60000000 - * 99 #define DT_LOOS 0x6000000d - * 100 #define DT_HIOS 0x6ffff000 - * 101 #define DT_VALRNGLO 0x6ffffd00 - * 102 #define DT_VALRNGHI 0x6ffffdff - * 103 #define DT_ADDRRNGLO 0x6ffffe00 - * 104 #define DT_ADDRRNGHI 0x6ffffeff - * 105 #define DT_VERSYM 0x6ffffff0 - * 106 #define DT_RELACOUNT 0x6ffffff9 - * 107 #define DT_RELCOUNT 0x6ffffffa - * 108 #define DT_FLAGS_1 0x6ffffffb - * 109 #define DT_VERDEF 0x6ffffffc - * 110 #define DT_VERDEFNUM 0x6ffffffd - * 111 #define DT_VERNEED 0x6ffffffe - * 112 #define DT_VERNEEDNUM 0x6fffffff - * 113 #define OLD_DT_HIOS 0x6fffffff - * 114 #define DT_LOPROC 0x70000000 - * 115 #define DT_HIPROC 0x7fffffff - *) - -let elf_dt_gnu_addrrnghi : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 939523967)(Nat_big_num.of_int 2))(Nat_big_num.of_int 1)) (*0x6ffffeff*) -let elf_dt_gnu_addrrnglo : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 939523840)(Nat_big_num.of_int 2)) (*0x6ffffe00*) -let elf_dt_gnu_auxiliary : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 1073741822)(Nat_big_num.of_int 2))(Nat_big_num.of_int 1)) (*0x7ffffffd*) -let elf_dt_gnu_filter : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 1073741823)(Nat_big_num.of_int 2))(Nat_big_num.of_int 1)) (*0x7fffffff*) -(** The following is "specified" in the LSB document but is not present in the - * elf.c file so taken from elf.h from GLIBC: - *) -let elf_dt_gnu_num : Nat_big_num.num= (Nat_big_num.of_int 32) (** ??? This should match something *) -let elf_dt_gnu_posflag_1 : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 939523838)(Nat_big_num.of_int 2))(Nat_big_num.of_int 1)) (*0x6ffffdfd*) -let elf_dt_gnu_relcount : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 939524093)(Nat_big_num.of_int 2)) (*0x6ffffffa*) -let elf_dt_gnu_relacount : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 939524092)(Nat_big_num.of_int 2))(Nat_big_num.of_int 1)) (*0x6FFFFFF9*) -let elf_dt_gnu_syminent : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 939523839)(Nat_big_num.of_int 2))(Nat_big_num.of_int 1)) (*0x6ffffdff*) -let elf_dt_gnu_syminfo : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 939523967)(Nat_big_num.of_int 2))(Nat_big_num.of_int 1)) (*0x6ffffeff*) -let elf_dt_gnu_syminsz : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 939523839)(Nat_big_num.of_int 2)) (*0x6ffffdfe*) -let elf_dt_gnu_valrnghi : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 939523839)(Nat_big_num.of_int 2))(Nat_big_num.of_int 1)) (*0x6ffffdff*) -let elf_dt_gnu_valrnglo : Nat_big_num.num= ( Nat_big_num.mul(Nat_big_num.of_int 939523712)(Nat_big_num.of_int 2)) (*0x6ffffd00*) -let elf_dt_gnu_verdef : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 939524094)(Nat_big_num.of_int 2)) (*0x6ffffffc*) -let elf_dt_gnu_verdefnum : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 939524094)(Nat_big_num.of_int 2))(Nat_big_num.of_int 1)) (*0x6ffffffd*) -let elf_dt_gnu_verneed : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 939524095)(Nat_big_num.of_int 2)) (*0x6ffffffe*) -let elf_dt_gnu_verneednum : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 939524095)(Nat_big_num.of_int 2))(Nat_big_num.of_int 1)) (*0x6fffffff*) -let elf_dt_gnu_versym : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 939524088)(Nat_big_num.of_int 2)) (*0x6ffffff0*) - -(** Not present in the LSB but turns up in "real" ELF files... *) - -let elf_dt_gnu_hash : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 939523962)(Nat_big_num.of_int 2))(Nat_big_num.of_int 1)) (*0x6ffffef5*) -let elf_dt_gnu_flags_1 : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 939524093)(Nat_big_num.of_int 2))(Nat_big_num.of_int 1)) (*0x6ffffffb*) -let elf_dt_gnu_checksum : Nat_big_num.num= ( Nat_big_num.mul(Nat_big_num.of_int 939523836)(Nat_big_num.of_int 2)) (* 0x6FFFFDF8 *) -let elf_dt_gnu_prelinked : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 939523834))(Nat_big_num.of_int 1)) (* 0x6FFFFDF5 *) - -(** Extended DT flags for FLAGS_1 dynamic section types. Taken from GLibC source - * as they appear to be completely unspecified! - *) - -let gnu_df_1_now : Nat_big_num.num= (Nat_big_num.of_int 1) (*0x00000001*) -let gnu_df_1_global : Nat_big_num.num= (Nat_big_num.of_int 2) (*0x00000002*) -let gnu_df_1_group : Nat_big_num.num= (Nat_big_num.of_int 4) (*0x00000004*) -let gnu_df_1_nodelete : Nat_big_num.num= (Nat_big_num.of_int 8) (*0x00000008*) -let gnu_df_1_loadfltr : Nat_big_num.num= (Nat_big_num.of_int 16) (*0x00000010*) -let gnu_df_1_initfirst : Nat_big_num.num= (Nat_big_num.of_int 32) (*0x00000020*) -let gnu_df_1_noopen : Nat_big_num.num= (Nat_big_num.of_int 64) (*0x00000040*) -let gnu_df_1_origin : Nat_big_num.num= (Nat_big_num.of_int 128) (*0x00000080*) -let gnu_df_1_direct : Nat_big_num.num= (Nat_big_num.of_int 256) (*0x00000100*) -let gnu_df_1_trans : Nat_big_num.num= (Nat_big_num.of_int 512) (*0x00000200*) -let gnu_df_1_interpose : Nat_big_num.num= (Nat_big_num.of_int 1024) (*0x00000400*) -let gnu_df_1_nodeflib : Nat_big_num.num= (Nat_big_num.of_int 2048) (*0x00000800*) -let gnu_df_1_nodump : Nat_big_num.num= (Nat_big_num.of_int 4096) (*0x00001000*) -let gnu_df_1_confalt : Nat_big_num.num= (Nat_big_num.of_int 8192) (*0x00002000*) -let gnu_df_1_endfiltee : Nat_big_num.num= (Nat_big_num.of_int 16384) (*0x00004000*) -let gnu_df_1_dispreldne : Nat_big_num.num= (Nat_big_num.of_int 32768) (*0x00008000*) -let gnu_df_1_disprelpnd : Nat_big_num.num= (Nat_big_num.of_int 65536) (*0x00010000*) - -(** [gnu_string_of_dt_flag1 m] produces a string based representation of GNU - * extensions flag_1 value [m]. - *) -(*val gnu_string_of_dt_flag_1 : natural -> string*) -let gnu_string_of_dt_flag_1 flag:string= - (if check_flag flag(Nat_big_num.of_int 0) then - "None" - else if check_flag flag gnu_df_1_now then - "NOW" - else if check_flag flag gnu_df_1_global then - "GLOBAL" - else if check_flag flag gnu_df_1_group then - "GROUP" - else if check_flag flag gnu_df_1_nodelete then - "NODELETE" - else if check_flag flag gnu_df_1_loadfltr then - "LOADFLTR" - else if check_flag flag gnu_df_1_initfirst then - "INITFIRST" - else if check_flag flag gnu_df_1_noopen then - "NOOPEN" - else if check_flag flag gnu_df_1_origin then - "ORIGIN" - else if check_flag flag gnu_df_1_direct then - "DIRECT" - else if check_flag flag gnu_df_1_trans then - "TRANS" - else if check_flag flag gnu_df_1_interpose then - "INTERPOSE" - else if check_flag flag gnu_df_1_nodeflib then - "NODEFLIB" - else if check_flag flag gnu_df_1_nodump then - "NODUMP" - else if check_flag flag gnu_df_1_confalt then - "CONFALT" - else if check_flag flag gnu_df_1_endfiltee then - "ENDFILTEE" - else if check_flag flag gnu_df_1_dispreldne then - "DISPRELDNE" - else if check_flag flag gnu_df_1_disprelpnd then - "DISPRELPND" - else if check_flag flag ( Nat_big_num.add gnu_df_1_nodelete gnu_df_1_now) then - "NOW NODELETE" - else if check_flag flag ( Nat_big_num.add gnu_df_1_nodelete gnu_df_1_initfirst) then - "NODELETE INITFIRST" - else (* XXX: add more as necessary *) - "Invalid GNU dynamic flag") - -(** [gnu_ext_os_additional_ranges m] checks whether dynamic section type [m] - * lies within the ranges set aside for GNU specific functionality. - * NB: quite ad hoc as this is not properly specified anywhere. - *) -(*val gnu_ext_os_additional_ranges : natural -> bool*) -let gnu_ext_os_additional_ranges m:bool= - (if Nat_big_num.greater_equal m elf_dt_gnu_addrrnglo && Nat_big_num.less_equal m elf_dt_gnu_addrrnghi then - true - else Nat_big_num.equal (* ad hoc extensions go here... *) - m elf_dt_gnu_verneed || (Nat_big_num.equal - m elf_dt_gnu_verneednum || (Nat_big_num.equal - m elf_dt_gnu_versym || (Nat_big_num.equal - m elf_dt_gnu_verdef || (Nat_big_num.equal - m elf_dt_gnu_verdefnum || (Nat_big_num.equal - m elf_dt_gnu_flags_1 || (Nat_big_num.equal - m elf_dt_gnu_relcount || (Nat_big_num.equal - m elf_dt_gnu_relacount || (Nat_big_num.equal - m elf_dt_gnu_checksum || Nat_big_num.equal - m elf_dt_gnu_prelinked))))))))) - -(** [gnu_ext_tag_correspondence_of_tag0 m] produces a tag correspondence for the - * extended GNU-specific dynamic section types [m]. Used to provide the ABI - * specific functionality expected of the corresponding function in the elf_dynamic - * module. - *) -(*val gnu_ext_tag_correspondence_of_tag0 : natural -> error tag_correspondence*) -let gnu_ext_tag_correspondence_of_tag0 m:(tag_correspondence)error= - (if Nat_big_num.equal m elf_dt_gnu_hash then - return C_Ptr - else if Nat_big_num.equal m elf_dt_gnu_flags_1 then - return C_Val - else if Nat_big_num.equal m elf_dt_gnu_versym then - return C_Ptr - else if Nat_big_num.equal m elf_dt_gnu_verneednum then - return C_Val - else if Nat_big_num.equal m elf_dt_gnu_verneed then - return C_Ptr - else if Nat_big_num.equal m elf_dt_gnu_verdef then - return C_Ptr - else if Nat_big_num.equal m elf_dt_gnu_verdefnum then - return C_Val - else if Nat_big_num.equal m elf_dt_gnu_relcount then - return C_Val - else if Nat_big_num.equal m elf_dt_gnu_relacount then - return C_Val - else if Nat_big_num.equal m elf_dt_gnu_checksum then - return C_Val - else if Nat_big_num.equal m elf_dt_gnu_prelinked then - return C_Val - else - fail "gnu_ext_tag_correspondence_of_tag0: invalid dynamic tag") - -(** [gnu_ext_tag_correspondence_of_tag m] produces a tag correspondence for the - * extended GNU-specific dynamic section types [m]. Used to provide the ABI - * specific functionality expected of the corresponding function in the elf_dynamic - * module. - * TODO: examine whether this and the function above really need separating into - * two functions. - *) -(*val gnu_ext_tag_correspondence_of_tag : natural -> error tag_correspondence*) -let gnu_ext_tag_correspondence_of_tag m:(tag_correspondence)error= - (if Nat_big_num.greater_equal m elf_dt_gnu_addrrnglo && Nat_big_num.less_equal m elf_dt_gnu_addrrnghi then - return C_Ptr - else if Nat_big_num.greater_equal m elf_dt_gnu_valrnglo && Nat_big_num.less_equal m elf_dt_gnu_valrnghi then - return C_Val - else if gnu_ext_os_additional_ranges m then - gnu_ext_tag_correspondence_of_tag0 m - else if Nat_big_num.equal m elf_dt_gnu_syminsz then - return C_Val (** unsure *) - else if Nat_big_num.equal m elf_dt_gnu_syminfo then - return C_Ptr (** unsure *) - else if Nat_big_num.equal m elf_dt_gnu_syminent then - return C_Val (** unsure *) - else if Nat_big_num.equal m elf_dt_gnu_posflag_1 then - return C_Val (** unsure *) - else if Nat_big_num.equal m elf_dt_gnu_num then - return C_Ignored - else if Nat_big_num.equal m elf_dt_gnu_filter then - return C_Val (** unsure *) - else if Nat_big_num.equal m elf_dt_gnu_auxiliary then - return C_Val (** unsure *) - else - fail ("gnu_ext_tag_correspondence_of_tag: unrecognised GNU dynamic tag")) - -(** [gnu_ext_elf32_value_of_elf32_dyn0 dyn] extracts a dynamic value from the - * dynamic section entry [dyn] under the assumption that its type is a GNU - * extended dynamic section type. Fails otherwise. Used to provide the - * ABI-specific functionality expected of the corresponding functions in - * elf_dynamic.lem. - *) -(*val gnu_ext_elf32_value_of_elf32_dyn0 : elf32_dyn -> string_table -> error elf32_dyn_value*) -let gnu_ext_elf32_value_of_elf32_dyn0 dyn stbl:(((Uint32.uint32),(Uint32.uint32))dyn_value)error= - (let tag = (Nat_big_num.abs (Nat_big_num.of_int32 dyn.elf32_dyn_tag)) in - if Nat_big_num.equal tag elf_dt_gnu_hash then - (match dyn.elf32_dyn_d_un with - | D_Val v -> fail "gnu_ext_elf32_value_of_elf32_dyn: GNU_HASH must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "gnu_ext_elf32_value_of_elf32_dyn: GNU_HASH must be a PTR" - ) >>= (fun addr -> - return (Address addr)) - else if Nat_big_num.equal tag elf_dt_gnu_flags_1 then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "gnu_ext_elf32_value_of_elf32_dyn: FLAGS_1 must be a Val" - | D_Ignored i -> fail "gnu_ext_elf32_value_of_elf32_dyn: FlAGS_1 must be a Val" - ) >>= (fun f -> - return (Flags1 (Nat_big_num.of_string (Uint32.to_string f)))) - else if Nat_big_num.equal tag elf_dt_gnu_versym then - (match dyn.elf32_dyn_d_un with - | D_Val v -> fail "gnu_ext_elf32_value_of_elf32_dyn: VERSYM must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "gnu_ext_elf32_value_of_elf32_dyn: VERSYM must be a PTR" - ) >>= (fun addr -> - return (Address addr)) - else if Nat_big_num.equal tag elf_dt_gnu_verdef then - (match dyn.elf32_dyn_d_un with - | D_Val v -> fail "gnu_ext_elf32_value_of_elf32_dyn: VERDEF must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "gnu_ext_elf32_value_of_elf32_dyn: VERDEF must be a PTR" - ) >>= (fun addr -> - return (Address addr)) - else if Nat_big_num.equal tag elf_dt_gnu_verdefnum then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "gnu_ext_elf32_value_of_elf32_dyn: VERDEFNUM must be a Val" - | D_Ignored i -> fail "gnu_ext_elf32_value_of_elf32_dyn: VERDEFNUM must be a Val" - ) >>= (fun sz -> - return (Numeric (Nat_big_num.of_string (Uint32.to_string sz)))) - else if Nat_big_num.equal tag elf_dt_gnu_verneednum then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "gnu_ext_elf32_value_of_elf32_dyn: VERNEEDNUM must be a Val" - | D_Ignored i -> fail "gnu_ext_elf32_value_of_elf32_dyn: VERNEEDNUM must be a Val" - ) >>= (fun sz -> - return (Numeric (Nat_big_num.of_string (Uint32.to_string sz)))) - else if Nat_big_num.equal tag elf_dt_gnu_verneed then - (match dyn.elf32_dyn_d_un with - | D_Val v -> fail "gnu_ext_elf32_value_of_elf32_dyn: VERNEED must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "gnu_ext_elf32_value_of_elf32_dyn: VERNEED must be a PTR" - ) >>= (fun addr -> - return (Address addr)) - else if Nat_big_num.equal tag elf_dt_gnu_relcount then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "gnu_ext_elf32_value_of_elf32_dyn: RELCOUNT must be a Val" - | D_Ignored i -> fail "gnu_ext_elf32_value_of_elf32_dyn: RELCOUNT must be a Val" - ) >>= (fun sz -> - return (Numeric (Nat_big_num.of_string (Uint32.to_string sz)))) - else if Nat_big_num.equal tag elf_dt_gnu_relacount then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "gnu_ext_elf32_value_of_elf32_dyn: RELACOUNT must be a Val" - | D_Ignored i -> fail "gnu_ext_elf32_value_of_elf32_dyn: RELACOUNT must be a Val" - ) >>= (fun sz -> - return (Numeric (Nat_big_num.of_string (Uint32.to_string sz)))) - else if Nat_big_num.equal tag elf_dt_gnu_checksum then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "gnu_ext_elf32_value_of_elf32_dyn: CHECKSUM must be a Val" - | D_Ignored i -> fail "gnu_ext_elf32_value_of_elf32_dyn: CHECKSUM must be a Val" - ) >>= (fun sz -> - return (Checksum (Nat_big_num.of_string (Uint32.to_string sz)))) - else if Nat_big_num.equal tag elf_dt_gnu_prelinked then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "gnu_ext_elf32_value_of_elf32_dyn: GNU_PRELINKED must be a Val" - | D_Ignored i -> fail "gnu_ext_elf32_value_of_elf32_dyn: GNU_PRELINKED must be a Val" - ) >>= (fun off -> - return (Timestamp (Nat_big_num.of_string (Uint32.to_string off)))) - else - fail "gnu_ext_elf32_value_of_elf32_dyn0: unrecognised GNU dynamic tag") - -(** [gnu_ext_elf64_value_of_elf64_dyn0 dyn] extracts a dynamic value from the - * dynamic section entry [dyn] under the assumption that its type is a GNU - * extended dynamic section type. Fails otherwise. Used to provide the - * ABI-specific functionality expected of the corresponding functions in - * elf_dynamic.lem. - *) -(*val gnu_ext_elf64_value_of_elf64_dyn0 : elf64_dyn -> string_table -> error elf64_dyn_value*) -let gnu_ext_elf64_value_of_elf64_dyn0 dyn stbl:(((Uint64.uint64),(Uint64.uint64))dyn_value)error= - (let tag = (Nat_big_num.abs (Nat_big_num.of_int64 dyn.elf64_dyn_tag)) in - if Nat_big_num.equal tag elf_dt_gnu_hash then - (match dyn.elf64_dyn_d_un with - | D_Val v -> fail "gnu_ext_elf64_value_of_elf64_dyn: GNU_HASH must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "gnu_ext_elf64_value_of_elf64_dyn: GNU_HASH must be a PTR" - ) >>= (fun addr -> - return (Address addr)) - else if Nat_big_num.equal tag elf_dt_gnu_flags_1 then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "gnu_ext_elf64_value_of_elf64_dyn: FLAGS_1 must be a Val" - | D_Ignored i -> fail "gnu_ext_elf64_value_of_elf64_dyn: FlAGS_1 must be a Val" - ) >>= (fun f -> - return (Flags1 (Ml_bindings.nat_big_num_of_uint64 f))) - else if Nat_big_num.equal tag elf_dt_gnu_versym then - (match dyn.elf64_dyn_d_un with - | D_Val v -> fail "gnu_ext_elf64_value_of_elf64_dyn: VERSYM must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "gnu_ext_elf64_value_of_elf64_dyn: VERSYM must be a PTR" - ) >>= (fun addr -> - return (Address addr)) - else if Nat_big_num.equal tag elf_dt_gnu_verdef then - (match dyn.elf64_dyn_d_un with - | D_Val v -> fail "gnu_ext_elf64_value_of_elf64_dyn: VERDEF must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "gnu_ext_elf64_value_of_elf64_dyn: VERDEF must be a PTR" - ) >>= (fun addr -> - return (Address addr)) - else if Nat_big_num.equal tag elf_dt_gnu_verdefnum then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "gnu_ext_elf32_value_of_elf64_dyn: VERDEFNUM must be a Val" - | D_Ignored i -> fail "gnu_ext_elf32_value_of_elf64_dyn: VERDEFNUM must be a Val" - ) >>= (fun sz -> - return (Numeric (Ml_bindings.nat_big_num_of_uint64 sz))) - else if Nat_big_num.equal tag elf_dt_gnu_verneednum then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "gnu_ext_elf64_value_of_elf64_dyn: VERNEEDNUM must be a Val" - | D_Ignored i -> fail "gnu_ext_elf64_value_of_elf64_dyn: VERNEEDNUM must be a Val" - ) >>= (fun sz -> - return (Numeric (Ml_bindings.nat_big_num_of_uint64 sz))) - else if Nat_big_num.equal tag elf_dt_gnu_verneed then - (match dyn.elf64_dyn_d_un with - | D_Val v -> fail "gnu_ext_elf64_value_of_elf64_dyn: VERNEED must be a PTR" - | D_Ptr p -> return p - | D_Ignored i -> fail "gnu_ext_elf64_value_of_elf64_dyn: VERNEED must be a PTR" - ) >>= (fun addr -> - return (Address addr)) - else if Nat_big_num.equal tag elf_dt_gnu_relcount then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "gnu_ext_elf64_value_of_elf64_dyn: RELCOUNT must be a Val" - | D_Ignored i -> fail "gnu_ext_elf64_value_of_elf64_dyn: RELCOUNT must be a Val" - ) >>= (fun sz -> - return (Numeric (Ml_bindings.nat_big_num_of_uint64 sz))) - else if Nat_big_num.equal tag elf_dt_gnu_relacount then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "gnu_ext_elf64_value_of_elf64_dyn: RELACOUNT must be a Val" - | D_Ignored i -> fail "gnu_ext_elf64_value_of_elf64_dyn: RELACOUNT must be a Val" - ) >>= (fun sz -> - return (Numeric (Ml_bindings.nat_big_num_of_uint64 sz))) - else if Nat_big_num.equal tag elf_dt_gnu_checksum then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "gnu_ext_elf64_value_of_elf64_dyn: CHECKSUM must be a Val" - | D_Ignored i -> fail "gnu_ext_elf64_value_of_elf64_dyn: CHECKSUM must be a Val" - ) >>= (fun sz -> - return (Checksum (Ml_bindings.nat_big_num_of_uint64 sz))) - else if Nat_big_num.equal tag elf_dt_gnu_prelinked then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "gnu_ext_elf64_value_of_elf64_dyn: GNU_PRELINKED must be a Val" - | D_Ignored i -> fail "gnu_ext_elf64_value_of_elf64_dyn: GNU_PRELINKED must be a Val" - ) >>= (fun off -> - return (Timestamp (Ml_bindings.nat_big_num_of_uint64 off))) - else - fail "gnu_ext_elf64_value_of_elf64_dyn0: unrecognised GNU dynamic tag") - -(** [gnu_ext_elf32_value_of_elf32_dyn dyn] extracts a dynamic value from the - * dynamic section entry [dyn] under the assumption that its type is a GNU - * extended dynamic section type. Fails otherwise. Used to provide the - * ABI-specific functionality expected of the corresponding functions in - * elf_dynamic.lem. - * TODO: some of these cases are missing as they have never come up in "real" - * ELF files that have been processed as part of validation. Try and find some - * files that do actually exhibit these. - *) -(*val gnu_ext_elf32_value_of_elf32_dyn : elf32_dyn -> string_table -> error elf32_dyn_value*) -let gnu_ext_elf32_value_of_elf32_dyn dyn stbl:(elf32_dyn_value)error= - (let tag = (Nat_big_num.abs (Nat_big_num.of_int32 dyn.elf32_dyn_tag)) in - if gnu_ext_os_additional_ranges tag then (* this should cover valrngs and addrrngs *) - gnu_ext_elf32_value_of_elf32_dyn0 dyn stbl - else if Nat_big_num.equal tag elf_dt_gnu_syminsz then - (match dyn.elf32_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "gnu_ext_elf32_value_of_elf32_dyn: SYMINSZ must be a VAL" - | D_Ignored i -> fail "gnu_ext_elf32_value_of_elf32_dyn: SYMINSZ must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag elf_dt_gnu_syminfo then - fail "SYMINFO" (* XXX: never seen in 32-bit ELF *) - else if Nat_big_num.equal tag elf_dt_gnu_syminent then - fail "SYMINENT" (* XXX: never seen in 32-bit ELF *) - else if Nat_big_num.equal tag elf_dt_gnu_posflag_1 then - fail "POSFLAG_1" (* XXX: never seen in 32-bit ELF *) - else if Nat_big_num.equal tag elf_dt_gnu_num then - fail "NUM" (* XXX: never seen in 32-bit ELF *) - else if Nat_big_num.equal tag elf_dt_gnu_filter then - fail "FILTER" (* XXX: never seen in 32-bit ELF *) - else if Nat_big_num.equal tag elf_dt_gnu_auxiliary then - fail "AUXILIARY" (* XXX: never seen in 32-bit ELF *) - else - fail "gnu_ext_elf32_value_of_elf32_dyn: unrecognised GNU dynamic tag") - -(** [gnu_ext_elf64_value_of_elf64_dyn dyn] extracts a dynamic value from the - * dynamic section entry [dyn] under the assumption that its type is a GNU - * extended dynamic section type. Fails otherwise. Used to provide the - * ABI-specific functionality expected of the corresponding functions in - * elf_dynamic.lem. - * TODO: some of these cases are missing as they have never come up in "real" - * ELF files that have been processed as part of validation. Try and find some - * files that do actually exhibit these. - *) -(*val gnu_ext_elf64_value_of_elf64_dyn : elf64_dyn -> string_table -> error elf64_dyn_value*) -let gnu_ext_elf64_value_of_elf64_dyn dyn stbl:(elf64_dyn_value)error= - (let tag = (Nat_big_num.abs (Nat_big_num.of_int64 dyn.elf64_dyn_tag)) in - if gnu_ext_os_additional_ranges tag then (* this should cover valrngs and addrrngs *) - gnu_ext_elf64_value_of_elf64_dyn0 dyn stbl - else if Nat_big_num.equal tag elf_dt_gnu_syminsz then - (match dyn.elf64_dyn_d_un with - | D_Val v -> return v - | D_Ptr p -> fail "gnu_ext_elf64_value_of_elf64_dyn: SYMINSZ must be a VAL" - | D_Ignored i -> fail "gnu_ext_elf64_value_of_elf64_dyn: SYMINSZ must be a VAL" - ) >>= (fun sz -> - return (Size sz)) - else if Nat_big_num.equal tag elf_dt_gnu_syminfo then - fail "SYMINFO" (* XXX: fill in as seen *) - else if Nat_big_num.equal tag elf_dt_gnu_syminent then - fail "SYMINENT" (* XXX: fill in as seen *) - else if Nat_big_num.equal tag elf_dt_gnu_posflag_1 then - fail "POSFLAG_1" (* XXX: fill in as seen *) - else if Nat_big_num.equal tag elf_dt_gnu_num then - fail "NUM" (* XXX: fill in as seen *) - else if Nat_big_num.equal tag elf_dt_gnu_filter then - fail "FILTER" (* XXX: fill in as seen *) - else if Nat_big_num.equal tag elf_dt_gnu_auxiliary then - fail "AUXILIARY" (* XXX: fill in as seen *) - else - fail "gnu_ext_elf64_value_of_elf64_dyn: unrecognised GNU dynamic tag") - -(** [string_of_gnu_ext_dynamic_tag0 m] produces a string based representation of - * GNU extensions dynamic tag value [m]. - *) -(*val string_of_gnu_ext_dynamic_tag0 : natural -> string*) -let string_of_gnu_ext_dynamic_tag0 m:string= - (if Nat_big_num.equal m elf_dt_gnu_hash then - "GNU_HASH" - else if Nat_big_num.equal m elf_dt_gnu_flags_1 then - "FLAGS_1" - else if Nat_big_num.equal m elf_dt_gnu_versym then - "VERSYM" - else if Nat_big_num.equal m elf_dt_gnu_verneednum then - "VERNEEDNUM" - else if Nat_big_num.equal m elf_dt_gnu_verneed then - "VERNEED" - else if Nat_big_num.equal m elf_dt_gnu_relcount then - "RELCOUNT" - else if Nat_big_num.equal m elf_dt_gnu_relacount then - "RELACOUNT" - else if Nat_big_num.equal m elf_dt_gnu_verdefnum then - "VERDEFNUM" - else if Nat_big_num.equal m elf_dt_gnu_verdef then - "VERDEF" - else if Nat_big_num.equal m elf_dt_gnu_checksum then - "CHECKSUM" - else if Nat_big_num.equal m elf_dt_gnu_prelinked then - "GNU_PRELINKED" - else - "Invalid dynamic tag") - -(** [string_of_gnu_ext_dynamic_tag m] produces a string based representation of - * GNU extensions dynamic tag value [m]. - *) -(*val string_of_gnu_ext_dynamic_tag : natural -> string*) -let string_of_gnu_ext_dynamic_tag m:string= - (if Nat_big_num.greater_equal m elf_dt_gnu_addrrnglo && Nat_big_num.less_equal m elf_dt_gnu_addrrnghi then - string_of_gnu_ext_dynamic_tag0 m - else if Nat_big_num.greater_equal m elf_dt_gnu_valrnglo && Nat_big_num.less_equal m elf_dt_gnu_valrnghi then - string_of_gnu_ext_dynamic_tag0 m - else if gnu_ext_os_additional_ranges m then - string_of_gnu_ext_dynamic_tag0 m - else if Nat_big_num.equal m elf_dt_gnu_syminsz then - "SYMINSZ" - else if Nat_big_num.equal m elf_dt_gnu_syminfo then - "SYMINFO" - else if Nat_big_num.equal m elf_dt_gnu_syminent then - "SYMINENT" - else if Nat_big_num.equal m elf_dt_gnu_posflag_1 then - "POSFLAG_1" - else if Nat_big_num.equal m elf_dt_gnu_num then - "NUM" - else if Nat_big_num.equal m elf_dt_gnu_filter then - "FILTER" - else if Nat_big_num.equal m elf_dt_gnu_auxiliary then - "AUXILIARY" - else - "Invalid dynamic tag") diff --git a/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_note.ml b/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_note.ml deleted file mode 100644 index f8f4328f..00000000 --- a/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_note.ml +++ /dev/null @@ -1,268 +0,0 @@ -(*Generated by Lem from gnu_extensions/gnu_ext_note.lem.*) -(** [gnu_ext_note] contains GNU extension specific definitions relating to the - * .note section/segment of an ELF file. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_list -open Lem_maybe -open Lem_string - -open Byte_sequence -open Endianness -open Error -open Missing_pervasives -open String_table - -open Elf_note -open Elf_section_header_table -open Elf_types_native_uint - -open Gnu_ext_section_header_table - -(** The following two functions are utility functions to convert a list of bytes - * into words, ready for further processing into strings. - *) - -(*val group_elf32_words : endianness -> list byte -> error (list elf32_word)*) -let rec group_elf32_words endian xs:((Uint32.uint32)list)error= - ((match xs with - | [] -> return [] - | x1::x2::x3::x4::xs -> - let bs0 = (Byte_sequence.from_byte_lists [[x1;x2;x3;x4]]) in - read_elf32_word endian bs0 >>= (fun (w, _) -> - group_elf32_words endian xs >>= (fun ws -> - return (w::ws))) - | xs -> fail "group_elf32_words: the impossible happened" - )) - -(*val group_elf64_words : endianness -> list byte -> error (list elf64_word)*) -let rec group_elf64_words endian xs:((Uint32.uint32)list)error= - ((match xs with - | [] -> return [] - | x1::x2::x3::x4::xs -> - let bs0 = (Byte_sequence.from_byte_lists [[x1;x2;x3;x4]]) in - read_elf64_word endian bs0 >>= (fun (w, _) -> - group_elf64_words endian xs >>= (fun ws -> - return (w::ws))) - | xs -> fail "group_elf64_words: the impossible happened" - )) - -(** [gnu_ext_check_elf32_abi_note_tag_section endain sht stbl bs0] checks the - * .note.ABI-tag section of an ELF file to ensure conformance with the GNU - * extensions. The string in this note should contain the string "GNU". - *) -(*val gnu_ext_check_elf32_abi_note_tag_section : endianness -> elf32_section_header_table -> - string_table -> byte_sequence -> bool*) -let gnu_ext_check_elf32_abi_note_tag_section endian sht sect_hdr_tbl bs0:bool= - (let abi_note_sects = -(List.filter (fun x -> - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string x.elf32_sh_type)) sht_note then - let nm = (Nat_big_num.of_string (Uint32.to_string x.elf32_sh_name)) in - (match String_table.get_string_at nm sect_hdr_tbl with - | Success name1 -> name1 = ".note.ABI-tag" - | Fail _ -> false - ) - else - false - ) sht) - in - (match abi_note_sects with - | [note] -> - let off = (Nat_big_num.of_string (Uint32.to_string note.elf32_sh_offset)) in - let siz = (Nat_big_num.of_string (Uint32.to_string note.elf32_sh_size)) in - let abi_tag = -(Byte_sequence.offset_and_cut off siz bs0 >>= (fun rel -> - Elf_note.read_elf32_note endian rel >>= (fun (abi_tag, _) -> - return abi_tag))) - in - (match abi_tag with - | Fail _ -> false - | Success abi_tag -> - let str = (name_string_of_elf32_note abi_tag) in - if str = "GNU\000" then - if Nat_big_num.greater_equal (Nat_big_num.of_string (Uint32.to_string abi_tag.elf32_note_descsz))(Nat_big_num.of_int 16) then - let take2 = (Lem_list.take( 16) abi_tag.elf32_note_desc) in - if List.length take2 < 16 then - false - else - true - else - false - else - false - ) - | _ -> - false - )) - -(** [gnu_ext_check_elf64_abi_note_tag_section endain sht stbl bs0] checks the - * .note.ABI-tag section of an ELF file to ensure conformance with the GNU - * extensions. The string in this note should contain the string "GNU". - *) -(*val gnu_ext_check_elf64_abi_note_tag_section : endianness -> elf64_section_header_table -> - string_table -> byte_sequence -> bool*) -let gnu_ext_check_elf64_abi_note_tag_section endian sht sect_hdr_tbl bs0:bool= - (let abi_note_sects = -(List.filter (fun x -> - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string x.elf64_sh_type)) sht_note then - let nm = (Nat_big_num.of_string (Uint32.to_string x.elf64_sh_name)) in - (match String_table.get_string_at nm sect_hdr_tbl with - | Success name1 -> name1 = ".note.ABI-tag" - | Fail _ -> false - ) - else - false - ) sht) - in - (match abi_note_sects with - | [note] -> - let off = (Nat_big_num.of_string (Uint64.to_string note.elf64_sh_offset)) in - let siz = (Ml_bindings.nat_big_num_of_uint64 note.elf64_sh_size) in - let abi_tag = -(Byte_sequence.offset_and_cut off siz bs0 >>= (fun rel -> - Elf_note.read_elf64_note endian rel >>= (fun (abi_tag, _) -> - return abi_tag))) - in - (match abi_tag with - | Fail _ -> false - | Success abi_tag -> - let str = (name_string_of_elf64_note abi_tag) in - if str = "GNU\000" then - if Nat_big_num.greater_equal (Ml_bindings.nat_big_num_of_uint64 abi_tag.elf64_note_descsz)(Nat_big_num.of_int 16) then - let take2 = (Lem_list.take( 16) abi_tag.elf64_note_desc) in - if List.length take2 < 16 then - false - else - true - else - false - else - false - ) - | _ -> - false - )) - -(** [gnu_ext_extract_elf32_earliest_compatible_kernel end sht stab bs0] extracts - * the earliest compatible Linux kernel with the given ELF file from its section - * header table [sht], and string table [stbl], assuming endianness [endian]. - * NB: marked as OCaml only as need to extract a string from integers. - * TODO: implement some string parsing functions in Isabelle/HOL so things like - * this can be extracted. - *) -(*val gnu_ext_extract_elf32_earliest_compatible_kernel : endianness -> elf32_section_header_table -> - string_table -> byte_sequence -> error string*) -let gnu_ext_extract_elf32_earliest_compatible_kernel endian sht sect_hdr_tbl bs0:(string)error= - (let abi_note_sects = -(List.filter (fun x -> - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string x.elf32_sh_type)) sht_note then - let nm = (Nat_big_num.of_string (Uint32.to_string x.elf32_sh_name)) in - (match String_table.get_string_at nm sect_hdr_tbl with - | Success name1 -> name1 = ".note.ABI-tag" - | Fail _ -> false - ) - else - false - ) sht) - in - (match abi_note_sects with - | [note] -> - let off = (Nat_big_num.of_string (Uint32.to_string note.elf32_sh_offset)) in - let siz = (Nat_big_num.of_string (Uint32.to_string note.elf32_sh_size)) in - let abi_tag = -(Byte_sequence.offset_and_cut off siz bs0 >>= (fun rel -> - Elf_note.read_elf32_note endian rel >>= (fun (abi_tag, _) -> - return abi_tag))) - in - (match abi_tag with - | Fail _ -> fail "gnu_ext_extract_elf32_earliest_compatible_kernel: parsing of NOTE section failed" - | Success abi_tag -> - let str = (name_string_of_elf32_note abi_tag) in - if str = "GNU\000" then - if Nat_big_num.greater_equal (Nat_big_num.of_string (Uint32.to_string abi_tag.elf32_note_descsz))(Nat_big_num.of_int 16) then - let take2 = (Lem_list.take( 16) abi_tag.elf32_note_desc) in - if List.length take2 < 16 then - fail "gnu_ext_extract_elf32_earliest_compatible_kernel: the impossible happened" - else - (match group_elf32_words endian take2 with - | Fail err -> fail "gnu_ext_extract_elf32_earliest_compatible_kernel: word grouping failed" - | Success ss -> - (match ss with - | c1::c2::c3::cs -> - let c1 = (Uint32.to_string c1) in - let c2 = (Uint32.to_string c2) in - let c3 = (Uint32.to_string c3) in - return (List.fold_right (^) (intercalate "." [c1;c2;c3]) "") - | _ -> fail "gnu_ext_extract_elf32_earliest_compatible_kernel: kernel version must have three components" - ) - ) - else - fail "gnu_ext_extract_elf32_earliest_compatible_kernel: .note.ABI-tag description size not required length" - else - fail "gnu_ext_extract_elf32_earliest_compatible_kernel: required GNU string not present" - ) - | _ -> fail "gnu_ext_extract_elf32_earliest_compatible_kernel: more than one .note.ABI-tag section present" - )) - -(** [gnu_ext_extract_elf64_earliest_compatible_kernel end sht stab bs0] extracts - * the earliest compatible Linux kernel with the given ELF file from its section - * header table [sht], and string table [stbl], assuming endianness [endian]. - * NB: marked as OCaml only as need to extract a string from integers. - * TODO: implement some string parsing functions in Isabelle/HOL so things like - * this can be extracted. - *) -(*val gnu_ext_extract_elf64_earliest_compatible_kernel : endianness -> elf64_section_header_table -> - string_table -> byte_sequence -> error string*) -let gnu_ext_extract_elf64_earliest_compatible_kernel endian sht sect_hdr_tbl bs0:(string)error= - (let abi_note_sects = -(List.filter (fun x -> - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string x.elf64_sh_type)) sht_note then - let nm = (Nat_big_num.of_string (Uint32.to_string x.elf64_sh_name)) in - (match String_table.get_string_at nm sect_hdr_tbl with - | Success name1 -> name1 = ".note.ABI-tag" - | Fail _ -> false - ) - else - false - ) sht) - in - (match abi_note_sects with - | [note] -> - let off = (Nat_big_num.of_string (Uint64.to_string note.elf64_sh_offset)) in - let siz = (Ml_bindings.nat_big_num_of_uint64 note.elf64_sh_size) in - let abi_tag = -(Byte_sequence.offset_and_cut off siz bs0 >>= (fun rel -> - Elf_note.read_elf64_note endian rel >>= (fun (abi_tag, _) -> - return abi_tag))) - in - (match abi_tag with - | Fail _ -> fail "gnu_ext_extract_elf64_earliest_compatible_kernel: parsing of NOTE section failed" - | Success abi_tag -> - let str = (name_string_of_elf64_note abi_tag) in - if str = "GNU\000" then - if Nat_big_num.greater_equal (Ml_bindings.nat_big_num_of_uint64 abi_tag.elf64_note_descsz)(Nat_big_num.of_int 16) then - let take2 = (Lem_list.take( 16) abi_tag.elf64_note_desc) in - if List.length take2 < 16 then - fail "gnu_ext_extract_elf64_earliest_compatible_kernel: the impossible happened" - else - (match group_elf64_words endian take2 with - | Fail err -> fail "gnu_ext_extract_elf64_earliest_compatible_kernel: word grouping failed" - | Success ss -> - (match ss with - | c1::c2::c3::cs -> - let c1 = (Uint32.to_string c1) in - let c2 = (Uint32.to_string c2) in - let c3 = (Uint32.to_string c3) in - return (List.fold_right (^) (intercalate "." [c1;c2;c3]) "") - | _ -> fail "gnu_ext_extract_elf64_earliest_compatible_kernel: kernel version must have three components" - ) - ) - else - fail "gnu_ext_extract_elf64_earliest_compatible_kernel: .note.ABI-tag description size not required length" - else - fail "gnu_ext_extract_elf64_earliest_compatible_kernel: required GNU string not present" - ) - | _ -> fail "gnu_ext_extract_elf64_earliest_compatible_kernel: more than one .note.ABI-tag section present" - )) diff --git a/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_program_header_table.ml b/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_program_header_table.ml deleted file mode 100644 index 4c5b78c1..00000000 --- a/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_program_header_table.ml +++ /dev/null @@ -1,34 +0,0 @@ -(*Generated by Lem from gnu_extensions/gnu_ext_program_header_table.lem.*) -(** [gnu_ext_program_header_table] contains GNU extension specific functionality - * related to the program header table. - *) - -open Lem_basic_classes -open Lem_num - -(** GNU extensions, as defined in the LSB, see section 11.2. *) - -(** The element specifies the location and size of a segment that may be made - * read-only after relocations have been processed. - *) -let elf_pt_gnu_relro : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 4)(Nat_big_num.of_int 421345620))(Nat_big_num.of_int 2)) (* 0x6474e552 *) -(** The [p_flags] member specifies the permissions of the segment containing the - * stack and is used to indicate whether the stack should be executable. - *) -let elf_pt_gnu_stack : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 4)(Nat_big_num.of_int 421345620))(Nat_big_num.of_int 1)) (* 0x6474e551 *) -(** Element specifies the location and size of exception handling information. *) -let elf_pt_gnu_eh_frame : Nat_big_num.num= (Nat_big_num.mul(Nat_big_num.of_int 4)(Nat_big_num.of_int 421345620)) (* 0x6474e550 *) - -(** [string_of_gnu_ext_segment_type m] produces a string representation of - * GNU extension segment type [m]. - *) -(*val string_of_gnu_ext_segment_type : natural -> string*) -let string_of_gnu_ext_segment_type pt:string= - (if Nat_big_num.equal pt elf_pt_gnu_relro then - "GNU_RELRO" - else if Nat_big_num.equal pt elf_pt_gnu_stack then - "GNU_STACK" - else if Nat_big_num.equal pt elf_pt_gnu_eh_frame then - "GNU_EH_FRAME" - else - "Invalid GNU EXT segment type") diff --git a/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_section_header_table.ml b/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_section_header_table.ml deleted file mode 100644 index 98faa8e4..00000000 --- a/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_section_header_table.ml +++ /dev/null @@ -1,151 +0,0 @@ -(*Generated by Lem from gnu_extensions/gnu_ext_section_header_table.lem.*) -(** The module [gnu_ext_section_header_table] implements function, definitions - * and types relating to the GNU extensions to the standard ELF section header - * table. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_map -open Lem_maybe -open Lem_num -open Lem_string - -open Hex_printing - -open Error -open String_table -open Show - -open Elf_section_header_table -open Elf_interpreted_section - -(** GNU extended section types *) - -(** [GNU_HASH] does not appear to be defined in the LSB but is present in - * several ELF binaries collected in the wild... - * - * TODO: find out where this comes from? - * ANSW: a mailing list apparently! See here: - * https://sourceware.org/ml/binutils/2006-10/msg00377.html - *) -let sht_gnu_hash : Nat_big_num.num= ( Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 939524091)) (* 0x6FFFFFF6 *) - -(** The following are all defined in Section 10.2.2.2 of the LSB as additional - * section types over the ones defined in the SCO ELF spec. - *) - -(** [sht_gnu_verdef] contains the symbol versions that are provided. - *) -let sht_gnu_verdef : Nat_big_num.num= (Nat_big_num.sub_nat ( Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 939524095))(Nat_big_num.of_int 1)) (* 0x6ffffffd *) -(** [sht_gnu_verneed] contains the symbol versions that are required. - *) -let sht_gnu_verneed : Nat_big_num.num= ( Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 939524095)) (* 0x6ffffffe *) -(** [sht_gnu_versym] contains the symbol version table. - *) -let sht_gnu_versym : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 939524095))(Nat_big_num.of_int 1)) (* 0x6fffffff *) -(** [sht_gnu_liblist] appears to be undocumented but appears in PowerPC 64 ELF - * binaries in "the wild". - *) -let sht_gnu_liblist : Nat_big_num.num= (Nat_big_num.add ( Nat_big_num.mul(Nat_big_num.of_int 2)(Nat_big_num.of_int 939524091))(Nat_big_num.of_int 1)) (* 0x6FFFFFF7 *) - -(** [string_of_gnu_ext_section_type m] produces a string based representation of - * GNU extension section type [m]. - *) -(*val string_of_gnu_ext_section_type : natural -> string*) -let string_of_gnu_ext_section_type i:string= - (if Nat_big_num.equal i sht_gnu_hash then - "GNU_HASH" - else if Nat_big_num.equal i sht_gnu_verdef then - "VERDEF" - else if Nat_big_num.equal i sht_gnu_verneed then - "VERNEED" - else if Nat_big_num.equal i sht_gnu_versym then - "VERSYM" - else if Nat_big_num.equal i sht_gnu_liblist then - "GNU_LIBLIST" - else if Nat_big_num.greater_equal i sht_loos && Nat_big_num.less_equal i sht_hios then - let diff = (Nat_big_num.sub_nat i sht_loos) in - let suff = (unsafe_hex_string_of_natural( 0) diff) in - "LOOS+" ^ suff - else - "Invalid GNU EXT section type: " ^ Nat_big_num.to_string i) - -(** [gnu_ext_additionall_special_sections] records additional section names that - * map appear in GNU ELF binaries and their required associated types and - * attributes. See Section 10.3.1.1 of the LSB and the related map - * [elf_special_sections] in [Elf_section_header_table] which records section - * names and their required types and attributes that all ELF binaries share. - *) -(*val gnu_ext_additional_special_sections : Map.map string (natural * natural)*) -let gnu_ext_additional_special_sections:((string),(Nat_big_num.num*Nat_big_num.num))Pmap.map= - (Lem_map.fromList (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) [ - (".ctors", (sht_progbits, Nat_big_num.add shf_alloc shf_write)) - ; (".data.rel.ro", (sht_progbits, Nat_big_num.add shf_alloc shf_write)) - ; (".dtors", (sht_progbits, Nat_big_num.add shf_alloc shf_write)) - ; (".eh_frame", (sht_progbits, shf_alloc)) - ; (".eh_frame_hdr", (sht_progbits, shf_alloc)) - ; (".gcc_execpt_table", (sht_progbits, shf_alloc)) - ; (".gnu.version", (sht_gnu_versym, shf_alloc)) - ; (".gnu.version_d", (sht_gnu_verdef, shf_alloc)) - ; (".gnu.version_r", (sht_gnu_verneed, shf_alloc)) - ; (".got.plt", (sht_progbits, Nat_big_num.add shf_alloc shf_write)) - ; (".jcr", (sht_progbits, Nat_big_num.add shf_alloc shf_write)) - ; (".note.ABI-tag", (sht_note, shf_alloc)) - ; (".stab", (sht_progbits,Nat_big_num.of_int 0)) - ; (".stabstr", (sht_strtab,Nat_big_num.of_int 0)) - ]) - -(** [is_valid_gnu_ext_elf32_section_header_table_entry scts stbl] checks whether - * sections [scts] conforms with the contents of the special sections table. - * Fails otherwise. - *) -(*val is_valid_gnu_ext_elf32_section_header_table_entry : elf32_interpreted_section -> - string_table -> bool*) -let is_valid_gnu_ext_elf32_section_header_table_entry ent stbl:bool= - ((match String_table.get_string_at ent.elf32_section_name stbl with - | Fail f -> false - | Success name1 -> - (match Pmap.lookup name1 gnu_ext_additional_special_sections with - | None -> - is_valid_elf32_section_header_table_entry ent stbl - | Some (typ, flags) -> Nat_big_num.equal - typ ent.elf32_section_type && Nat_big_num.equal flags ent.elf32_section_flags - ) - )) - -(** [is_valid_gnu_ext_elf32_section_header_table sht stbl] checks whether every - * member of the section header table [sht] conforms with the special sections - * table. - *) -(*val is_valid_gnu_ext_elf32_section_header_table : list elf32_interpreted_section -> - string_table -> bool*) -let is_valid_gnu_ext_elf32_section_header_table ents stbl:bool= - (List.for_all (fun x -> is_valid_gnu_ext_elf32_section_header_table_entry x stbl) ents) - -(** [is_valid_gnu_ext_elf64_section_header_table_entry scts stbl] checks whether - * sections [scts] conforms with the contents of the special sections table. - * Fails otherwise. - *) -(*val is_valid_gnu_ext_elf64_section_header_table_entry : elf64_interpreted_section -> - string_table -> bool*) -let is_valid_gnu_ext_elf64_section_header_table_entry ent stbl:bool= - ((match String_table.get_string_at ent.elf64_section_name stbl with - | Fail f -> false - | Success name1 -> - (match Pmap.lookup name1 gnu_ext_additional_special_sections with - | None -> - is_valid_elf64_section_header_table_entry ent stbl - | Some (typ, flags) -> Nat_big_num.equal - typ ent.elf64_section_type && Nat_big_num.equal flags ent.elf64_section_flags - ) - )) - -(** [is_valid_gnu_ext_elf64_section_header_table sht stbl] checks whether every - * member of the section header table [sht] conforms with the special sections - * table. - *) -(*val is_valid_gnu_ext_elf64_section_header_table : list elf64_interpreted_section -> - string_table -> bool*) -let is_valid_gnu_ext_elf64_section_header_table ents stbl:bool= - (List.for_all (fun x -> is_valid_gnu_ext_elf64_section_header_table_entry x stbl) ents) diff --git a/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_section_to_segment_mapping.ml b/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_section_to_segment_mapping.ml deleted file mode 100644 index 86a5c5ed..00000000 --- a/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_section_to_segment_mapping.ml +++ /dev/null @@ -1,265 +0,0 @@ -(*Generated by Lem from gnu_extensions/gnu_ext_section_to_segment_mapping.lem.*) -(** [gnu_ext_section_to_segment_mapping] contains (GNU specific) functionality - * relating to calculating the section to segment mapping for an ELF file. In - * particular, the test over whether a section is inside a segment is ABI - * specific. This module provides that test. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_num - -open Elf_header -open Elf_program_header_table -open Elf_section_header_table -open Elf_types_native_uint - -open Lem_string -open Show - -open Gnu_ext_program_header_table - -(** [elf32_section_in_segment sec_hdr segment] implements the - * ELF_SECTION_IN_SEGMENT1 macro from readelf. Note the macro is always used - * with [check_vma] and [strict] set to 1. - * - #define ELF_SECTION_IN_SEGMENT_1(sec_hdr, segment, check_vma, strict) \ - ((/* Only PT_LOAD, PT_GNU_RELRO and PT_TLS segments can contain \ - SHF_TLS sections. */ \ - ((((sec_hdr)->sh_flags & SHF_TLS) != 0) \ - && ((segment)->p_type == PT_TLS \ - || (segment)->p_type == PT_GNU_RELRO \ - || (segment)->p_type == PT_LOAD)) \ - /* PT_TLS segment contains only SHF_TLS sections, PT_PHDR no \ - sections at all. */ \ - || (((sec_hdr)->sh_flags & SHF_TLS) == 0 \ - && (segment)->p_type != PT_TLS \ - && (segment)->p_type != PT_PHDR)) \ - /* PT_LOAD and similar segments only have SHF_ALLOC sections. */ \ - && !(((sec_hdr)->sh_flags & SHF_ALLOC) == 0 \ - && ((segment)->p_type == PT_LOAD \ - || (segment)->p_type == PT_DYNAMIC \ - || (segment)->p_type == PT_GNU_EH_FRAME \ - || (segment)->p_type == PT_GNU_RELRO \ - || (segment)->p_type == PT_GNU_STACK)) \ - /* Any section besides one of type SHT_NOBITS must have file \ - offsets within the segment. */ \ - && ((sec_hdr)->sh_type == SHT_NOBITS \ - || ((bfd_vma) (sec_hdr)->sh_offset >= (segment)->p_offset \ - && (!(strict) \ - || ((sec_hdr)->sh_offset - (segment)->p_offset \ - <= (segment)->p_filesz - 1)) \ - && (((sec_hdr)->sh_offset - (segment)->p_offset \ - + ELF_SECTION_SIZE(sec_hdr, segment)) \ - <= (segment)->p_filesz))) \ - /* SHF_ALLOC sections must have VMAs within the segment. */ \ - && (!(check_vma) \ - || ((sec_hdr)->sh_flags & SHF_ALLOC) == 0 \ - || ((sec_hdr)->sh_addr >= (segment)->p_vaddr \ - && (!(strict) \ - || ((sec_hdr)->sh_addr - (segment)->p_vaddr \ - <= (segment)->p_memsz - 1)) \ - && (((sec_hdr)->sh_addr - (segment)->p_vaddr \ - + ELF_SECTION_SIZE(sec_hdr, segment)) \ - <= (segment)->p_memsz))) \ - /* No zero size sections at start or end of PT_DYNAMIC. */ \ - && ((segment)->p_type != PT_DYNAMIC \ - || (sec_hdr)->sh_size != 0 \ - || (segment)->p_memsz == 0 \ - || (((sec_hdr)->sh_type == SHT_NOBITS \ - || ((bfd_vma) (sec_hdr)->sh_offset > (segment)->p_offset \ - && ((sec_hdr)->sh_offset - (segment)->p_offset \ - < (segment)->p_filesz))) \ - && (((sec_hdr)->sh_flags & SHF_ALLOC) == 0 \ - || ((sec_hdr)->sh_addr > (segment)->p_vaddr \ - && ((sec_hdr)->sh_addr - (segment)->p_vaddr \ - < (segment)->p_memsz)))))) - * - * From [internal.h] of readelf's source code. - *) - -(*val elf32_section_flags : elf32_section_header_table_entry -> natural -> bool*) -let elf32_section_flags0 sec_hdr typ:bool= (not ((Uint32.logand sec_hdr.elf32_sh_flags (Uint32.of_string (Nat_big_num.to_string typ))) = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))))) - -(*val elf64_section_flags : elf64_section_header_table_entry -> natural -> bool*) -let elf64_section_flags0 sec_hdr typ:bool= (not ((Uint64.logand sec_hdr.elf64_sh_flags (Uint64.of_string (Nat_big_num.to_string typ))) = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))))) - -(*val elf32_section_of_type : elf32_section_header_table_entry -> natural -> bool*) -let elf32_section_of_type sec_hdr typ:bool= - (sec_hdr.elf32_sh_type = Uint32.of_string (Nat_big_num.to_string typ)) - -(*val elf64_section_of_type : elf64_section_header_table_entry -> natural -> bool*) -let elf64_section_of_type sec_hdr typ:bool= - (sec_hdr.elf64_sh_type = Uint32.of_string (Nat_big_num.to_string typ)) - -(*val elf32_segment_of_type : elf32_program_header_table_entry -> natural -> bool*) -let elf32_segment_of_type segment typ:bool= - (segment.elf32_p_type = Uint32.of_string (Nat_big_num.to_string typ)) - -(*val elf64_segment_of_type : elf64_program_header_table_entry -> natural -> bool*) -let elf64_segment_of_type segment typ:bool= - (segment.elf64_p_type = Uint32.of_string (Nat_big_num.to_string typ)) - -(** Only PT_LOAD, PT_GNU_RELRO and PT_TLS segments can contain SHF_TLS sections - * and PT_TLS segment contains only SHF_TLS sections, PT_PHDR no sections at all - *) -(*val elf32_section_in_segment1 : elf32_section_header_table_entry -> elf32_program_header_table_entry -> bool*) -let elf32_section_in_segment1 sec_hdr segment:bool= - ((elf32_section_flags0 sec_hdr shf_tls && - (elf32_segment_of_type segment elf_pt_tls || -(elf32_segment_of_type segment elf_pt_gnu_relro || - elf32_segment_of_type segment elf_pt_load))) || - (not (elf32_section_flags0 sec_hdr shf_tls) - && (not (elf32_segment_of_type segment elf_pt_tls) - && not (elf32_segment_of_type segment elf_pt_phdr)))) - -(*val elf64_section_in_segment1 : elf64_section_header_table_entry -> elf64_program_header_table_entry -> bool*) -let elf64_section_in_segment1 sec_hdr segment:bool= - ((elf64_section_flags0 sec_hdr shf_tls && - (elf64_segment_of_type segment elf_pt_tls || -(elf64_segment_of_type segment elf_pt_gnu_relro || - elf64_segment_of_type segment elf_pt_load))) || - (not (elf64_section_flags0 sec_hdr shf_tls) - && (not (elf64_segment_of_type segment elf_pt_tls) - && not (elf64_segment_of_type segment elf_pt_phdr)))) - -(** PT_LOAD and similar segments only have SHF_ALLOC sections *) - -(*val elf32_section_in_segment2 : elf32_section_header_table_entry -> elf32_program_header_table_entry -> bool*) -let elf32_section_in_segment2 sec_hdr segment:bool= - (not ((not (elf32_section_flags0 sec_hdr shf_alloc)) && - (elf32_segment_of_type segment elf_pt_load || -(elf32_segment_of_type segment elf_pt_dynamic || -(elf32_segment_of_type segment elf_pt_gnu_eh_frame || -(elf32_segment_of_type segment elf_pt_gnu_relro || - elf32_segment_of_type segment elf_pt_gnu_stack)))))) - -(*val elf64_section_in_segment2 : elf64_section_header_table_entry -> elf64_program_header_table_entry -> bool*) -let elf64_section_in_segment2 sec_hdr segment:bool= - (not ((not (elf64_section_flags0 sec_hdr shf_alloc)) && - (elf64_segment_of_type segment elf_pt_load || -(elf64_segment_of_type segment elf_pt_dynamic || -(elf64_segment_of_type segment elf_pt_gnu_eh_frame || -(elf64_segment_of_type segment elf_pt_gnu_relro || - elf64_segment_of_type segment elf_pt_gnu_stack)))))) - - -(** Any section besides one of type SHT_NOBITS must have file offsets within - * the segment. - *) - -(*val elf32_sect_size : elf32_header -> elf32_section_header_table_entry -> elf32_program_header_table_entry -> natural*) -let elf32_sect_size hdr sec_hdr segment:Nat_big_num.num= - (if is_elf32_tbss_special sec_hdr segment then Nat_big_num.of_int 0 - else - Nat_big_num.of_string (Uint32.to_string (hdr.elf32_shentsize))) - -(*val elf64_sect_size : elf64_header -> elf64_section_header_table_entry -> elf64_program_header_table_entry -> natural*) -let elf64_sect_size hdr sec_hdr segment:Nat_big_num.num= - (if is_elf64_tbss_special sec_hdr segment then Nat_big_num.of_int 0 - else - Nat_big_num.of_string (Uint32.to_string (hdr.elf64_shentsize))) - -(*val elf32_section_in_segment3 : elf32_header -> elf32_section_header_table_entry -> elf32_program_header_table_entry -> bool*) -let elf32_section_in_segment3 hdr sec_hdr segment:bool= - (let sec_off = ((Nat_big_num.of_string (Uint32.to_string sec_hdr.elf32_sh_offset))) in - let seg_off = ((Nat_big_num.of_string (Uint32.to_string segment.elf32_p_offset))) in - let seg_fsz = ((Nat_big_num.of_string (Uint32.to_string segment.elf32_p_filesz))) in - let sec_siz = ((elf32_sect_size hdr sec_hdr segment)) in - elf32_section_of_type sec_hdr sht_nobits || - ( Nat_big_num.greater_equal sec_off seg_off && -(( Nat_big_num.less_equal( Nat_big_num.sub sec_off seg_off) ( Nat_big_num.sub seg_fsz(Nat_big_num.of_int 1))) && - ( Nat_big_num.less_equal (Nat_big_num.sub sec_off ( Nat_big_num.add seg_off sec_siz)) seg_fsz)))) - -(*val elf64_section_in_segment3 : elf64_header -> elf64_section_header_table_entry -> elf64_program_header_table_entry -> bool*) -let elf64_section_in_segment3 hdr sec_hdr segment:bool= - (let sec_off = ((Nat_big_num.of_string (Uint64.to_string sec_hdr.elf64_sh_offset))) in - let seg_off = ((Nat_big_num.of_string (Uint64.to_string segment.elf64_p_offset))) in - let seg_fsz = ((Ml_bindings.nat_big_num_of_uint64 segment.elf64_p_filesz)) in - let sec_siz = ((elf64_sect_size hdr sec_hdr segment)) in - elf64_section_of_type sec_hdr sht_nobits || - ( Nat_big_num.greater_equal sec_off seg_off && -(( Nat_big_num.less_equal( Nat_big_num.sub sec_off seg_off) ( Nat_big_num.sub seg_fsz(Nat_big_num.of_int 1))) && - ( Nat_big_num.less_equal (Nat_big_num.sub sec_off ( Nat_big_num.add seg_off sec_siz)) seg_fsz)))) - -(** SHF_ALLOC sections must have VMAs within the segment - *) - -(*val elf32_section_in_segment4 : elf32_header -> elf32_section_header_table_entry -> elf32_program_header_table_entry -> bool*) -let elf32_section_in_segment4 hdr sec_hdr segment:bool= - (let sec_addr = ((Nat_big_num.of_string (Uint32.to_string sec_hdr.elf32_sh_addr))) in - let seg_vadr = ((Nat_big_num.of_string (Uint32.to_string segment.elf32_p_vaddr))) in - let seg_mmsz = ((Nat_big_num.of_string (Uint32.to_string segment.elf32_p_memsz))) in - let sec_size = ((elf32_sect_size hdr sec_hdr segment)) in - (not (elf32_section_flags0 sec_hdr shf_alloc) || Nat_big_num.greater_equal - sec_addr seg_vadr) && (Nat_big_num.less_equal (Nat_big_num.sub - sec_addr seg_vadr) (Nat_big_num.sub seg_mmsz(Nat_big_num.of_int 1)) && Nat_big_num.less_equal (Nat_big_num.sub - sec_addr ( Nat_big_num.add seg_vadr sec_size)) seg_mmsz)) - -(*val elf64_section_in_segment4 : elf64_header -> elf64_section_header_table_entry -> elf64_program_header_table_entry -> bool*) -let elf64_section_in_segment4 hdr sec_hdr segment:bool= - (let sec_addr = ((Ml_bindings.nat_big_num_of_uint64 sec_hdr.elf64_sh_addr)) in - let seg_vadr = ((Ml_bindings.nat_big_num_of_uint64 segment.elf64_p_vaddr)) in - let seg_mmsz = ((Ml_bindings.nat_big_num_of_uint64 segment.elf64_p_memsz)) in - let sec_size = ((elf64_sect_size hdr sec_hdr segment)) in - (not (elf64_section_flags0 sec_hdr shf_alloc) || Nat_big_num.greater_equal - sec_addr seg_vadr) && (Nat_big_num.less_equal (Nat_big_num.sub - sec_addr seg_vadr) (Nat_big_num.sub seg_mmsz(Nat_big_num.of_int 1)) && Nat_big_num.less_equal (Nat_big_num.sub - sec_addr ( Nat_big_num.add seg_vadr sec_size)) seg_mmsz)) - -(** No zero size sections at start or end of PT_DYNAMIC *) - -(*val elf32_section_in_segment5 : elf32_section_header_table_entry -> elf32_program_header_table_entry -> bool*) -let elf32_section_in_segment5 sec_hdr segment:bool= - (let sec_siz = ((Nat_big_num.of_string (Uint32.to_string sec_hdr.elf32_sh_size))) in - let seg_msz = ((Nat_big_num.of_string (Uint32.to_string segment.elf32_p_memsz))) in - let sec_off = ((Nat_big_num.of_string (Uint32.to_string sec_hdr.elf32_sh_offset))) in - let seg_off = ((Nat_big_num.of_string (Uint32.to_string segment.elf32_p_offset))) in - let seg_fsz = ((Nat_big_num.of_string (Uint32.to_string segment.elf32_p_filesz))) in - let sec_adr = ((Nat_big_num.of_string (Uint32.to_string sec_hdr.elf32_sh_addr))) in - let seg_vad = ((Nat_big_num.of_string (Uint32.to_string segment.elf32_p_vaddr))) in - (not (elf32_segment_of_type segment elf_pt_dynamic)) || (not (Nat_big_num.equal sec_siz(Nat_big_num.of_int 0)) || (Nat_big_num.equal - seg_msz(Nat_big_num.of_int 0) || - ((elf32_section_of_type sec_hdr sht_nobits || - ( Nat_big_num.greater sec_off seg_off && Nat_big_num.less (Nat_big_num.sub - sec_off seg_off) seg_fsz)) && - (not (elf32_section_flags0 sec_hdr shf_alloc) || - ( Nat_big_num.greater sec_adr seg_vad && Nat_big_num.less (Nat_big_num.sub - sec_adr seg_vad) seg_msz)))))) - -(*val elf64_section_in_segment5 : elf64_section_header_table_entry -> elf64_program_header_table_entry -> bool*) -let elf64_section_in_segment5 sec_hdr segment:bool= - (let sec_siz = ((Ml_bindings.nat_big_num_of_uint64 sec_hdr.elf64_sh_size)) in - let seg_msz = ((Ml_bindings.nat_big_num_of_uint64 segment.elf64_p_memsz)) in - let sec_off = ((Nat_big_num.of_string (Uint64.to_string sec_hdr.elf64_sh_offset))) in - let seg_off = ((Nat_big_num.of_string (Uint64.to_string segment.elf64_p_offset))) in - let seg_fsz = ((Ml_bindings.nat_big_num_of_uint64 segment.elf64_p_filesz)) in - let sec_adr = ((Ml_bindings.nat_big_num_of_uint64 sec_hdr.elf64_sh_addr)) in - let seg_vad = ((Ml_bindings.nat_big_num_of_uint64 segment.elf64_p_vaddr)) in - (not (elf64_segment_of_type segment elf_pt_dynamic)) || (not (Nat_big_num.equal sec_siz(Nat_big_num.of_int 0)) || (Nat_big_num.equal - seg_msz(Nat_big_num.of_int 0) || - ((elf64_section_of_type sec_hdr sht_nobits || - ( Nat_big_num.greater sec_off seg_off && Nat_big_num.less (Nat_big_num.sub - sec_off seg_off) seg_fsz)) && - (not (elf64_section_flags0 sec_hdr shf_alloc) || - ( Nat_big_num.greater sec_adr seg_vad && Nat_big_num.less (Nat_big_num.sub - sec_adr seg_vad) seg_msz)))))) - -(** The final section in segment tests, bringing all the above together. - *) - -(*val elf32_section_in_segment : elf32_header -> elf32_section_header_table_entry -> elf32_program_header_table_entry -> bool*) -let elf32_section_in_segment hdr sec_hdr segment:bool= - (elf32_section_in_segment1 sec_hdr segment && -(elf32_section_in_segment2 sec_hdr segment && -(elf32_section_in_segment3 hdr sec_hdr segment && -(elf32_section_in_segment4 hdr sec_hdr segment && - elf32_section_in_segment5 sec_hdr segment)))) - -(*val elf64_section_in_segment : elf64_header -> elf64_section_header_table_entry -> elf64_program_header_table_entry -> bool*) -let elf64_section_in_segment hdr sec_hdr segment:bool= - (elf64_section_in_segment1 sec_hdr segment && -(elf64_section_in_segment2 sec_hdr segment && -(elf64_section_in_segment3 hdr sec_hdr segment && -(elf64_section_in_segment4 hdr sec_hdr segment && - elf64_section_in_segment5 sec_hdr segment)))) diff --git a/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_symbol_versioning.ml b/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_symbol_versioning.ml deleted file mode 100644 index fe9382b0..00000000 --- a/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_symbol_versioning.ml +++ /dev/null @@ -1,294 +0,0 @@ -(*Generated by Lem from gnu_extensions/gnu_ext_symbol_versioning.lem.*) -(** The [gnu_ext_symbol_versioning] defines constants, types and functions - * relating to the GNU symbol versioning extensions (i.e. contents of - * GNU_VERSYM sections). - * - * TODO: work out what is going on with symbol versioning. The specification - * is completely opaque. - *) - -open Lem_basic_classes -open Lem_bool -open Lem_list -open Lem_maybe -open Lem_num -open Lem_string - -open Byte_sequence -open Endianness -open Error - -open Elf_dynamic -open Elf_file -open Elf_header -open Elf_section_header_table -open Elf_symbol_table -open Elf_types_native_uint - -open Missing_pervasives -open Show - -open Gnu_ext_dynamic -open Gnu_ext_section_header_table - -(** [gnu_ext_elf32_symbol_version_table] is an array (linked list, here) of - * [elf32_half] entries. - *) -type gnu_ext_elf32_symbol_version_table = Uint32.uint32 - list - -type gnu_ext_elf64_symbol_version_table = Uint32.uint32 - list - -(*val obtain_gnu_ext_elf32_symbol_version_table : elf32_file -> byte_sequence -> error gnu_ext_elf32_symbol_version_table*) -let obtain_gnu_ext_elf32_symbol_version_table f1 bs0:((Uint32.uint32)list)error= - (let sht = (f1.elf32_file_section_header_table) in - let endian = (get_elf32_header_endianness f1.elf32_file_header) in - let vers = (List.filter (fun ent -> - ent.elf32_sh_type = Uint32.of_string (Nat_big_num.to_string sht_gnu_versym) - ) sht) - in - (match vers with - | [] -> return [] - | [ver] -> - let off = (Nat_big_num.of_string (Uint32.to_string ver.elf32_sh_offset)) in - let siz = (Nat_big_num.of_string (Uint32.to_string ver.elf32_sh_size)) in - let lnk = (Nat_big_num.of_string (Uint32.to_string ver.elf32_sh_link)) in - get_elf32_symbol_table_by_index f1 lnk >>= (fun symtab -> - let dlen = (Nat_big_num.of_int (List.length symtab)) in - Byte_sequence.offset_and_cut off siz bs0 >>= (fun ver -> - Error.repeatM' dlen bs0 (read_elf32_half endian) >>= (fun (ver, _) -> - return ver))) - | _ -> fail "obtain_gnu_ext_elf32_symbol_version_table: multiple sections of type .gnu_versym present in file" - )) - -(*val obtain_gnu_ext_elf64_symbol_version_table : endianness -> elf64_section_header_table -> elf64_symbol_table -> byte_sequence -> error gnu_ext_elf64_symbol_version_table*) -let obtain_gnu_ext_elf64_symbol_version_table endian sht dynsym bs0:((Uint32.uint32)list)error= - (let dlen = (Nat_big_num.of_int (List.length dynsym)) in - if Nat_big_num.equal dlen(Nat_big_num.of_int 0) then - return [] - else - let vers = (List.filter (fun ent -> - ent.elf64_sh_type = Uint32.of_string (Nat_big_num.to_string sht_gnu_versym) - ) sht) - in - (match vers with - | [] -> return [] - | [ver] -> - let off = (Nat_big_num.of_string (Uint64.to_string ver.elf64_sh_offset)) in - let siz = (Ml_bindings.nat_big_num_of_uint64 ver.elf64_sh_size) in - Byte_sequence.offset_and_cut off siz bs0 >>= (fun ver -> - Error.repeatM' dlen bs0 (read_elf64_half endian) >>= (fun (ver, _) -> - return ver)) - | _ -> fail "obtain_gnu_ext_elf64_symbol_version_table: multiple sections of type .gnu_versym present in file" - )) - -type gnu_ext_elf32_verdef = - { gnu_ext_elf32_vd_version : Uint32.uint32 - ; gnu_ext_elf32_vd_flags : Uint32.uint32 - ; gnu_ext_elf32_vd_ndx : Uint32.uint32 - ; gnu_ext_elf32_vd_cnt : Uint32.uint32 - ; gnu_ext_elf32_vd_hash : Uint32.uint32 - ; gnu_ext_elf32_vd_aux : Uint32.uint32 - ; gnu_ext_elf32_vd_next : Uint32.uint32 - } - -type gnu_ext_elf64_verdef = - { gnu_ext_elf64_vd_version : Uint32.uint32 - ; gnu_ext_elf64_vd_flags : Uint32.uint32 - ; gnu_ext_elf64_vd_ndx : Uint32.uint32 - ; gnu_ext_elf64_vd_cnt : Uint32.uint32 - ; gnu_ext_elf64_vd_hash : Uint32.uint32 - ; gnu_ext_elf64_vd_aux : Uint32.uint32 - ; gnu_ext_elf64_vd_next : Uint32.uint32 - } - -(*val string_of_gnu_ext_elf32_verdef : gnu_ext_elf32_verdef -> string*) -let string_of_gnu_ext_elf32_verdef verdef:string= - (unlines [ -("Version: " ^ Uint32.to_string verdef.gnu_ext_elf32_vd_version) - ; ("Flags: " ^ Uint32.to_string verdef.gnu_ext_elf32_vd_flags) - ; ("Index: " ^ Uint32.to_string verdef.gnu_ext_elf32_vd_ndx) - ; ("Count: " ^ Uint32.to_string verdef.gnu_ext_elf32_vd_cnt) - ; ("Hash: " ^ Uint32.to_string verdef.gnu_ext_elf32_vd_hash) - ]) - -(*val string_of_gnu_ext_elf64_verdef : gnu_ext_elf64_verdef -> string*) -let string_of_gnu_ext_elf64_verdef verdef:string= - (unlines [ -("Version: " ^ Uint32.to_string verdef.gnu_ext_elf64_vd_version) - ; ("Flags: " ^ Uint32.to_string verdef.gnu_ext_elf64_vd_flags) - ; ("Index: " ^ Uint32.to_string verdef.gnu_ext_elf64_vd_ndx) - ; ("Count: " ^ Uint32.to_string verdef.gnu_ext_elf64_vd_cnt) - ; ("Hash: " ^ Uint32.to_string verdef.gnu_ext_elf64_vd_hash) - ]) - -(*val read_gnu_ext_elf32_verdef : endianness -> byte_sequence -> error (gnu_ext_elf32_verdef * byte_sequence)*) -let read_gnu_ext_elf32_verdef endian bs0:(gnu_ext_elf32_verdef*byte_sequence)error= - (read_elf32_half endian bs0 >>= (fun (ver, bs0) -> - read_elf32_half endian bs0 >>= (fun (flg, bs0) -> - read_elf32_half endian bs0 >>= (fun (ndx, bs0) -> - read_elf32_half endian bs0 >>= (fun (cnt, bs0) -> - read_elf32_word endian bs0 >>= (fun (hsh, bs0) -> - read_elf32_word endian bs0 >>= (fun (aux, bs0) -> - read_elf32_word endian bs0 >>= (fun (nxt, bs0) -> - return ({ gnu_ext_elf32_vd_version = ver; gnu_ext_elf32_vd_flags = flg; - gnu_ext_elf32_vd_ndx = ndx; gnu_ext_elf32_vd_cnt = cnt; - gnu_ext_elf32_vd_hash = hsh; gnu_ext_elf32_vd_aux = aux; - gnu_ext_elf32_vd_next = nxt }, bs0))))))))) - -(*val read_gnu_ext_elf64_verdef : endianness -> byte_sequence -> error (gnu_ext_elf64_verdef * byte_sequence)*) -let read_gnu_ext_elf64_verdef endian bs0:(gnu_ext_elf64_verdef*byte_sequence)error= - (read_elf64_half endian bs0 >>= (fun (ver, bs0) -> - read_elf64_half endian bs0 >>= (fun (flg, bs0) -> - read_elf64_half endian bs0 >>= (fun (ndx, bs0) -> - read_elf64_half endian bs0 >>= (fun (cnt, bs0) -> - read_elf64_word endian bs0 >>= (fun (hsh, bs0) -> - read_elf64_word endian bs0 >>= (fun (aux, bs0) -> - read_elf64_word endian bs0 >>= (fun (nxt, bs0) -> - return ({ gnu_ext_elf64_vd_version = ver; gnu_ext_elf64_vd_flags = flg; - gnu_ext_elf64_vd_ndx = ndx; gnu_ext_elf64_vd_cnt = cnt; - gnu_ext_elf64_vd_hash = hsh; gnu_ext_elf64_vd_aux = aux; - gnu_ext_elf64_vd_next = nxt }, bs0))))))))) - -(*val gnu_ext_elf32_verdef_size : natural*) -let gnu_ext_elf32_verdef_size:Nat_big_num.num= (Nat_big_num.of_int 160) - -(*val gnu_ext_elf64_verdef_size : natural*) -let gnu_ext_elf64_verdef_size:Nat_big_num.num= (Nat_big_num.of_int 256) - -type gnu_ext_elf32_veraux = - { gnu_ext_elf32_vda_name : Uint32.uint32 - ; gnu_ext_elf32_vda_next : Uint32.uint32 - } - -type gnu_ext_elf64_veraux = - { gnu_ext_elf64_vda_name : Uint32.uint32 - ; gnu_ext_elf64_vda_next : Uint32.uint32 - } - -(*val gnu_ext_elf32_veraux_size : natural*) -let gnu_ext_elf32_veraux_size:Nat_big_num.num= (Nat_big_num.of_int 64) - -(*val gnu_ext_elf64_veraux_size : natural*) -let gnu_ext_elf64_veraux_size:Nat_big_num.num= (Nat_big_num.of_int 128) - -(*val read_gnu_ext_elf32_veraux : endianness -> byte_sequence -> error (gnu_ext_elf32_veraux * byte_sequence)*) -let read_gnu_ext_elf32_veraux endian bs0:(gnu_ext_elf32_veraux*byte_sequence)error= - (read_elf32_word endian bs0 >>= (fun (nme, bs0) -> - read_elf32_word endian bs0 >>= (fun (nxt, bs0) -> - return ({ gnu_ext_elf32_vda_name = nme; gnu_ext_elf32_vda_next = nxt }, bs0)))) - -(*val read_gnu_ext_elf64_veraux : endianness -> byte_sequence -> error (gnu_ext_elf64_veraux * byte_sequence)*) -let read_gnu_ext_elf64_veraux endian bs0:(gnu_ext_elf64_veraux*byte_sequence)error= - (read_elf64_word endian bs0 >>= (fun (nme, bs0) -> - read_elf64_word endian bs0 >>= (fun (nxt, bs0) -> - return ({ gnu_ext_elf64_vda_name = nme; gnu_ext_elf64_vda_next = nxt }, bs0)))) - -type gnu_ext_elf32_verneed = - { gnu_ext_elf32_vn_version : Uint32.uint32 - ; gnu_ext_elf32_vn_cnt : Uint32.uint32 - ; gnu_ext_elf32_vn_file : Uint32.uint32 - ; gnu_ext_elf32_vn_aux : Uint32.uint32 - ; gnu_ext_elf32_vn_next : Uint32.uint32 - } - -type gnu_ext_elf64_verneed = - { gnu_ext_elf64_vn_version : Uint32.uint32 - ; gnu_ext_elf64_vn_cnt : Uint32.uint32 - ; gnu_ext_elf64_vn_file : Uint32.uint32 - ; gnu_ext_elf64_vn_aux : Uint32.uint32 - ; gnu_ext_elf64_vn_next : Uint32.uint32 - } - -(*val gnu_ext_elf32_verneed_size : natural*) -let gnu_ext_elf32_verneed_size:Nat_big_num.num= (Nat_big_num.of_int 128) - -(*val gnu_ext_elf64_verneed_size : natural*) -let gnu_ext_elf64_verneed_size:Nat_big_num.num= (Nat_big_num.of_int 224) - -(*val read_gnu_ext_elf32_verneed : endianness -> byte_sequence -> error (gnu_ext_elf32_verneed * byte_sequence)*) -let read_gnu_ext_elf32_verneed endian bs0:(gnu_ext_elf32_verneed*byte_sequence)error= - (read_elf32_half endian bs0 >>= (fun (ver, bs0) -> - read_elf32_half endian bs0 >>= (fun (cnt, bs0) -> - read_elf32_word endian bs0 >>= (fun (fle, bs0) -> - read_elf32_word endian bs0 >>= (fun (aux, bs0) -> - read_elf32_word endian bs0 >>= (fun (nxt, bs0) -> - return ({ gnu_ext_elf32_vn_version = ver; gnu_ext_elf32_vn_cnt = cnt; - gnu_ext_elf32_vn_file = fle; gnu_ext_elf32_vn_aux = aux; - gnu_ext_elf32_vn_next = nxt }, bs0))))))) - -(*val read_gnu_ext_elf64_verneed : endianness -> byte_sequence -> error (gnu_ext_elf64_verneed * byte_sequence)*) -let read_gnu_ext_elf64_verneed endian bs0:(gnu_ext_elf64_verneed*byte_sequence)error= - (read_elf64_half endian bs0 >>= (fun (ver, bs0) -> - read_elf64_half endian bs0 >>= (fun (cnt, bs0) -> - read_elf64_word endian bs0 >>= (fun (fle, bs0) -> - read_elf64_word endian bs0 >>= (fun (aux, bs0) -> - read_elf64_word endian bs0 >>= (fun (nxt, bs0) -> - return ({ gnu_ext_elf64_vn_version = ver; gnu_ext_elf64_vn_cnt = cnt; - gnu_ext_elf64_vn_file = fle; gnu_ext_elf64_vn_aux = aux; - gnu_ext_elf64_vn_next = nxt }, bs0))))))) - -type gnu_ext_elf32_vernaux = - { gnu_ext_elf32_vna_hash : Uint32.uint32 - ; gnu_ext_elf32_vna_flags : Uint32.uint32 - ; gnu_ext_elf32_vna_other : Uint32.uint32 - ; gnu_ext_elf32_vna_name : Uint32.uint32 - ; gnu_ext_elf32_vna_next : Uint32.uint32 - } - -type gnu_ext_elf64_vernaux = - { gnu_ext_elf64_vna_hash : Uint32.uint32 - ; gnu_ext_elf64_vna_flags : Uint32.uint32 - ; gnu_ext_elf64_vna_other : Uint32.uint32 - ; gnu_ext_elf64_vna_name : Uint32.uint32 - ; gnu_ext_elf64_vna_next : Uint32.uint32 - } - -(*val string_of_gnu_ext_elf32_vernaux : gnu_ext_elf32_vernaux -> string*) -let string_of_gnu_ext_elf32_vernaux vernaux:string= - (unlines [ -("Hash: " ^ Uint32.to_string vernaux.gnu_ext_elf32_vna_hash) - ; ("Flags: " ^ Uint32.to_string vernaux.gnu_ext_elf32_vna_flags) - ; ("Other: " ^ Uint32.to_string vernaux.gnu_ext_elf32_vna_other) - ; ("Name: " ^ Uint32.to_string vernaux.gnu_ext_elf32_vna_name) - ; ("Next: " ^ Uint32.to_string vernaux.gnu_ext_elf32_vna_next) - ]) - -(*val string_of_gnu_ext_elf64_vernaux : gnu_ext_elf64_vernaux -> string*) -let string_of_gnu_ext_elf64_vernaux vernaux:string= - (unlines [ -("Hash: " ^ Uint32.to_string vernaux.gnu_ext_elf64_vna_hash) - ; ("Flags: " ^ Uint32.to_string vernaux.gnu_ext_elf64_vna_flags) - ; ("Other: " ^ Uint32.to_string vernaux.gnu_ext_elf64_vna_other) - ; ("Name: " ^ Uint32.to_string vernaux.gnu_ext_elf64_vna_name) - ; ("Next: " ^ Uint32.to_string vernaux.gnu_ext_elf64_vna_next) - ]) - -(*val gnu_ext_elf32_vernaux_size : natural*) -let gnu_ext_elf32_vernaux_size:Nat_big_num.num= (Nat_big_num.of_int 16) - -(*val gnu_ext_elf64_vernaux_size : natural*) -let gnu_ext_elf64_vernaux_size:Nat_big_num.num= (Nat_big_num.of_int 224) - -(*val read_gnu_ext_elf32_vernaux : endianness -> byte_sequence -> error (gnu_ext_elf32_vernaux * byte_sequence)*) -let read_gnu_ext_elf32_vernaux endian bs0:(gnu_ext_elf32_vernaux*byte_sequence)error= - (read_elf32_word endian bs0 >>= (fun (hsh, bs0) -> - read_elf32_half endian bs0 >>= (fun (flg, bs0) -> - read_elf32_half endian bs0 >>= (fun (otr, bs0) -> - read_elf32_word endian bs0 >>= (fun (nme, bs0) -> - read_elf32_word endian bs0 >>= (fun (nxt, bs0) -> - return ({ gnu_ext_elf32_vna_hash = hsh; gnu_ext_elf32_vna_flags = flg; - gnu_ext_elf32_vna_other = otr; gnu_ext_elf32_vna_name = nme; - gnu_ext_elf32_vna_next = nxt }, bs0))))))) - -(*val read_gnu_ext_elf64_vernaux : endianness -> byte_sequence -> error (gnu_ext_elf64_vernaux * byte_sequence)*) -let read_gnu_ext_elf64_vernaux endian bs0:(gnu_ext_elf64_vernaux*byte_sequence)error= - (read_elf64_word endian bs0 >>= (fun (hsh, bs0) -> - read_elf64_half endian bs0 >>= (fun (flg, bs0) -> - read_elf64_half endian bs0 >>= (fun (otr, bs0) -> - read_elf64_word endian bs0 >>= (fun (nme, bs0) -> - read_elf64_word endian bs0 >>= (fun (nxt, bs0) -> - return ({ gnu_ext_elf64_vna_hash = hsh; gnu_ext_elf64_vna_flags = flg; - gnu_ext_elf64_vna_other = otr; gnu_ext_elf64_vna_name = nme; - gnu_ext_elf64_vna_next = nxt }, bs0))))))) diff --git a/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_types_native_uint.ml b/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_types_native_uint.ml deleted file mode 100644 index ec4be185..00000000 --- a/lib/ocaml_rts/linksem/gnu_extensions/gnu_ext_types_native_uint.ml +++ /dev/null @@ -1,12 +0,0 @@ -(*Generated by Lem from gnu_extensions/gnu_ext_types_native_uint.lem.*) -(** [gnu_ext_types_native_uint] provides extended types defined by the GNU - * extensions over and above the based ELF types. - *) - -open Missing_pervasives -open Elf_types_native_uint - -(** LSB section 9.2.1.1: in addition to SCO ELF spec types GNU defines an - * additional 1-byte integral type. - *) -type gnu_ext_byte = char diff --git a/lib/ocaml_rts/linksem/hex_printing.ml b/lib/ocaml_rts/linksem/hex_printing.ml deleted file mode 100644 index fe2c42ca..00000000 --- a/lib/ocaml_rts/linksem/hex_printing.ml +++ /dev/null @@ -1,68 +0,0 @@ -(*Generated by Lem from hex_printing.lem.*) -(** [hex_printing] is a utility module for converting natural numbers and integers - * into hex strings of various widths. Split into a new module as both the - * validation code and the main program need this functionality. - *) - -open Lem_basic_classes -open Lem_list -open Lem_num -open Lem_string - -open Missing_pervasives -open Elf_types_native_uint - -(*val hex_string_of_big_int_no_padding : natural -> string*) -(* declare ocaml target_rep function hex_string_of_big_int_no_padding = `Ml_bindings.hex_string_of_big_int_no_padding` *) -let hex_string_of_big_int_no_padding:Nat_big_num.num ->string= hex_string_of_natural -(*val hex_string_of_big_int_no_padding' : integer -> string*) -(*val hex_string_of_big_int_pad2 : natural -> string*) -(*val hex_string_of_big_int_pad4 : natural -> string*) -(*val hex_string_of_big_int_pad5 : natural -> string*) -(*val hex_string_of_big_int_pad6 : natural -> string*) -(*val hex_string_of_big_int_pad7 : natural -> string*) -(*val hex_string_of_big_int_pad8 : natural -> string*) -(*val hex_string_of_big_int_pad16 : natural -> string*) - -(*val hex_string_of_nat_pad2 : nat -> string*) - -(*val unsafe_hex_string_of_natural : nat -> natural -> string*) -let unsafe_hex_string_of_natural pad m:string= - (if pad = 2 then - Ml_bindings.hex_string_of_big_int_pad2 m - else if pad = 5 then - Ml_bindings.hex_string_of_big_int_pad5 m - else if pad = 4 then - Ml_bindings.hex_string_of_big_int_pad4 m - else if pad = 6 then - Ml_bindings.hex_string_of_big_int_pad6 m - else if pad = 7 then - Ml_bindings.hex_string_of_big_int_pad7 m - else if pad = 8 then - Ml_bindings.hex_string_of_big_int_pad8 m - else if pad = 16 then - Ml_bindings.hex_string_of_big_int_pad16 m - else - hex_string_of_big_int_no_padding m) - -(*val unsafe_hex_string_of_uc_list : list unsigned_char -> string*) -let rec unsafe_hex_string_of_uc_list xs:string= - ((match xs with - | [] -> "" - | x::y::xs -> - let sx = (unsafe_hex_string_of_natural( 2) (Nat_big_num.of_string (Uint32.to_string x))) in - let sy = (unsafe_hex_string_of_natural( 2) (Nat_big_num.of_string (Uint32.to_string y))) in - let sx = -(if String.length sx = 2 then - sx - else - "0" ^ sx) - in - let sy = -(if String.length sy = 2 then - sy - else - "0" ^ sy) - in - sx ^ (" " ^ (sy ^ (" " ^ unsafe_hex_string_of_uc_list xs))) - )) diff --git a/lib/ocaml_rts/linksem/input_list.ml b/lib/ocaml_rts/linksem/input_list.ml deleted file mode 100644 index fe698586..00000000 --- a/lib/ocaml_rts/linksem/input_list.ml +++ /dev/null @@ -1,317 +0,0 @@ -(*Generated by Lem from input_list.lem.*) -open Lem_basic_classes -open Lem_function -open Lem_string -open Lem_string_extra -open Lem_tuple -open Lem_bool -open Lem_list -open Lem_list_extra -open Lem_sorting -open Lem_num -open Lem_maybe -open Lem_assert_extra - -open Byte_sequence -open Default_printing -open Error -open Missing_pervasives -open Show - -open Archive -open Command_line -open Elf_types_native_uint -open Elf_file -open Elf_header - -(* Here we elaborate away various properties of the command line: - * archives, groups, library paths, -l, --as-needed, --whole-archive, - * and which inputs can be used to resolve symbols undefined in which other inputs. - * - * What we get out is a list of input files and the options applying to them. - * Input files are either relocatable files, shared objects or linker scripts. - *) - -type input_blob = Reloc of byte_sequence - | Shared of byte_sequence - | Script of byte_sequence - | ControlScript - -(* We remember where the input item came from on the command line, - * using "coordinates" identifying the index in the higher-up list - * followed by the index within that item. *) -type origin_coord = InArchive of (Nat_big_num.num * Nat_big_num.num * string * Nat_big_num.num) (* archive-id, pos-within-archive, archive-name, archive-member-count *) - | InGroup of (Nat_big_num.num * Nat_big_num.num) (* group-id, pos-within-group *) - | InCommandLine of Nat_big_num.num - | Builtin - -(*val string_of_origin_coord : origin_coord -> string*) -let string_of_origin_coord c:string= ((match c with - InArchive(aid, aidx, aname, _) -> "at position " ^ ((Nat_big_num.to_string aidx) ^ (" within archive " ^ (aname ^ (" (at position " ^ ((Nat_big_num.to_string aid) ^ ")"))))) - | InGroup(gid1, gidx) -> "at position " ^ ((Nat_big_num.to_string gidx) ^ (" within group at position " ^ (Nat_big_num.to_string gid1))) - | InCommandLine(cid) -> "(command line)" - | Builtin -> "(built-in)" -)) - -let instance_Show_Show_Input_list_origin_coord_dict:(origin_coord)show_class= ({ - - show_method = string_of_origin_coord}) - -type input_origin = input_unit * origin_coord list - -type input_item = string * input_blob * input_origin - -(*val string_of_input_blob : input_blob -> string*) -let string_of_input_blob item:string= ((match item with - Reloc(seq) -> "relocatable file (" ^ ((Nat_big_num.to_string (Byte_sequence.length0 seq)) ^ " bytes)") - | Shared(seq) -> "shared object (" ^ ((Nat_big_num.to_string (Byte_sequence.length0 seq)) ^ " bytes)") - | Script(seq) -> "script (" ^ ((Nat_big_num.to_string (Byte_sequence.length0 seq)) ^ " bytes)") - | ControlScript -> "the linker control script" -)) - -let instance_Show_Show_Input_list_input_blob_dict:(input_blob)show_class= ({ - - show_method = string_of_input_blob}) - -(*val short_string_of_input_item : input_item -> string*) -let short_string_of_input_item item:string= - (let (fname1, blob, (u, origin)) = item - in - (match origin with - InArchive(aid, aidx, aname, _) :: _ -> aname ^ ("(" ^ (fname1 ^ ")")) - | _ -> fname1 - )) - -(* About symbol resolution and "suppliers". - * - * Groups change this. - * - * When we expand a .a file into a list of .o files, what is the supplier - * relation among them? I *THINK* that within the archive, each can supply any other, - * but outside the archive, each can only supply leftmore. - *) - -type can_supply_function = input_item list -> int -> bool list - -type input_options = { item_fmt : string - ; item_check_sections : bool - ; item_copy_dt_needed : bool - ; item_force_output : bool (* true for .o, false for .a unless --whole-archive, - true for .so with --no-as-needed, - false for .so with --as-needed *) - } - -(*val null_input_options : input_options*) -let null_input_options:input_options= - ({ item_fmt = "" - ; item_check_sections = false - ; item_copy_dt_needed = false - ; item_force_output = true - }) - -(*val string_of_input_options : input_options -> string*) -let string_of_input_options opts:string= "(some options)" - -let instance_Show_Show_Input_list_input_options_dict:(input_options)show_class= ({ - - show_method = string_of_input_options}) - -type input_list = (input_item * input_options) list - -(*val toplevel_dot_o_can_supply : list input_item -> nat -> list bool*) -let toplevel_dot_o_can_supply inputs pos:(bool)list= - (Lem_list.genlist (fun _ -> true) (List.length inputs)) - -(*val toplevel_shared_can_supply : list input_item -> nat -> list bool*) -let toplevel_shared_can_supply inputs pos:(bool)list= - (Lem_list.genlist (fun ndx -> ndx <= pos) (List.length inputs)) - -(*val toplevel_archive_can_supply : list input_item -> nat -> list bool*) -let toplevel_archive_can_supply inputs pos:(bool)list= - (Lem_list.genlist (fun ndx -> ndx <= pos) (List.length inputs)) - -(*val lib_filename_from_spec : string -> string -> string*) -let lib_filename_from_spec spec ext:string= - ((match (Xstring.explode spec) with - ':' :: more -> (Xstring.implode more) - | _ -> "lib" ^ (spec ^ ("." ^ ext)) - )) - -(*val find_library_in : string -> list string -> list string -> maybe string*) -let find_library_in spec extensions pathlist:(string)option= -( - (* Recall the GNU libc's "libc.so is a linker script" hack. - * This tells us that we should only look at file extensions, not contents. *)let file_exists name1= - ((match Byte_sequence.acquire name1 with (* FIXME: use cheaper call *) - Success _ -> true - | Fail _ -> false - )) - in - let expand_candidate_libname = (fun path -> fun ext -> (path ^ ("/" ^ (lib_filename_from_spec spec ext)))) - in - let get_expansions_existing = (fun path -> - let x2 = ([]) in List.fold_right (fun cand x2 -> if file_exists cand then cand :: x2 else x2) - (Lem_list.map (expand_candidate_libname path) extensions) x2) - in - let found_by_path = (Lem_list.map (fun path -> (path, get_expansions_existing path)) pathlist) - in - (* Do we take the first path for which some extension is found? - * Or do we keep going if we prefer shared libraries, say? - * I think it's the former. *) - (match Lem_list.list_find_opt (fun (path, exps) -> (List.length exps) > 0) found_by_path with - Some (path, exps) -> Some(List.hd exps) - | None -> None - )) - -(*val find_one_library_filename : input_file_options -> string -> string*) -let find_one_library_filename options str:string= - (let extensions = (if options.input_link_sharedlibs then ["so"; "a"] else ["a"]) - in - let found = (find_library_in str extensions options.input_libpath) - in (match found with - None -> failwith ("couldn't find library matching '" ^ (str ^ "'")) - | Some result -> result - )) - -(*val is_elf64_with_type : elf64_half -> byte_sequence -> bool*) -let is_elf64_with_type typ seq:bool= -( - (*let _ = Missing_pervasives.errs ("elf64? " ^ - (match seq with Sequence(bs) -> show (List.take 16 bs) end)) - in*)(match Elf_file.read_elf64_file seq with - Success(e) -> (* let _ = Missing_pervasives.errln ": yes" in *) (e.elf64_file_header.elf64_type = typ) - | Fail _ -> (* let _ = Missing_pervasives.errln ": no" in *) false - )) - -(*val is_archive : byte_sequence -> bool*) -let is_archive seq:bool= - ((match read_archive_global_header seq with - Success _ -> true - | Fail _ -> false - )) - -(*val open_file_and_expand : string -> input_unit -> natural -> list input_item*) -let open_file_and_expand toplevel_fname u fpos:(string*input_blob*(input_unit*(origin_coord)list))list= - ((match Byte_sequence.acquire toplevel_fname with - Fail _ -> failwith ("could not open file " ^ toplevel_fname) - | Success seq -> - if is_elf64_with_type (Uint32.of_string (Nat_big_num.to_string elf_ft_rel)) seq - then [(toplevel_fname, Reloc(seq), (u, []))] - else if is_elf64_with_type (Uint32.of_string (Nat_big_num.to_string elf_ft_dyn)) seq - then [(toplevel_fname, Shared(seq), (u, []))] - else if is_archive seq - then - (match read_archive seq with - Fail _ -> failwith ("could not read archive " ^ toplevel_fname) - | Success (pairs : (string * byte_sequence) list) -> - (*let _ = Missing_pervasives.errln (toplevel_fname ^ " is an archive with " ^ (show (List.length pairs)) ^ " members") - in*) - let not_elf = (List.filter (fun (inner_fname, seq) -> not (is_elf64_with_type (Uint32.of_string (Nat_big_num.to_string elf_ft_rel)) seq)) pairs) - in - if List.length not_elf = 0 - then mapMaybei - (fun (i : Nat_big_num.num) -> (fun ((inner_fname : string), seq) -> - let (trimmed_inner_fname : string) = ((match ((Ml_bindings.string_index_of '/' inner_fname) : Nat_big_num.num option) with - None -> inner_fname - | Some (ind : Nat_big_num.num) -> (match Ml_bindings.string_prefix ind inner_fname with - Some s -> s - | None -> failwith "impossible: string has character index >= its length" - ) - )) - in - Some (trimmed_inner_fname, Reloc(seq), (u, [InArchive(fpos, i, toplevel_fname, length pairs)])) - )) pairs - else let (names, seqs) = (List.split not_elf) in - failwith ("archive with unsupported contents" (*(" ^ (show names) ^ ")*)) - ) - else [(toplevel_fname, Script(seq), (u, []))] - )) - -(*val make_input_items_and_options : list input_item -> Command_line.input_file_options -> list origin_coord -> list (input_item * input_options)*) -let make_input_items_and_options file_list cmdopts coords_to_append:((string*input_blob*(input_unit*(origin_coord)list))*input_options)list= - ((match file_list with - [] -> failwith "impossible: empty list of files" - | [(fname1, Reloc(seq), (u, coords))] -> - [((fname1, Reloc(seq), (u, List.rev_append (List.rev coords) coords_to_append)), - { item_fmt = (cmdopts.input_fmt) - ; item_check_sections = (cmdopts.input_check_sections) - ; item_copy_dt_needed = (cmdopts.input_copy_dt_needed) - ; item_force_output = true - })] - | [(fname1, Shared(seq), (u, coords))] -> - [((fname1, Shared(seq), (u, List.rev_append (List.rev coords) coords_to_append)), - { item_fmt = (cmdopts.input_fmt) - ; item_check_sections = (cmdopts.input_check_sections) - ; item_copy_dt_needed = (cmdopts.input_copy_dt_needed) - ; item_force_output = (if cmdopts.input_as_needed then false else true) - })] - | [(fname1, Script(seq), (u, coords))] -> - [((fname1, Script(seq), (u, List.rev_append (List.rev coords) coords_to_append)), - { item_fmt = (cmdopts.input_fmt) - ; item_check_sections = (cmdopts.input_check_sections) - ; item_copy_dt_needed = (cmdopts.input_copy_dt_needed) - ; item_force_output = true - })] - | _ -> (* guaranteed to be all relocs, from one archive *) - let (items_and_options : (input_item * input_options) list) = - (mapMaybei (fun i -> (fun (fname1, reloc1, (u, coords)) -> - let (item : input_item) = (fname1, reloc1, (u, List.rev_append (List.rev coords) coords_to_append)) - in - let (options : input_options) = - ({ item_fmt = (cmdopts.input_fmt) - ; item_check_sections = (cmdopts.input_check_sections) - ; item_copy_dt_needed = (cmdopts.input_copy_dt_needed) - ; item_force_output = (if cmdopts.input_whole_archive then true else false) - }) - in Some (item, options) - )) file_list) - in items_and_options - | _ -> failwith "impossible expanded input item" - )) - -(*val elaborate_input_helper : natural -> list Command_line.input_unit -> input_list -> input_list*) -let rec elaborate_input_helper input_pos inputs acc:(input_item*input_options)list= - ((match inputs with - [] -> acc - | input :: more_inputs -> - (match input with - File(spec, options) - -> (match spec with - Filename(str) - -> elaborate_input_helper ( Nat_big_num.add input_pos(Nat_big_num.of_int 1)) more_inputs - ( List.rev_append (List.rev acc) (make_input_items_and_options - (open_file_and_expand str input input_pos) options [InCommandLine(input_pos)])) - | Libname(str) - -> elaborate_input_helper ( Nat_big_num.add input_pos(Nat_big_num.of_int 1)) more_inputs - ( List.rev_append (List.rev acc) (make_input_items_and_options - (open_file_and_expand (find_one_library_filename options str) input input_pos) - options [InCommandLine(input_pos)])) - ) - | Group(specs_and_options) -> - (* Every member of a group is either a filename or a libname. - * First expand the libnames, leaving the Group intact. *) - let group_with_lib_files - = (Lem_list.map (fun (spec, options) -> (match spec with - Filename(str) -> (str, options) - | Libname(str) -> (find_one_library_filename options str, options) - )) specs_and_options) - in - (* Now expand archives into file lists. *) - let group_with_file_lists - = (mapMaybei (fun i -> (fun (str, options) -> - Some ((open_file_and_expand str input input_pos), options) - )) group_with_lib_files) - in - (* Now expand them into files and fix up the options appropriately *) - let to_add - = (mapMaybei (fun index_in_group -> (fun (file_list, options) -> ( - Some( - make_input_items_and_options file_list options [InGroup(input_pos, index_in_group); InCommandLine(input_pos)] - )))) group_with_file_lists) - in - elaborate_input_helper ( Nat_big_num.add input_pos(Nat_big_num.of_int 1)) more_inputs ( List.rev_append (List.rev acc) (List.concat to_add)) - ) - )) - -(*val elaborate_input : list Command_line.input_unit -> input_list*) -let rec elaborate_input inputs:(input_item*input_options)list= (elaborate_input_helper(Nat_big_num.of_int 0) inputs []) diff --git a/lib/ocaml_rts/linksem/link.ml b/lib/ocaml_rts/linksem/link.ml deleted file mode 100644 index 1265de61..00000000 --- a/lib/ocaml_rts/linksem/link.ml +++ /dev/null @@ -1,1005 +0,0 @@ -(*Generated by Lem from link.lem.*) -open Lem_basic_classes -open Lem_function -open Lem_string -open Lem_tuple -open Lem_bool -open Lem_list -open Lem_sorting -open Lem_map -open Lem_set -(*import Set_extra*) -open Lem_num -open Lem_maybe -open Lem_assert_extra -(*import Command_line*) -(*import Input_list*) - -open Byte_sequence -open Default_printing -open Error -open Missing_pervasives -open Show -open Endianness - -open Elf_header -open Elf_interpreted_section -open Elf_interpreted_segment -open Elf_section_header_table -open Elf_program_header_table -open Elf_symbol_table -open Elf_types_native_uint -open Elf_relocation - -open Abis -open Abi_amd64_relocation (* HACK -- remove me *) - -open Input_list -open Linkable_list -(*import Command_line*) - -open Memory_image -open Memory_image_orderings -open Elf_memory_image -open Elf_memory_image_of_elf64_file -open Linker_script - -let all_common_symbols img2:(symbol_definition)list= (List.filter (fun def -> Nat_big_num.equal - (Nat_big_num.of_string (Uint32.to_string def.def_syment.elf64_st_shndx)) shn_common -) (elf_memory_image_defined_symbols img2)) - -(* Q. On what does the decision about a reloc depend? definitely on - * - * -- command-line options applying to the referenc*ed* object; - * (CHECK: I'm inferring that -Bsymbolic, like -Bstatic, applies to the - * *referenced* object, not the referring -- need experimental conf.) - * ACTUALLY, it seems to be global: if a definition goes in the library, - * bind to it; doesn't matter where it comes from. So - * - * -- command-line options applying to the output object / whole link (-Bsymbolic); - * - * -- command-line options applying to the referencing object? - * - * What decision can we make? - * Given a reloc, it might be - * - not bound (weak symbols) -- THIS MEANS it *is* bound but to the value 0! - * - bound to a definition - * - * ... perhaps our distinction is between "firm binding or provisional binding"? - * "final binding or overridable binding"? - * - * Can we also hit cases where the binding is final but can't be relocated til load time? - * YES, e.g. any final R_*_64_64 reference in a shared library's data segment. - * WHAT do we do in these cases? Apply what we can and generate a R_*_RELATIVE? - * Yes, that's where R_*_RELATIVE come from, since they don't appear in .o inputs. - *) - -(*val def_is_in_reloc : linkable_item -> bool*) -let def_is_in_reloc def_item:bool= ((match def_item with - (RelocELF(_), _, _) -> true - | (ScriptAST(_), _, _) -> true - | _ -> false -)) - -let retrieve_binding_for_ref dict_Basic_classes_Eq_b r r_linkable_idx item bindings_by_name:('b*symbol_reference*'d)*'c= - (let maybe_found_bs = (Pmap.lookup r.ref.ref_symname bindings_by_name) - in - (match maybe_found_bs with - None -> failwith "impossible: list of bindings does not include symbol reference (map empty)" - (* FIXME: could this actually be an "undefined symbol" link error perhaps? *) - | Some bis_and_bs -> (match List.filter (fun (b_idx, ((b_ref_idx, b_ref, b_ref_item), b_maybe_def)) -> - if dict_Basic_classes_Eq_b.isEqual_method b_ref_idx r_linkable_idx && (b_ref = r.ref) then - (*let _ = Missing_pervasives.errln ("saw ref from linkable idx " ^ (show r_linkable_idx) - ^ ", ref sym scn " ^ (show r.ref.ref_sym_scn) ^ ", ref sym idx "^ (show r.ref.ref_sym_idx) - ^ ", item " ^ (show item) ^ "; binding to " ^ ( - match b_maybe_def with - Just (def_idx, def, def_item) -> "linkable idx " ^ (show def_idx) ^ - ", def sym scn " ^ (show def.def_sym_scn) ^ ", def sym idx " ^ - (show def.def_sym_idx) - | Nothing -> "no definition" - end - ) - ) - in*) true - else false) bis_and_bs with - [] -> failwith "impossible: list of bindings does not include symbol reference (filtered list empty)" - | [(bi, b)] -> b - | _ -> failwith ("impossible: list of bindings binds reference to symbol `" - ^ (r.ref.ref_symname ^ "' more than one way (filtered list has >1 element)")) - ) - )) - -type reloc_site_resolution = reloc_site * binding * reloc_decision - - -(*val mark_fate_of_relocs : natural -> abi any_abi_feature -> set Command_line.link_option -> - binding_map -> linkable_item -> elf_memory_image -> ((list reloc_site_resolution) * elf_memory_image)*) -let mark_fate_of_relocs linkable_idx a options bindings_by_name item img2:(reloc_site*((Nat_big_num.num*symbol_reference*(linkable_object*input_item*input_options))*(Nat_big_num.num*symbol_definition*(linkable_object*input_item*input_options))option)*reloc_decision)list*(any_abi_feature)annotated_memory_image= -( - (* Our image already models relocation sites. For each relocation *record*, - * we use our bindings to make a decision about whether to apply it or not. - * - * Q1. How do we get the .rela.dyn made? Synthesise a fake reloc section? - * Or pass them through to the linker script separately? - * AHA. Note that the script already has an entry for .rela.dyn. - * And it matches the ordinary rel sections, e.g. .rela.text and so on. - * So if "-q" is active, the applied relocs need to be injected back in *after* the script - * has run. - * So we need both to materialize some relocs into the script inputs, *and* save some for later. - * - * Can we just use memory image metadata as the "saved for later" case? YES, I think so. - * What do we do with metadata that is now being materialized? - * I think we should only remove the metadata when we apply the relocation. - * Q. When do we do that? - * A. *After* address assignment has happened, i.e. all sections are allocated. - *)let building_executable = (Pset.mem (Command_line.OutputKind(Command_line.Executable)) options) in - let building_shared_library = (Pset.mem (Command_line.OutputKind(Command_line.SharedLibrary)) options) in - let bind_functions_early = (Pset.mem Command_line.BindFunctionsEarly options) in - let bind_non_functions_early = (Pset.mem Command_line.BindNonFunctionsEarly options) in - let (new_by_tag, rev_decisions) = (List.fold_left (fun (acc_by_tag, rev_acc_decisions) -> (fun (tag, maybe_range) -> - let pass_through = (Pset.add (tag, maybe_range) acc_by_tag, rev_acc_decisions) - in - (match tag with - SymbolRef(r) -> - (match r.maybe_reloc with - Some reloc1 -> - (* decision: do we want to - * - apply it? if so, do we need a consequent relocation (e.g. R_*_RELATIVE) in the output? - * - PICify it, but leave it interposable? - * - is "PICified, non-interposable" a thing? I don't think so, because non-interposable bindings are - either intra-object *or* necessarily need load-time relocation to account for load addresses. - In fact ELF can't express "non-interposable inter-object bindings" because we can't name - specific objects when binding symbols. - * - leave it alone, i.e. "relocate at load time"? - * - * Some useful questions: is the binding final? - * The GNU linker *never* leaves text relocs alone when generating shared libs; - * it always PICifies them. - * It can leave them alone when generating executables, though. - * This is an approximation; load-time text relocation can make sense for shared libs. - * (but it's dangerous because PC32 relocs might overflow) - *) - let (binding_is_final : Command_line.link_option Pset.set -> binding -> bool) - = (fun options -> (fun ((ref_idx, ref1, ref_item), maybe_def) -> - (match maybe_def with - (* Weak bindings to 0 are final (though libcrunch wishes they weren't!). *) - None -> true - | Some (def_idx, def, def_item) -> Nat_big_num.equal -( - (* Bindings to non-global symbols are final. *)get_elf64_symbol_binding def.def_syment) stb_local - || -( - (* Bindings to hidden- or protected- or internal-visibility globals - * are final. *)Pset.mem (get_symbol_visibility def.def_syment.elf64_st_info)(Pset.from_list Nat_big_num.compare [ stv_hidden; stv_protected; stv_internal ]) - || -( - (* Bindings to global symbols are non-final - * *unless* - * 1. the symbol definition is [going to end up] in the executable - * 2. we're -Bsymbolic, outputting a shared object, - * and the symbol definition is [going to end up] within the same shared object - * 3. we're -Bsymbolic-functions, outputting a shared object, - * and the symbol definition has STT_FUNC and is [going to end up] within the same shared object - * - * ... where "going to end up in an X" means "we're building an X and def is in a RelocELF rather than a SharedELF". - *) - (* 1. *)(building_executable && def_is_in_reloc def_item) || - (* 2 and 3. *) - (building_shared_library && (def_is_in_reloc def_item && - ( ( Nat_big_num.equal(get_elf64_symbol_type def.def_syment) stt_func && bind_functions_early) - || ( not (Nat_big_num.equal (get_elf64_symbol_type def.def_syment) stt_func) && bind_non_functions_early) - )) - ))) - (* FIXME: does it matter if the binding is intra-object or inter-object? - * We don't get inter-object bindings much to non-{default global}s. How much? *) - ))) - in - let (reloc_is_absolute : reloc_site -> bool) = (fun rs -> - let kind = (get_elf64_relocation_a_type rs.ref_relent) in - let (is_abs, _) = (a.reloc kind) in - is_abs) - in - (* What's our decision for this reloc? leave, apply, MakePIC? - * In fact we return both a decision and a maybe-function to create - * the consequent reloc. - * In what circumstances do we leave the reloc? If we're making an executable - and the definition is not in a relocatable input file or archive or script. - Or if we're making a shared library and the reference is "from data". - What does "from data" mean? I think it means it's a PC-relative reloc. - If we compile our code to do movabs $addr, even from a *local* address, - it's not PIC because that address needs load-time fixup. - So actually it's "is absolute address" again. - *) - let b = (retrieve_binding_for_ref - instance_Basic_classes_Eq_Num_natural_dict r linkable_idx item bindings_by_name) - in - let ((ref_idx, _, ref_item), maybe_def) = b - in - let defined_in_shared_lib = ((match maybe_def with - Some (def_idx, def, def_item) -> not (def_is_in_reloc def_item) - | None -> false (* i.e. the "definition", 0, can be "linked in" *) - )) - in - let decide = (fun decision -> ( - (*let _ = errln ("Decided to " ^ match decision with - LeaveReloc -> "leave" - | ApplyReloc -> "apply" - end ^ " relocation in linkable " ^ (show ref_item) ^ "'s image, bound to " ^ - match maybe_def with - Just(def_idx, def, def_item) -> "a definition called `" ^ def.def_symname ^ "' in linkable " ^ - (show def_item) - | Nothing -> "no definition" - end - ) - in*) - Pset.add (SymbolRef({ - ref = (r.ref) - ; maybe_reloc = (r.maybe_reloc) - ; maybe_def_bound_to = (Some (decision, - (match maybe_def with - Some(def_idx, def, def_item) -> - Some { def_symname = (def.def_symname) - ; def_syment = (def.def_syment) - ; def_sym_scn = (def.def_sym_scn) - ; def_sym_idx = (def.def_sym_idx) - ; def_linkable_idx = def_idx - } - | None -> None - ) - )) - } - ), maybe_range) acc_by_tag, -((reloc1, b, decision) :: rev_acc_decisions))) - in - if (building_executable && defined_in_shared_lib) - || (building_shared_library && (reloc_is_absolute reloc1)) - then decide LeaveReloc - else - (* In what circumstances do we apply the reloc? If it's a final binding. *) - if binding_is_final options b then decide ApplyReloc - (* In what circumstances do we MakePIC? If it's a non-absolute relocatable field - * and we're building a shared library. - * - * PIC is a kind of "consequent relocation", so let's think through it. - * A call site that calls <printf> will usually be non-final (overridable). - * Output needs to call <printf@plt>. BUT the trick is as follows: - * the reloc is swizzled so that it binds to the PLT slot <printf@plt>; - * the PLT slot is locally generated, so no reloc is needed. - * So the point is that - * a *non*-applied reloc - * might still need "applying" after a fashion (swizzling). - * The initial reloc is removed! Since PLT means removing relocs from code - * and reproducing their effect using a PLT. - * That's why we need this special MakePIC behaviour. - * Actually, generalise to a ChangeRelocTo. - * - * What about data? - * Suppose I have a shared library containing a read-only pointer to <environ>. - * The binding is final because <environ> is defined in the executable, say. - * PIC doesn't handle this case -- we still need load-time relocation. - * It's PIC, not PID: data can't be made position-independent. - * - * So, at least for simple cases of PIC, we don't need consequent relocation if - * we don't apply the reloc. We'll be removing the reloc. But we *do* need to create - * extra stuff later (PLT, GOT). - *) - else if building_shared_library then decide (* MakePIC *) (ChangeRelocTo(Nat_big_num.of_int 0, r.ref, reloc1)) (* FIXME *) - (* The above are non-exclusive and non-exhaustive. Often, more than one option is available, - * ABIs / practice makes an arbitrary choice. For example, final bindings - * within a library could be realised the PIC way, but aren't (it'd create a - * pointless indirection). *) - else failwith "didn't know what to do with relocation" - | None -> - (* symbol ref with no reloc *) - pass_through - ) - | _ -> pass_through - ) - )) ((Pset.from_list (pairCompare compare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare)))) []), []) (Pset.elements img2.by_tag)) - in - (List.rev rev_decisions, { elements = (img2.elements) - ; by_tag = new_by_tag - ; by_range = (by_range_from_by_tag - instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) new_by_tag) - })) - -(*val strip_metadata_sections : list (reloc_site * binding * reloc_decision) -> abi any_abi_feature -> elf_memory_image -> elf_memory_image*) -let strip_metadata_sections reloc_decisions a img2:(any_abi_feature)annotated_memory_image= - (let (section_tags, section_ranges) = (elf_memory_image_section_ranges img2) - in - let rel_sections = (Lem_list.mapMaybe (fun (range_tag1, (el_name, el_range)) -> - (match range_tag1 with - FileFeature(ElfSection(idx1, isec1)) -> - if Pset.mem isec1.elf64_section_type(Pset.from_list Nat_big_num.compare [ sht_rel; sht_rela ]) - then Some (idx1, isec1, el_name) - else None - | _ -> None - ) - ) (list_combine section_tags section_ranges)) - in - let discarded_sections_with_element_name = (Lem_list.mapMaybe (fun (range_tag1, (el_name, el_range)) -> - (match range_tag1 with - FileFeature(ElfSection(idx1, isec1)) -> - if a.section_is_special isec1 img2 (* discard reloc sections, and we'll re-add them *) - then Some (el_name, range_tag1) else None - ) - ) (list_combine section_tags section_ranges)) - in - let discarded_elements_map = (List.fold_left (fun m -> (fun (el_name, range_tag1) -> - (*let _ = errln ("Discarding a metadata element named `" ^ el_name ^ "'") in*) - Pmap.add el_name range_tag1 m - )) (Pmap.empty compare) discarded_sections_with_element_name) - in - let filtered_image = (Memory_image.filter_elements (fun (el_name, el) -> not (Pmap.mem el_name discarded_elements_map)) img2) - in - let new_reloc_section_length = (fun idx1 -> (fun isec1 -> - let retained_relocs_from_this_section = (let x2 = - ([]) in List.fold_right - (fun(reloc1, b, decision) x2 -> - if Nat_big_num.equal (* is it from this section? *) reloc1.ref_rel_scn - idx1 (* are we retaining it? *) && (decision = LeaveReloc) then - (reloc1, b, decision) :: x2 else x2) reloc_decisions x2) - in Nat_big_num.mul (length retained_relocs_from_this_section) isec1.elf64_section_entsize - )) - in - let (new_reloc_elements, new_reloc_tags_and_ranges) = (List.split (let x2 = - ([]) in List.fold_right - (fun(idx1, isec1, el_name) x2 -> - if Nat_big_num.greater (new_reloc_section_length idx1 isec1) - (Nat_big_num.of_int 0) then - (let new_len = (new_reloc_section_length idx1 isec1) in - let new_el = ({ startpos = None ; length1 = (Some new_len); contents = - ([]) }) in - let new_isec = ({ elf64_section_name = (isec1.elf64_section_name) - ; elf64_section_type = (isec1.elf64_section_type) - ; elf64_section_flags = (isec1.elf64_section_flags) - ; elf64_section_addr =(Nat_big_num.of_int 0) (* should be 0 anyway *) - ; elf64_section_offset =(Nat_big_num.of_int 0) (* ignored *) - ; elf64_section_size = new_len - ; elf64_section_link = (isec1.elf64_section_link) - ; elf64_section_info = (isec1.elf64_section_info) - ; elf64_section_align = (isec1.elf64_section_align) - ; elf64_section_entsize = (isec1.elf64_section_entsize) - ; elf64_section_body = Byte_sequence.empty (* ignored *) - ; elf64_section_name_as_string = (isec1.elf64_section_name_as_string) - }) in - let new_meta = (FileFeature (ElfSection (idx1, new_isec))) in - ((el_name, new_el), (new_meta, Some - (el_name, (Nat_big_num.of_int 0, new_len))))) - :: x2 else x2) rel_sections x2)) - in - let new_by_tag = (Pset.bigunion (pairCompare compare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))))(Pset.from_list (Pset.compare_by (pairCompare compare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))))) [ filtered_image.by_tag; (Pset.from_list (pairCompare compare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare)))) new_reloc_tags_and_ranges) ])) - in - { - elements = (List.fold_right Pmap.union [filtered_image.elements; Lem_map.fromList - (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) new_reloc_elements] (Pmap.empty compare)) - ; by_tag = new_by_tag - ; by_range = (by_range_from_by_tag - instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) new_by_tag) - }) - - -let expand_sections_for_one_image a options bindings_by_name linkable_idx item strip_relocs:(reloc_site*binding*reloc_decision)list*(any_abi_feature)annotated_memory_image*(input_spec)list= - ((match item with - (RelocELF(img2), (fname1, blob, origin), input_opts) -> - (*let _ = List.foldl (fun _ -> fun (isec, shndx) -> - let _ = errln ("For file " ^ fname ^ " before stripping, saw section idx " ^ (show shndx) ^ - " with name " ^ isec.elf64_section_name_as_string ^ ", first 20 bytes: " ^ (show (take 20 ( - (let maybe_elname = elf_memory_image_element_coextensive_with_section shndx img - in - match maybe_elname with - Nothing -> failwith ("impossible: no such section (" ^ (show shndx) ^ ") in image of " ^ fname) - | Just idstr -> - match Map.lookup idstr img.elements with - Just el -> el.contents - | Nothing -> failwith "no such element" - end - end - ))))) - in - () - ) () (elf_memory_image_sections_with_indices img) - in*) - let ((reloc_decisions : (reloc_site * binding * reloc_decision) list), marked_img) = (mark_fate_of_relocs linkable_idx a options bindings_by_name item img2) - in - (* Now we have a decision for each reloc: Leave, Apply, MakePIC. Which ones - * do we materialize? Only the Leave ones, for now. To support -q we'll - * have to support tweaking this. - * - * For each relocation that we Leave, we figure out its originating section - * and re-create a lookalike in the memory image. - * - * We also get called for the "generated" memory image that contains .plt, - * .rela.plt and so on. We don't strip these, since they actually contain relocs - * that need to go directly into the output file. That's what the strip_relocs - * argument is for. FIXME: refactor this into two functions. - *) - let stripped_img_with_reloc_sections = (if strip_relocs - then (*let _ = errln ("Discarding metadata sections from image of `" ^ fname ^ "'") in*) - strip_metadata_sections reloc_decisions a marked_img - else marked_img) - in - (* Now we have a whole new image! It differs from the old one in that - * - non-special sections have been stripped - * - the relocs we want to participate in linking have been materialized. - *) - (* The "-q" option is tricky. It causes all incoming relocs to be retained, but - * they *don't* participate in linking -- notice that the default linker script - * pulls all .rela.* sections into .rela.dyn, whereas these ones *don't* go in there. - * So FIXME: to support this, we need a way to re-add them, probably when we - * generate meta-output like .symtab etc.. *) - let inputs = - - (List.rev_append (List.rev (let x2 = - ([]) (* not (a.section_is_special isec img *)in - List.fold_right - (fun(isec1, shndx1) x2 -> - if true then - (let short_name = (short_string_of_linkable_item item) in - (*let _ = errln ("For file " ^ short_name ^ " after stripping, saw section idx " ^ (show shndx) ^ - " with name " ^ isec.elf64_section_name_as_string ^ ", first 20 bytes: " ^ (show (take 20 ( - (let maybe_elname = elf_memory_image_element_coextensive_with_section shndx stripped_img_with_reloc_sections - in - match maybe_elname with - Nothing -> failwith ("impossible: no such section (matching " ^ (show shndx) ^ ")") - | Just idstr -> - match Map.lookup idstr stripped_img_with_reloc_sections.elements with - Just el -> el.contents - | Nothing -> failwith "no such element" - end - end - ))))) - in*) - InputSection - ({ idx = linkable_idx ; fname = short_name - ; img = stripped_img_with_reloc_sections ; shndx = shndx1 - ; secname = (isec1.elf64_section_name_as_string) ; isec = isec1 - })) :: x2 else x2) - (elf_memory_image_sections_with_indices stripped_img_with_reloc_sections) - x2)) ( - (* One item per common symbol. FIXME: what about common symbols that have the same name? - * We need to explicitly instantiate common symbols somewhere, probably here. - * This means dropping any that are unreferenced (does it?) and merging any multiply-defined. - * Actually, we deal with section merging at the same time as section concatenation, so during - * linker script processing. For discarding unused common symbols, I *think* that this has already - * been done by discarding unreferenced inputs. *) - let common_symbols = (all_common_symbols stripped_img_with_reloc_sections) - in - (*let _ = errln ("Expanding " ^ (show (length common_symbols)) ^ " common symbols") - in*) - let x2 = ([]) in List.fold_right - (fun def x2 -> - if - (*let _ = Missing_pervasives.outln ((space_padded_and_maybe_newline 20 def.def_symname) - ^ (let hexstr = "0x" ^ (hex_string_of_natural (natural_of_elf64_xword def.def_syment.elf64_st_size)) - in - space_padded_and_maybe_newline 20 hexstr - ) - ^ - fname) - in*) - true then - Common (linkable_idx, fname1, stripped_img_with_reloc_sections, def) :: - x2 else x2) common_symbols x2 - )) - in (reloc_decisions, stripped_img_with_reloc_sections, inputs) - | _ -> failwith "non-reloc linkable not supported yet" -)) - -type reloc_resolution = reloc_site * binding * reloc_decision - -(*val default_merge_generated : abi any_abi_feature -> elf_memory_image -> list (list Linker_script.input_spec) -> list (list Linker_script.input_spec)*) -let default_merge_generated a generated_img input_spec_lists:((input_spec)list)list= -( - (* We expand the sections in the generated image and hang them off - * the first linkable item. *) - (*let _ = errln ("Generated image has " ^ (show (Map.size generated_img.elements)) ^ " elements and " ^ (show (Set.size (generated_img.by_tag))) ^ - " metadata elements (sanity: " ^ (show (Set.size (generated_img.by_range))) ^ ")") - in*)let dummy_input_item = ("(no file)", Input_list.Reloc(Sequence([])), ((Command_line.File(Command_line.Filename("(no file)"), Command_line.null_input_file_options)), [InCommandLine(Nat_big_num.of_int 0)])) - in - let dummy_linkable_item = (RelocELF(generated_img), dummy_input_item, Input_list.null_input_options) - in - let (_, _, generated_inputs) = (expand_sections_for_one_image a(Pset.from_list compare []) (Pmap.empty compare)(Nat_big_num.of_int 0) dummy_linkable_item false) - in - (*let _ = errln ("Generated image yielded " ^ (show (length generated_inputs)) ^ " input items") - in*) - (* okay, hang them off the first one *) - (match input_spec_lists with - [] -> failwith "link job empty" - | first_input_list :: more_input_lists -> ( List.rev_append (List.rev first_input_list) generated_inputs) :: more_input_lists - )) - (* input_spec_lists *) - -(*val expand_sections_for_all_inputs : abi any_abi_feature -> set Command_line.link_option -> binding_map -> - (abi any_abi_feature -> elf_memory_image -> list (list Linker_script.input_spec) -> list (list Linker_script.input_spec)) (* merge_generated *) -> - list (natural * Linkable_list.linkable_item) -> - list (list reloc_resolution * elf_memory_image * list Linker_script.input_spec)*) -let expand_sections_for_all_inputs a options bindings_by_name merge_generated idx_and_linkables:((reloc_site*binding*reloc_decision)list*(any_abi_feature)annotated_memory_image*(input_spec)list)list= - (let (expanded_reloc_lists, expanded_imgs, linker_script_input_lists) = (unzip3 (Lem_list.map (fun (idx1, linkable) -> - expand_sections_for_one_image a options bindings_by_name idx1 linkable true) idx_and_linkables)) - in - let fnames = (Lem_list.map (fun (idx1, (_, (fname1, _, _), _)) -> fname1) idx_and_linkables) - in - (* We pass the collection of linkable images and reloc decision lists - * to an ABI tap function. - * - * This returns us a new *image* containing all the elements. Logically - * this is another participant in the link, which we could expand separately. - * A personality function takes care of actually merging it back into the - * linker script inputs... in the case of the GNU linker, this means pretending - * the generated stuff came from the first input object. - *) - let generated_img = (a.generate_support (* expanded_relocs *) (list_combine fnames expanded_imgs)) - in - (* We need to return a - * - * list (list reloc_decision * elf_memory_image * list Linker_script.input_spec) - * - * i.e. one item for every input image. *) - let (final_input_spec_lists : ( Linker_script.input_spec list) list) = (merge_generated a generated_img linker_script_input_lists) - in - zip3 expanded_reloc_lists expanded_imgs final_input_spec_lists) - -(*val relocate_output_image : abi any_abi_feature -> map string (list (natural * binding)) -> elf_memory_image -> elf_memory_image*) -let relocate_output_image a bindings_by_name img2:(any_abi_feature)annotated_memory_image= - (let relocs = (Multimap.lookupBy0 - (instance_Basic_classes_Ord_Memory_image_range_tag_dict - instance_Basic_classes_Ord_Abis_any_abi_feature_dict) (instance_Basic_classes_Ord_Maybe_maybe_dict - (instance_Basic_classes_Ord_tup2_dict - Lem_string_extra.instance_Basic_classes_Ord_string_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_Num_natural_dict - instance_Basic_classes_Ord_Num_natural_dict))) instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) (Memory_image_orderings.tagEquiv - instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict) (SymbolRef(null_symbol_reference_and_reloc_site)) - img2.by_tag) - in - - (*let _ = errln ("For __libc_multiple_threads (in relocate_output_image), we have " ^ - (let all_bs = match Map.lookup "__libc_multiple_threads" bindings_by_name with - Just l -> l - | Nothing -> [] - end - in - ((show (length all_bs)) ^ - " bindings, of which " ^ - (show (length (List.filter (fun (bi, ((ref_idx, ref, ref_item), maybe_def)) -> - match maybe_def with - Just _ -> true - | _ -> false - end - ) all_bs))) ^ " have defs"))) - in*) - let apply_reloc = (fun img2 -> fun (el_name, start, len) -> fun symref_and_reloc_site -> fun symaddr -> ( - let reloc_site1 = ((match symref_and_reloc_site.maybe_reloc with - None -> failwith "impossible: no reloc site during relocation" - | Some r -> r - )) - in - let (field_is_absolute_addr, applyfn) = (a.reloc (get_elf64_relocation_a_type reloc_site1.ref_relent)) - in - let element1 = ((match Pmap.lookup el_name img2.elements with - None -> failwith "impossible: reloc site in nonexistent section" - | Some e -> e - )) - in - let site_address = ((match element1.startpos with - Some addr -> Nat_big_num.add addr start - | None -> failwith "error: relocation in section with no address" - )) - in - let (width, calculate) = (applyfn img2 site_address symref_and_reloc_site) - in - let existing_field = (extract_natural_field width element1 start) - in - (*let _ = errln ("Existing field has value 0x" ^ (hex_string_of_natural existing_field)) - in*) - (*let _ = errln ("Symaddr has value 0x" ^ (hex_string_of_natural symaddr)) - in*) - let addend = (Nat_big_num.of_int64 reloc_site1.ref_relent.elf64_ra_addend) - in - let new_field_value = (calculate symaddr addend existing_field) - in - (*let _ = errln ("Calculated new field value 0x" ^ (hex_string_of_natural new_field_value)) - in*) - let new_element = (write_natural_field new_field_value width element1 start) - in - { - elements = (Pmap.add el_name new_element (Pmap.remove el_name img2.elements)) - ; by_tag = (Pset.diff img2.by_tag(Pset.from_list (pairCompare compare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare)))) [(SymbolRef(symref_and_reloc_site), Some(el_name, (start, len)))])) - ; by_range = (Pset.diff img2.by_range(Pset.from_list (pairCompare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))) compare) [(Some(el_name, (start, len)), SymbolRef(symref_and_reloc_site))])) - } - )) - in - let relocated_img = (List.fold_left (fun acc_img -> (fun (tag, maybe_range) -> - (match tag with - SymbolRef(x) -> (match x.maybe_reloc with - Some rs -> - (match maybe_range with - None -> failwith "impossible: reloc site with no range" - | Some (el_name, (start, len)) -> - (*let _ = errln ("During relocation, saw a reloc site in element " ^ el_name ^ ", offset 0x" ^ - (hex_string_of_natural start) ^ ", length 0x" ^ (hex_string_of_natural len) ^ - ", reloc type " ^ (* a. *) Abi_amd64_relocation.string_of_amd64_relocation_type (get_elf64_relocation_a_type rs.ref_relent) ^ - ", symbol name `" ^ x.ref.ref_symname ^ "'") - in*) - let symaddr = ((match x.maybe_def_bound_to with - Some(ApplyReloc, Some(bound_def)) -> - (* Here we are mapping - * *from* the definition found in an input object during resolution (bound_def) - * *to* the corresponding symbol in the output image, now that we've built it. - * - * Q. What about ABI-specific interventions, e.g. - * redirecting a symbol reference to its GOT or PLT slot? - * A. Indeed, we need to ask the ABI to give us the target - * address. The default implementation is just to look for - * a matching symbol and use its address. But ABIs can do - * wacky things if they like. - *) - a.get_reloc_symaddr bound_def img2 x.maybe_reloc - | None -> failwith "no def found for bound-to symbol" - | Some(ApplyReloc, None) -> - (*let _ = errln "No definition, so we think this is a weak reference; giving it value 0." - in*) - (* CHECK: does the syment say it's weak? *) - if not (Nat_big_num.equal (get_elf64_symbol_binding x.ref.ref_syment) stb_weak) then - (*let _ = errln "Actually not weak! bailing" - in*) - failwith "not a weak reference, but no binding" - else Nat_big_num.of_int - (* Weak symbol. *)0 - | Some(LeaveReloc, _) -> - (* We shouldn't be seeing this, given that we're applying the reloc Right Now. *) - failwith "internal error: applying reloc that is not to be applied" - )) - in - (*let _ = errln ("Got symaddr: 0x" ^ (hex_string_of_natural symaddr)) - in*) - apply_reloc acc_img (el_name, start, len) x symaddr - ) - | None -> (* okay, do nothing *) acc_img - ) - | _ -> failwith "impossible: not a symbol ref" - ) - )) img2 relocs) - in - relocated_img) - -(*val link : address_expr_fn_map allocated_sections_map -> linker_control_script -> abi any_abi_feature -> set Command_line.link_option -> linkable_list -> elf_memory_image*) -let link alloc_map script1 a options linkables:(any_abi_feature)annotated_memory_image= - (let initial_included_indices = (mapMaybei (fun i -> (fun (obj, inp, (opts : input_options)) -> - if opts.item_force_output - then Some i - else None - )) linkables) - in - let linker_script_linkable_idx = (length linkables) - in - let defmap = (all_definitions_by_name linkables) - in - let (accumulated_bindings : binding list) - = -( (* accumulate_bindings_bf a linkables defmap {} initial_included_indices [] *)accumulate_bindings_objectwise_df a linkables defmap [](Pset.from_list Nat_big_num.compare []) initial_included_indices) - in - (* Keep a map whose keys are referenced objects, and whose values are - * *some* (diagnostic purposes only) reference to that linkable. *) - let referenced_object_indices_and_reasons = (List.fold_left (fun acc_m -> (fun ((ref_idx, ref_sym, ref_linkable), maybe_def_idx_and_sym_and_linkable) -> - (match maybe_def_idx_and_sym_and_linkable with - None -> acc_m - | Some (def_idx, def_sym, def_linkable) -> - (* Make sure the map contains this key. *) - if (Lem.option_equal (Lem.pair_equal (=) - (tripleEqual instance_Basic_classes_Eq_var_dict - (instance_Basic_classes_Eq_tup3_dict - instance_Basic_classes_Eq_string_dict - instance_Basic_classes_Eq_var_dict - (instance_Basic_classes_Eq_tup2_dict - instance_Basic_classes_Eq_var_dict - (instance_Basic_classes_Eq_list_dict - instance_Basic_classes_Eq_var_dict))) - instance_Basic_classes_Eq_var_dict)) (Pmap.lookup def_idx acc_m) None) - then Pmap.add def_idx (ref_sym, ref_linkable) acc_m - else acc_m - ) - )) ((Pmap.empty Nat_big_num.compare) : (Nat_big_num.num, (symbol_reference * linkable_item)) Pmap.map) accumulated_bindings) - in - (* Print something similar to GNU ld's linker map output, about included archive members. *) - (*let _ = Missing_pervasives.outln "Archive member included to satisfy reference by file (symbol)\n" in*) - let linkables_not_discarded = (mapMaybei (fun i -> (fun (obj, inp, opts) -> - let referenced_object_map_entry = (Pmap.lookup i referenced_object_indices_and_reasons) - in - let referenced = ( not ((Lem.option_equal (Lem.pair_equal (=) - (tripleEqual instance_Basic_classes_Eq_var_dict - (instance_Basic_classes_Eq_tup3_dict - instance_Basic_classes_Eq_string_dict - instance_Basic_classes_Eq_var_dict - (instance_Basic_classes_Eq_tup2_dict - instance_Basic_classes_Eq_var_dict - (instance_Basic_classes_Eq_list_dict - instance_Basic_classes_Eq_var_dict))) - instance_Basic_classes_Eq_var_dict)) referenced_object_map_entry None))) - in - (* Print our link map thing *) - (*let _ = ( - if (not referenced) then () else - (* Did it come from an archive? *) - let (name, _, (inp_unit, coordlist)) = inp in - match coordlist with - InArchive(aid, aidx, aname, _) :: _ -> - (* yes, from an archive, so print a line *) - let (ref_sym, (ref_obj, (ref_name, ref_blob, ref_origin), ref_opts)) = match referenced_object_map_entry with - Just(x, y) -> (x, y) - | Nothing -> failwith "impossible: referenced item has no definition" - end - in - let lhs_name = aname ^ "(" ^ name ^ ")" - in - let lhs_name_len = stringLength lhs_name - in - let spacing = if lhs_name_len >= 29 - then ("\n" ^ (makeString 30 #' ')) - else makeString (30 - lhs_name_len) #' ' - in - Missing_pervasives.outln ( - lhs_name ^ spacing ^ - (match ref_origin with - (_, InArchive(bid, bidx, bname, _) :: _) -> bname ^ "(" ^ ref_name ^ ")" - | _ -> ref_name - end) - ^ " (" ^ ref_sym.ref_symname ^ ")" - ) - | _ (* not from an archive *) -> () - end - ) - in*) - if referenced || opts.item_force_output - then Some (i, (obj, inp, opts)) - else None - )) linkables) - in - (*let _ = Missing_pervasives.outln "\nAllocating common symbols\nCommon symbol size file\n" - in*) - (* We have to do a pass over relocations quite early. This is because relocs *do* participate - * in linking. For each reloc, we need to decide whether to apply it or not. For those not applied, - * we include it in a synthesised section that participates in linking. - * - * Similarly, the GOT needs to participate in linking, so that it gets assigned an address - * at the appropriate place (as determined by the script). So we have to generate the GOT - * *before* running the linker script. The GNU linker hangs the whole GOT and PLT content - * off the first input object (usually crt1.o). In general, expand_sections calls an ABI tap - * which synthesises all the necessary things, like (in the GNU case) the .got and .plt sections - * hanging off the first input object. *) - let (initial_bindings_by_name : (string, ( (Nat_big_num.num * binding)list)) Pmap.map) = - (List.fold_left (fun m -> fun (b_idx, ((ref_idx, ref1, ref_item), maybe_def)) -> (match Pmap.lookup ref1.ref_symname m with - None -> Pmap.add ref1.ref_symname [ (b_idx, ((ref_idx, ref1, ref_item), maybe_def)) ] m - | Some ((bi, b) :: more) -> Pmap.add ref1.ref_symname ((b_idx, ((ref_idx, ref1, ref_item), maybe_def)) :: ((bi, b) :: more)) m - | _ -> failwith "impossible: found empty list in map lacking empties by construction" - )) (Pmap.empty compare) (Lem_list.mapi (fun i -> fun b -> (Nat_big_num.of_int i, b)) accumulated_bindings)) - in - let (expanded_triples : ( reloc_resolution list * elf_memory_image * Linker_script.input_spec list) list) - = (expand_sections_for_all_inputs a options initial_bindings_by_name default_merge_generated linkables_not_discarded) - in - let (reloc_resolutions, imgs, input_lists) = (unzip3 expanded_triples) - in - let input_sections = (list_concat input_lists) - in - let seen_ordering = (fun is1 -> (fun is2 -> ( - let toNaturalList = (fun is -> ( - (* We're mapping the item to a list of naturals that determine a - * lexicographic order. The list has a fixed depth: - * - * [within-commandline, within-group, within-archive, section-or-symbol] - * - * For .o files on the command line, we use the command line order. This - * is the first level in the hierarchy. - * - * For .a files with --whole-archive, we want to do the same. Do this - * by using archive position as the second level of the hierarchy, *if* - * the item is marked as force_output. - * - * For other archives, "order seen" means something different: it's - * the order in which they were "pulled in" during input enumeration. Another - * way to say this is that they're ordered by the first binding that was - * made to them. We map these to numbers starting from the size of the archive, - * i.e. so that "force_output" makes an element appear sooner. In practice - * we won't get a mixture of force_output and non- in the same archive, - * so each archive will use only one of the two orderings. - * - * How do sections order relative to common symbols? Again, in practice it - * doesn't matter because no input query will get a mixture of the two. - * For symbols, we start the numbering from the number of sections in the file, - * so symbols always appear later in the sortd order. - *) - let (linkable_idx, section_or_symbol_idx) = ((match is with - Common(idx1, fname1, img2, def) -> (idx1, Nat_big_num.add - (let (_, l) = (elf_memory_image_section_ranges img2) in length l) def.def_sym_idx) - | InputSection(isrec) -> (isrec.idx, isrec.shndx) - )) - in - (match Lem_list.list_index linkables (Nat_big_num.to_int linkable_idx) with - None -> failwith "impossible: linker input not in linkables list" - | Some (obj, (fname1, blob, (inp_unit, coords)), options) -> - let (our_cid, our_gid, our_aid, maybe_archive_size) = ((match coords with - InArchive(aid, aidx, _, asize) :: InGroup(gid1, gidx) :: [InCommandLine(cid)] -> (cid, gid1, aid, Some asize) - | InArchive(aid, aidx, _, asize) :: [InCommandLine(cid)] -> (cid,Nat_big_num.of_int 0, aid, Some asize) - | InGroup(gid1, gidx) :: [InCommandLine(cid)] -> (cid, gid1,Nat_big_num.of_int 0, None) - | [InCommandLine(cid)] -> (cid,Nat_big_num.of_int 0,Nat_big_num.of_int 0, None) - | _ -> failwith "internal error: impossible coordinates" - )) - in - let aid_to_use = (if options.item_force_output then our_aid - else (* how many elements does the archive have? *) - let archive_size = ((match maybe_archive_size with - None -> failwith "impossible: archive with no size" - | Some a -> a - )) - in Nat_big_num.add archive_size - (* search the bindings: we want the index of the first binding - that refers to this object. - *) - (match Lem_list.find_index (fun ((b_ref_idx, b_ref, b_ref_item), b_maybe_def) -> (match b_maybe_def with - Some (b_def_idx, b_def, b_def_item) -> Nat_big_num.equal b_def_idx linkable_idx - | _ -> false - )) accumulated_bindings with - Some n -> Nat_big_num.of_int n - | None -> failwith "impossible: non-force-output object does not contain any bound-to defs" - )) - in - (* do we care about group idx? probably not. *) - [our_cid; aid_to_use; section_or_symbol_idx] - ) - )) - in -(lexicographic_compare Nat_big_num.compare (toNaturalList is1) (toNaturalList is2)) - ))) - in - (* - let get_binding_for_ref = (fun symref -> (fun linkable_idx -> (fun fname -> - let name_matches = match Map.lookup symref.ref_symname bindings_by_name with Just x -> x | Nothing -> [] end - in - match List.filter (fun (bi, ((r_idx, r, r_item), m_d)) -> r_idx = linkable_idx && r = symref) name_matches with - [(b_idx, b)] -> (b_idx, b) - | [] -> failwith "no binding found" - | _ -> failwith ("ambiguous binding found for symbol `" ^ symref.ref_symname ^ "' in file " ^ fname) - end - ))) - in - *) - let (unrelocated_output_image_lacking_abs_symbols, bindings_by_name) - = (interpret_linker_control_script alloc_map script1 linkables linker_script_linkable_idx a input_sections seen_ordering default_place_orphans initial_bindings_by_name) - in - (* also copy over ABS (range-less) symbols from all included input items *) - let all_abs_range_tags_in_included_inputs = (List.concat ( - Lem_list.map (fun (img2, (idx1, linkable)) -> - let abslist = (Lem_list.mapMaybe (fun (tag, maybeRange) -> - (match tag with - SymbolDef(ent) -> if (Lem.option_equal (Lem.pair_equal (=) (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal)) maybeRange None) && Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string ent.def_syment.elf64_st_shndx)) shn_abs - then Some (maybeRange, ent) - else None - | _ -> None - ) - ) (tagged_ranges_matching_tag - instance_Basic_classes_Ord_Abis_any_abi_feature_dict instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict (SymbolDef(null_symbol_definition)) img2)) - in - (*let _ = errln ("Copying " ^ (show (length abslist)) ^ " ABS symbols (names: " ^ - List.foldl (fun acc -> fun str -> if stringLength acc = 0 then str else acc ^ ", " ^ str) "" - (List.map (fun (_, x) -> x.def_symname) abslist) - ^ ") from not-discarded linkable item " ^ - (short_string_of_linkable_item linkable)) - in*) - let x2 = ([]) in List.fold_right - (fun(maybe_range, ent) x2 -> - if true then - (maybe_range, SymbolDef - ({ def_symname = (ent.def_symname) - ; def_syment = (ent.def_syment) - ; def_sym_scn = (ent.def_sym_scn) - ; def_sym_idx = (ent.def_sym_idx) - ; def_linkable_idx = idx1 })) :: x2 else x2) - abslist x2 - ) (list_combine imgs linkables_not_discarded) - )) - in - let by_range_including_abs_symbols = - - (Pset.(union) unrelocated_output_image_lacking_abs_symbols.by_range - ((Pset.from_list (pairCompare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))) compare) all_abs_range_tags_in_included_inputs))) - in - let unrelocated_output_image = ({ - elements = (unrelocated_output_image_lacking_abs_symbols.elements) - ; by_range = by_range_including_abs_symbols - ; by_tag = (by_tag_from_by_range - (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) instance_Basic_classes_SetType_var_dict by_range_including_abs_symbols) - }) - (* This image has - * - addresses assigned - * - relocations *not* applied - * - no entry point - * - some ABI features not generated? GOT, certainly. HMM. - -- don't consider output features, like symtabs, yet; - -- other ABI features have to be generated before the linker script runs (dyn relocs, GOT, PLT?) - -- ... so we might be okay for now. - *) - in - let remaining_relocs = (Multimap.lookupBy0 - (instance_Basic_classes_Ord_Memory_image_range_tag_dict - instance_Basic_classes_Ord_Abis_any_abi_feature_dict) (instance_Basic_classes_Ord_Maybe_maybe_dict - (instance_Basic_classes_Ord_tup2_dict - Lem_string_extra.instance_Basic_classes_Ord_string_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_Num_natural_dict - instance_Basic_classes_Ord_Num_natural_dict))) instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) (Memory_image_orderings.tagEquiv - instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict) (SymbolRef(null_symbol_reference_and_reloc_site)) - unrelocated_output_image.by_tag) - in - let _ = (List.fold_left (fun _ -> (fun (tag, maybe_range) -> - let _ = ((match tag with - SymbolRef(x) -> (match x.maybe_reloc with - Some rs -> - (match maybe_range with - None -> failwith "impossible: reloc site with no range" - | Some (el_name, (start, len)) -> - () (* errln ("After linking, saw a reloc site in element " ^ el_name ^ ", offset 0x" ^ - (hex_string_of_natural start) ^ ", length 0x" ^ (hex_string_of_natural len) ^ - ", reloc type " ^ Abi_amd64_relocation.string_of_amd64_relocation_type (get_elf64_relocation_a_type rs.ref_relent)) *) - ) - | None -> (* okay, do nothing *) () - ) - | _ -> failwith "impossible: not a symbol ref" - )) - in - () - )) () remaining_relocs) - in - (* Before we relocate, we concretise any ABI features that we've linked in. *) - (*let _ = errln "Asking ABI to concretise support structures" in*) - let unrelocated_concrete_output_image = (a.concretise_support unrelocated_output_image) - in - let output_image = (relocate_output_image a bindings_by_name unrelocated_concrete_output_image) - in - let (maybe_entry_point_address : Nat_big_num.num option) = - ((match Command_line.find_option_matching_tag (Command_line.EntryAddress(Nat_big_num.of_int 0)) options with - None -> a.guess_entry_point output_image - | Some(Command_line.EntryAddress(x)) -> Some x - )) - in - (match maybe_entry_point_address with - Some addr -> - (match address_to_element_and_offset addr output_image with - Some (el_name, el_offset) -> - (*let _ = errln ("Tagging element " ^ el_name ^ " as containing entry point at offset 0x" ^ (hex_string_of_natural el_offset)) - in*) - tag_image (EntryPoint) el_name el_offset(Nat_big_num.of_int 0) output_image - | None -> - (* HMM. entry point symbol has no address at present. *) - failwith ("error: entry point address 0x" ^ ((hex_string_of_natural addr) ^ " does not correspond to any element position")) - ) - | None -> - (*let _ = errln "Warning: not tagging entry point in output image" - in*) - output_image - )) diff --git a/lib/ocaml_rts/linksem/linkable_list.ml b/lib/ocaml_rts/linksem/linkable_list.ml deleted file mode 100644 index c128563c..00000000 --- a/lib/ocaml_rts/linksem/linkable_list.ml +++ /dev/null @@ -1,568 +0,0 @@ -(*Generated by Lem from linkable_list.lem.*) -open Lem_basic_classes -open Lem_function -open Lem_string -open Lem_string_extra -open Lem_tuple -open Lem_bool -open Lem_list -open Lem_list_extra -open Lem_set -open Lem_set_extra -(*import Map*) -open Lem_sorting -open Lem_num -open Lem_maybe -open Lem_assert_extra - -open Byte_sequence -open Default_printing -open Error -open Missing_pervasives -open Show - -open Elf_types_native_uint -open Elf_memory_image -open Elf_header -open Elf_file -open Memory_image -open Elf_memory_image -open Elf_section_header_table -open Elf_symbol_table -open String_table -open Input_list - -open Elf_memory_image -open Elf_memory_image_of_elf64_file - -type script = byte_sequence (* FIXME *) - -type linkable_object = RelocELF of elf_memory_image (* memory image without address assignments *) - | SharedELF of elf_memory_image (* memory image with address assignments *) - | ScriptAST of script (* FIXME: should be elaborated away *) - | ControlScriptDefs - -(*val string_of_linkable_object : linkable_object -> string*) -let string_of_linkable_object l:string= ((match l with - RelocELF(_) -> "a relocatable file (...)" - | SharedELF(_) -> "a shared library (...)" - | ScriptAST(_) -> "a linker script (...)" - | ControlScriptDefs -> "the control script" -)) - -(* We keep the original input item around, hence the filename and byte sequence - * and options. *) -type linkable_item = linkable_object * input_item * input_options - -(*val short_string_of_linkable_item : linkable_item -> string*) -let short_string_of_linkable_item item:string= - (let (obj, inp, opts) = item - in - short_string_of_input_item inp) - -let instance_Show_Show_Linkable_list_linkable_object_dict:(linkable_object)show_class= ({ - - show_method = string_of_linkable_object}) - -type linkable_list = linkable_item list - -type symbol_resolution_oracle = linkable_list -> int -> string -> int list -type binding = (Nat_big_num.num * symbol_reference * linkable_item) * (Nat_big_num.num * symbol_definition * linkable_item)option -type binding_list = binding list -type binding_map = (string, ( (Nat_big_num.num * binding)list)) Pmap.map - - -let image_of_linkable_item item:(Abis.any_abi_feature)annotated_memory_image= ((match item with - (RelocELF(image), _, _) -> image - | (SharedELF(image), _, _) -> image - | _ -> failwith "no image" -)) - -(*val linkable_item_of_input_item_and_options : forall 'abifeature. abi 'abifeature -> input_item -> input_options -> linkable_item*) -let linkable_item_of_input_item_and_options a it opts:linkable_object*(string*input_blob*(Command_line.input_unit*(origin_coord)list))*input_options= - ((match ((match it with - (fname1, Reloc(seq), origin) -> - (*let _ = Missing_pervasives.errln ("Considering relocatable file " ^ fname) in*) - Elf_file.read_elf64_file seq >>= (fun e -> - return (RelocELF(elf_memory_image_of_elf64_file a fname1 e), it, opts)) - | (fname1, Shared(seq), origin) -> - (*let _ = Missing_pervasives.errln ("Skipping shared object " ^ fname) in *) - fail "unsupported input item" - | (fname1, Script(seq), origin) -> - (*let _ = Missing_pervasives.errln ("Skipping linker script " ^ fname) in*) - fail "unsupported input item" - )) - with - Success(item) -> item - | Fail(str) -> failwith (str ^ ": non-ELF or non-relocatable input file") - )) - -(*val string_of_linkable : linkable_item -> string*) -let string_of_linkable l:string= ((match l with - (_, item, _) -> string_of_triple - instance_Show_Show_string_dict instance_Show_Show_Input_list_input_blob_dict (instance_Show_Show_tup2_dict - Command_line.instance_Show_Show_Command_line_input_unit_dict - (instance_Show_Show_list_dict - instance_Show_Show_Input_list_origin_coord_dict)) item -)) - -(* How do we signal "multiple definitions"? - * This is part of the policy baked into the particular oracle: - * are multiple definitions okay, or do we fail? - * - * NOTE that multiple definitions *globally* is not the same as - * multiple definitions as candidates for a given binding. We - * can get the former even if we don't have the latter, in some - * weird group/archive arrangements. The right place to detect - * this condition is probably when generating the output symtab. - *) - -(*val add_definition_to_map : (natural * symbol_definition * linkable_item) -> Map.map string (list (natural * symbol_definition * linkable_item)) - -> Map.map string (list (natural * symbol_definition * linkable_item))*) -let add_definition_to_map def_idx_and_def_and_linkable m:((string),((Nat_big_num.num*symbol_definition*(linkable_object*input_item*input_options))list))Pmap.map= - (let (def_idx, def, def_linkable) = def_idx_and_def_and_linkable - in - (match Pmap.lookup def.def_symname m with - Some curlist -> Pmap.add def.def_symname ((def_idx, def, def_linkable) :: curlist) m - | None -> Pmap.add def.def_symname [(def_idx, def, def_linkable)] m - )) - -(*val all_definitions_by_name : linkable_list -> Map.map string (list (natural * symbol_definition * linkable_item))*) -let all_definitions_by_name linkables:((string),((Nat_big_num.num*symbol_definition*linkable_item)list))Pmap.map= -( - (* Now that linkables are ELF memory images, we can make the - * list of definitions much more easily. *)let list_of_deflists = (Lem_list.mapi (fun (idx1 : int) -> (fun (item : linkable_item) -> - let img2 = (image_of_linkable_item item) - in - let (all_def_tags, all_def_ranges) - = (List.split (Multimap.lookupBy0 - (Memory_image_orderings.instance_Basic_classes_Ord_Memory_image_range_tag_dict - Abis.instance_Basic_classes_Ord_Abis_any_abi_feature_dict) (instance_Basic_classes_Ord_Maybe_maybe_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_string_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_Num_natural_dict - instance_Basic_classes_Ord_Num_natural_dict))) instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) (Memory_image_orderings.tagEquiv - Abis.instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict) (SymbolDef(null_symbol_definition)) img2.by_tag)) - in - let all_defs = (Lem_list.map (fun tag -> (match tag with - SymbolDef(def) -> (def, item) - | _ -> failwith "matched tag not a symbol definition" - )) all_def_tags) - in - let x2 = ([]) in List.fold_right - (fun(def, def_linkable) x2 -> - if true then (Nat_big_num.of_int idx1, def, def_linkable) :: x2 else x2) - all_defs x2 - )) linkables) - in - List.fold_left (fun accum -> (fun deflist -> - List.fold_left (fun m -> (fun (def_idx, def, def_linkable) -> add_definition_to_map (def_idx, def, def_linkable) m)) accum deflist - )) (Pmap.empty compare) list_of_deflists) - -type binding_oracle = - linkable_list - -> (string, ( (Nat_big_num.num * symbol_definition * linkable_item)list)) Pmap.map - -> (Nat_big_num.num * symbol_reference * linkable_item) - -> (Nat_big_num.num * symbol_definition * linkable_item)option - -(*val resolve_one_reference_default : forall 'abifeature. abi 'abifeature -> binding_oracle*) -let resolve_one_reference_default a linkables defmap ref_idx_and_ref_and_linkable:(Nat_big_num.num*symbol_definition*(linkable_object*(string*input_blob*(Command_line.input_unit*(origin_coord)list))*input_options))option= - (let (ref_idx, ref1, ref_linkable) = ref_idx_and_ref_and_linkable - in - (* Get the list of all definitions whose name matches. - * Don't match empty names. - * How should we handle common symbols here? - * A common symbol is a potential definition, so it goes in the def list. - *) - let (defs_and_linkables_with_matching_name : (Nat_big_num.num * symbol_definition * linkable_item) list) - = ((match Pmap.lookup ref1.ref_symname defmap with - Some (l : ( (Nat_big_num.num * symbol_definition * linkable_item)list)) -> l - | None -> [] - )) - in - (* Filter the list by eligibility rules. - * Normally, - * - * - any .o file can supply any other .o file on the command line - * - any .a file supplies only files appearing to its left - * i.e. "it is searched once for definitions" - * - does a .o file supply a .a file? to both its right and left? Experimentally, YES. - * - * So the restrictions are - * - archives may not supply weak references - * - archives may only supply to the left, or to themselves, or to objects in the same group - *) - let (ref_obj, (ref_fname, ref_blob, (ref_u, ref_coords)), ref_options) = ref_linkable - in - let ref_is_weak = (Nat_big_num.equal (get_elf64_symbol_binding ref1.ref_syment) stb_weak) - in - let def_is_eligible = (fun (def_idx, def, def_linkable) -> - let ref_is_unnamed = (ref1.ref_symname = "") - in - let ref_is_to_defined_or_common_symbol = ( not (Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string ref1.ref_syment.elf64_st_shndx)) stn_undef)) - in - let def_sym_is_ref_sym = ( Nat_big_num.equal ref_idx def_idx && (Nat_big_num.equal ref1.ref_sym_scn def.def_sym_scn - && Nat_big_num.equal ref1.ref_sym_idx def.def_sym_idx)) - in - let (def_obj, (def_fname, def_blob, def_origin), def_options) = def_linkable - in - let (def_u, def_coords) = def_origin - in - let (def_in_group, def_in_archive) = ((match def_coords with - InArchive(aid, aidx, _, _) :: InGroup(gid1, gidx) :: [_] -> (Some gid1, Some aid) - | InArchive(aid, aidx, _, _) :: [_] -> (None, Some aid) - | InGroup(gid1, gidx) :: [_] -> (Some gid1, None) - | [_] -> (None, None) - | _ -> failwith "internal error: didn't understand origin coordinates of definition" - )) - in - let ref_is_leftmore = (Nat_big_num.less_equal ref_idx def_idx) - in - (* For simplicity we include the case of "same archive" in "in group with". *) - let ref_is_in_group_with_def = ((match def_in_group with - None -> false - | Some def_gid -> - (match ref_coords with - InArchive(_, _, _, _) :: InGroup(gid1, _) :: [_] -> Nat_big_num.equal gid1 def_gid - | InGroup(gid1, _) :: [_] -> Nat_big_num.equal gid1 def_gid - | _ -> false - ) - )) - in - (* but maybe same archive? *) - (* DEBUGGING: print some stuff out if we care about this symbol. *)let _ = - (if (ref_fname = "backtrace.o") && (def.def_symname = "_Unwind_GetCFA") then - (*Missing_pervasives.errln ("saw backtrace.o referencing _Unwind_GetCFA; coords are " - ^ "def: " ^ (show def_coords) ^ ", ref: " ^ (show ref_coords) ^ "; ref_is_in_group_with_def: " - ^ (show ref_is_in_group_with_def) ^ "; def_in_group: " ^ (show def_in_group))*) - () - else ()) - in - let ref_and_def_are_in_same_archive = ((match (def_coords, ref_coords) with - (InArchive(x1, _, _, _) :: _, InArchive(x2, _, _, _) :: _) -> Nat_big_num.equal x1 x2 - | _ -> false - )) - in - let def_is_in_archive = ((match def_in_archive with - Some _ -> true - | None -> false - )) - in - if ref_is_to_defined_or_common_symbol then def_sym_is_ref_sym - else - if ref_is_unnamed then false - else - if def_is_in_archive - then - (* Weak references *can* be resolved to archive members... - * if the reference itself is also in the archive. *) - ((not ref_is_weak) || ref_and_def_are_in_same_archive) - && ( - ref_is_leftmore - || (ref_and_def_are_in_same_archive - || ref_is_in_group_with_def) - ) - else - true - ) - in - let eligible_defs = (List.filter def_is_eligible defs_and_linkables_with_matching_name) - in - let (maybe_target_def_idx, maybe_target_def, maybe_target_def_linkable) = ((match eligible_defs with - [] -> (None, None, None) - | [(def_idx, def, def_linkable)] -> (Some def_idx, Some def, Some def_linkable) - | (d_idx, d, d_l) :: more_pairs -> - (* Break ties by - * - putting defs in relocs (or --defsym or linker script, a.k.a. command line) ahead of defs in archives; - * - else whichever definition appeared first in the left-to-right order. - *) - let sorted = (insertSortBy (fun (d_idx1, d1, (_, (_, _, (_, d_l1_coords)), _)) -> (fun (d_idx2, d2, (_, (_, _, (_, d_l2_coords)), _)) -> - (match (d_l1_coords, d_l2_coords) with - (InCommandLine(_) :: _, InCommandLine(_) :: _) -> Nat_big_num.less d_idx1 d_idx2 - | (InCommandLine(_) :: _, _) -> (* command-line wins *) true - | (_, InCommandLine(_) :: _) -> (* command-line wins *) false - | (_, _) -> Nat_big_num.less d_idx1 d_idx2 - ))) eligible_defs) - in - (match sorted with - (first_d_idx, first_d, first_d_l) :: _ -> (Some first_d_idx, Some first_d, Some first_d_l) - | _ -> failwith "impossible: sorted list is shorter than original" - ) - )) - in - let refstr = ("`" - ^ (ref1.ref_symname ^ ("' (" ^ - ((if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string ref1.ref_syment.elf64_st_shndx)) shn_undef then "UND" else "defined") ^ - (" symbol at index " ^ ((Nat_big_num.to_string ref1.ref_sym_idx) ^ (" in symtab " - ^ ((Nat_big_num.to_string ref1.ref_sym_scn) ^ (" in " ^ (ref_fname - ^ ")")))))))))) - in - (*let _ = Missing_pervasives.errs ("Bound a reference from " ^ refstr ^ " to ") - in*) - (match (maybe_target_def_idx, maybe_target_def, maybe_target_def_linkable) with - (Some target_def_idx, Some target_def, Some target_def_linkable) -> - (*let _ = Missing_pervasives.errln (" a definition in "^ (show (target_def_linkable))) - in*) - Some(target_def_idx, target_def, target_def_linkable) - | (None, None, None) -> - (*let _ = Missing_pervasives.errln " no definition" - in*) - if ref_is_weak (* || a.symbol_is_generated_by_linker ref.ref_symname *) then None - else (* failwith ("undefined symbol: " ^ refstr) *) None - (* FIXME: do a check, *after* the linker script has been interpreted, - * that all remaining undefined symbols are permitted by the ABI/policy. *) - | _ -> failwith "impossible: non-matching maybes for target_def_idx and target_def" - )) - -(*val resolve_all : - linkable_list - -> Map.map string (list (natural * symbol_definition * linkable_item)) (* all definitions *) - -> binding_oracle - -> list (natural * symbol_reference * linkable_item) - -> list ((natural * symbol_reference * linkable_item) * maybe (natural * symbol_definition * linkable_item))*) -let resolve_all linkables all_defs oracle refs:((Nat_big_num.num*symbol_reference*(linkable_object*input_item*input_options))*(Nat_big_num.num*symbol_definition*linkable_item)option)list= - (Lem_list.map (fun (ref_idx, ref1, ref_linkable) -> ((ref_idx, ref1, ref_linkable), (oracle linkables all_defs (ref_idx, ref1, ref_linkable)))) refs) - -(* To accumulate which inputs are needed, we work with a list of undefineds, starting with those - * in the forced-output objects. We then iteratively build a list of all needed symbol definitions, - * pulling in the objects that contain them, until we reach a fixed point. *) -(*val resolve_undefs_in_one_object : - linkable_list - -> Map.map string (list (natural * symbol_definition * linkable_item)) (* all definitions *) - -> binding_oracle - -> natural - -> list ((natural * symbol_reference * linkable_item) * maybe (natural * symbol_definition * linkable_item))*) -let resolve_undefs_in_one_object linkables all_defs oracle idx1:((Nat_big_num.num*symbol_reference*linkable_item)*(Nat_big_num.num*symbol_definition*linkable_item)option)list= -( - (* Get this object's list of references *)let item = ((match Lem_list.list_index linkables (Nat_big_num.to_int idx1) with - Some it -> it - | None -> failwith "impossible: linkable not in list of linkables" - )) - in - let img2 = (image_of_linkable_item item) - in - let (all_ref_tags, all_ref_ranges) - = (List.split (Multimap.lookupBy0 - (Memory_image_orderings.instance_Basic_classes_Ord_Memory_image_range_tag_dict - Abis.instance_Basic_classes_Ord_Abis_any_abi_feature_dict) (instance_Basic_classes_Ord_Maybe_maybe_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_string_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_Num_natural_dict - instance_Basic_classes_Ord_Num_natural_dict))) instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) (Memory_image_orderings.tagEquiv - Abis.instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict) (SymbolRef(null_symbol_reference_and_reloc_site)) img2.by_tag)) - in - (* By using SymbolRef, we are extracting and binding each relocation site individually. - * since there might be more than one relocation site referencing the same symbol name, - * in a given object. - * - * We are also binding SymbolRefs that have no relocation, which occur when there's - * an UND symbol which is not actually used by a relocation site, but is nevertheless - * in need of being resolved. - * - * We don't (for the moment) want to make different decisions for different reloc sites - * in the same object referencing the same symbol. So we dedup from a list to a set. - *) - let all_refs = (Pset.from_list compare (Lem_list.map (fun tag -> (match tag with - SymbolRef(r) -> r.ref - | _ -> failwith "matched tag not a relocation site" - )) all_ref_tags)) - in - let ref_triples = (let x2 =(Pset.from_list (tripleCompare Nat_big_num.compare compare (tripleCompare compare (tripleCompare compare compare (pairCompare compare (lexicographic_compare compare))) compare)) - []) in Pset.fold - (fun ref1 x2 -> if true then Pset.add (idx1, ref1, item) x2 else x2) - all_refs x2) - in - (*let _ = Missing_pervasives.errln ("object " ^ (show item) ^ " has " ^ - (show (Set.size ref_triples)) ^ " reloc references (symname, sym_scn, sym_idx, st_shndx) (" ^ - (show (List.map (fun x -> ("\"" ^ x.ref_symname ^ "\"", x.ref_sym_scn, x.ref_sym_idx, natural_of_elf64_half x.ref_syment.elf64_st_shndx)) (Set_extra.toList all_refs))) ^ ")") - in*) - let und_ref_triples = (let x2 =(Pset.from_list (tripleCompare Nat_big_num.compare compare (tripleCompare compare (tripleCompare compare compare (pairCompare compare (lexicographic_compare compare))) compare)) - []) in Pset.fold - (fun(idx1, ref1, ref_item) x2 -> - if Nat_big_num.equal - (Nat_big_num.of_string - (Uint32.to_string ref1.ref_syment.elf64_st_shndx)) shn_undef then - Pset.add (idx1, ref1, ref_item) x2 else x2) ref_triples x2) - in - (*let _ = Missing_pervasives.errln ("... of which " ^ - (show (Set.size und_ref_triples)) ^ " are to undefined symbols: (symname, sym_scn, sym_idx, st_shndx) (" ^ - (show (List.map (fun (idx, x, _) -> ("\"" ^ x.ref_symname ^ "\"", x.ref_sym_scn, x.ref_sym_idx, natural_of_elf64_half x.ref_syment.elf64_st_shndx)) (Set_extra.toList und_ref_triples))) ^ ")") - in*) - resolve_all linkables all_defs oracle (Pset.elements ref_triples)) - -(*val accumulate_bindings_bf : forall 'abifeature. - abi 'abifeature - -> linkable_list - -> Map.map string (list (natural * symbol_definition * linkable_item)) (* all definitions *) - -> set natural (* inputs fully-bound so far *) - -> list natural (* ordered list of inputs to bind next *) - -> list ((natural * symbol_reference * linkable_item) * maybe (natural * symbol_definition * linkable_item)) (* bindings made so far *) - -> list ((natural * symbol_reference * linkable_item) * maybe (natural * symbol_definition * linkable_item))*) (* all accumulated bindings bindings *) -let rec accumulate_bindings_bf a linkables all_defs fully_bound to_bind bindings_accum:((Nat_big_num.num*symbol_reference*linkable_item)*(Nat_big_num.num*symbol_definition*linkable_item)option)list= -( - (* This is like foldl, except that each stage - * can add stuff to the work list *)(match to_bind with - [] -> bindings_accum (* termination *) - | l_idx :: more_idx -> - (* Get the new bindings for this object *) - let new_bindings = (resolve_undefs_in_one_object - linkables - all_defs - (resolve_one_reference_default a) - l_idx) - in - let new_fully_bound = (Pset.add l_idx fully_bound) - in - (* Which of the new bindings are to objects - * not yet fully bound or not yet in the to-bind list? *) - let new_bindings_def_idx = (list_concat_map (fun (ref1, maybe_def_and_idx_and_linkable) -> - (match maybe_def_and_idx_and_linkable with - Some (def_idx, def, def_linkable) -> [def_idx] - | None -> [] - ) - ) new_bindings) - in - let new_bindings_def_idx_set = (Pset.from_list Nat_big_num.compare new_bindings_def_idx) - in - let included_linkables_idx = (Pset.(union) fully_bound ((Pset.from_list Nat_big_num.compare to_bind))) - in - let new_l_idx = (Pset.diff new_bindings_def_idx_set included_linkables_idx) - in - let new_l_idx_list = (Pset.elements new_l_idx) - in - (*let _ = Missing_pervasives.errln ( - if List.null new_l_idx_list - then - "Fully bound references in " ^ (show (List.index linkables (natFromNatural l_idx))) - ^ " using only already-included linkables (" - ^ (show (List.map (fun i -> List.index linkables (natFromNatural i)) (Set_extra.toList included_linkables_idx))) - else - "Including additional linkables " - ^ (show (List.mapMaybe (fun i -> List.index linkables (natFromNatural i)) new_l_idx_list)) - ) - in*) - accumulate_bindings_bf - a - linkables - all_defs - new_fully_bound - ( List.rev_append (List.rev more_idx) new_l_idx_list) - ( List.rev_append (List.rev bindings_accum) new_bindings) - )) - -(* We need a generalised kind of depth-first search in which there are multiple start points. - * Also, we always work one object at a time, not one edge at a time; when we pull in an object, - * we resolve *all* the references therein. - *) -(*val accumulate_bindings_objectwise_df : forall 'abifeature. - abi 'abifeature - -> linkable_list - -> Map.map string (list (natural * symbol_definition * linkable_item)) (* all definitions *) - - -> list ((natural * symbol_reference * linkable_item) * maybe (natural * symbol_definition * linkable_item)) (* bindings made so far *) - -> set natural (* inputs fully-bound so far -- these are "black" *) - -> list natural (* inputs scheduled for binding -- these include - any "grey" (in-progress) nodes *and* - any nodes that we have committed to exploring - (the "start nodes"). - Because we're depth-first, we prepend our adjacent - nodes to this list, making them grey, then we - recurse by taking from the head. We must always - filter out the prepended nodes from the existing list, - to ensure we don't recurse infinitely. *) - -> list ((natural * symbol_reference * linkable_item) * maybe (natural * symbol_definition * linkable_item))*) (* all accumulated bindings bindings *) -let rec accumulate_bindings_objectwise_df a linkables all_defs bindings_accum blacks greys:((Nat_big_num.num*symbol_reference*linkable_item)*(Nat_big_num.num*symbol_definition*linkable_item)option)list= - ((match greys with - [] -> bindings_accum (* termination *) - | l_idx :: more_idx -> - (* Get the new bindings for this object *) - let new_bindings = (resolve_undefs_in_one_object - linkables - all_defs - (resolve_one_reference_default a) - l_idx) - in - (* We pull in the whole object at a time ("objectwise"), so by definition, - * we have created bindings for everything in this object; it's now black. *) - let new_fully_bound = (Pset.add l_idx blacks) - in - (* Which of the new bindings are to objects - * not yet fully bound or not yet in the to-bind list? *) - let new_bindings_def_idx = (list_concat_map (fun (ref1, maybe_def_and_idx_and_linkable) -> - (match maybe_def_and_idx_and_linkable with - Some (def_idx, def, def_linkable) -> [def_idx] - | None -> [] - ) - ) new_bindings) - in - let new_bindings_def_idx_set = (Pset.from_list Nat_big_num.compare new_bindings_def_idx) - in - (* this is the "black or grey" set. *) - let included_linkables_idx = (Pset.(union) blacks ((Pset.from_list Nat_big_num.compare greys))) - in - (* these are the white ones that we're adjacent to *) - let new_l_idx = (Pset.diff new_bindings_def_idx_set included_linkables_idx) - in - let new_l_idx_list = (Pset.elements new_l_idx) - in - (* What is the new grey-alike list? (This is the list we tail-recurse down.) - * It's - * - the existing grey-alike list - * - with any new (were-white) objects prepended - * - ... and filtered to *remove* these from the existing list (avoid duplication). - *) - let new_grey_list = (List.rev_append (List.rev new_l_idx_list) (List.filter (fun x -> not ( Pset.mem x new_l_idx)) more_idx)) - in - (* whether or not we've not uncovered any new white nodes, we tail-recurse *) - (*let _ = (if List.null new_l_idx_list then - Missing_pervasives.errln ("Fully bound references in " ^ (show (List.index linkables (natFromNatural l_idx))) - ^ " using only already-included linkables (" - ^ (show (List.map (fun i -> List.index linkables (natFromNatural i)) (Set_extra.toList included_linkables_idx))) - ) else Missing_pervasives.errln ("Including additional linkables " - ^ (show (List.mapMaybe (fun i -> List.index linkables (natFromNatural i)) new_l_idx_list)))) - in*) - accumulate_bindings_objectwise_df - a - linkables - all_defs - ( List.rev_append (List.rev bindings_accum) new_bindings) - (new_fully_bound : Nat_big_num.num Pset.set) - (new_grey_list : Nat_big_num.num list) - )) - -(* Rather than recursively expanding the link by searching for definitions of undefs, - * the GNU linker works by recursing/looping along the list of *linkables*, testing whether - * any of the defs satisfies a currently-undef'd thing. On adding a new undef'd thing, - * we re-search only from the current archive, not from the beginning (i.e. the - * "def_is_leftmore or def_in_same_archive" logic). - * - * Why is this not the same as depth-first? One example is if we pull in a new object - * which happens to have two undefs: one satisfied by the *first* element in the current archive, - * and one satisfied by the last. - * - * In the GNU algorithm, we'll pull in the first archive element immediately afterwards, because - * we'll re-traverse the archive and find it's needed. - * - * In the depth-first algorithm, it depends entirely on the ordering of the new bindings, i.e. - * the symtab ordering of the two undefs. If the later-in-archive def was bound *first*, we'll - * recurse down *that* object's dependencies first. - * - * So if we sort the new grey list - * so that bindings formed in order of *current archive def pos*, - * will we get the same behaviour? - * We can't really do this, because we have no "current archive". - * - * Need to rewrite the algorithm to fold along the list of linkables. - *) diff --git a/lib/ocaml_rts/linksem/linker_script.ml b/lib/ocaml_rts/linksem/linker_script.ml deleted file mode 100644 index 535d9037..00000000 --- a/lib/ocaml_rts/linksem/linker_script.ml +++ /dev/null @@ -1,2783 +0,0 @@ -(*Generated by Lem from linker_script.lem.*) -open Lem_basic_classes -open Lem_function -open Lem_string -open Lem_tuple -open Lem_bool -open Lem_list -open Lem_sorting -open Lem_num -open Lem_maybe -open Lem_assert_extra -open Lem_set -(*import Map*) - -open Byte_sequence -open Default_printing -open Error -open Missing_pervasives -open Show - -open Elf_header -open Elf_file -open Elf_interpreted_section - -open Abis -open Command_line -open Input_list -open Linkable_list -open Memory_image -open Elf_memory_image (* HMM -- ideally we'd be ELF-agnostic in this file. - But Abstract_abi is now merged into Elf_memory_image, so never mind. *) -open Elf_memory_image_of_elf64_file -open Elf_relocation -open Elf_symbol_table -open Elf_section_header_table -open Elf_types_native_uint -open Memory_image_orderings - -(* We model two kinds of linker script: "implicit scripts", which are supplied - * on the command line as input objects, and "control scripts" of which there - * is exactly one per link job. The abstract syntax of each script comes from the - * same grammar. - * - * We define the control script as a bunch of functions, to allow for - * link jobs where we don't have an AST and the script behaviour is hard-coded. - *) - -(* Input sections come from individual (relocatable) ELF files. - * The name of this file is important! - * - * Each input "section" is always an identified section or common symbol - * *within* some ELF memory image. *) - -type input_section_rec = { - idx : Nat_big_num.num (* linkable idx *) -; fname : string -; img : elf_memory_image -; shndx : Nat_big_num.num -; secname: string -; isec : elf64_interpreted_section -} - -type input_spec - = Common of (Nat_big_num.num * string * elf_memory_image * symbol_definition) (* string is symbol name -- must be a COMMON symbol *) - | InputSection of input_section_rec - -(* A control script defines - * - output sections - * - a mapping from output sections to (ordered) input sections - * - extra symbols - * - output format etc. (skip this for now) - *) - -(* We will have to deal with merging etc. at some point, somewhere - * (maybe here, maybe not); for now we just produce an ordered list - * of sections. - *) - -(* We can't model linker scripts as plain Lem functions without writing - * them to a very different structure than that of scripts. The reason is that - * certain features of the script language necessitate multiple passes - * over the script structure. For example, to figure out how big an - * output section is, hence where to begin the next section, you need to - * know which of the input sections are marked for KEEP. For that, you need - * a def-use graph over input sections. But for that, you also need to account - * for *all* symbol definitions, and the script itself is allowed to add new - * ones (right in among its input sections). So we have to do one pass to - * enumerate the symbol additions, and another pass to eliminate sections - * that we don't want to KEEP. - * - * Other gotchas include: - * - * - symbol provision and address advancement can occur in among the input - * section queries, but also outside any output section. - * - * - semantics of DATA_SEGMENT_ALIGN depend on future script contents - * - * - ONLY_IF_RO and ONLY_IF_RW are tricky: need to evaluate the input section - * queries - * - * - semantics of empty sections are subtle (". = ." will force an empty section - * to be emitted, but ". = . + 0" will not do so). - * - * Our approach is to define an interpreter for (at present) most of the script - * language. - *) - -type symbol_def_policy = AlwaysDefine - | ProvideIfUsed - -type input_selector = input_spec list -> input_spec list - -type address_expr = Memory_image.expr - -type output_guard = AlwaysOutput - | OnlyIfRo - | OnlyIfRw - -type symbol_spec = (Nat_big_num.num * Uint32.uint32 * Uint32.uint32) (* size, info, other *) - -type retain_policy - = DefaultKeep - | KeepEvenWhenGC - -type address_expr_fn_ref = Nat_big_num.num -type 'a address_expr_fn_map = (address_expr_fn_ref, (Nat_big_num.num -> 'a -> Nat_big_num.num)) Pmap.map -(* 'a = allocated_sections_map *) - -type output_section_composition_element - = IncludeInputSection of (retain_policy * input_section_rec) - | IncludeCommonSymbol of (retain_policy * string (* file *) * Nat_big_num.num (* linkable_idx *) * symbol_definition * elf_memory_image) - | Hole of address_expr_fn (* compute the next addr to continue layout at *) - | ProvideSymbol of (symbol_def_policy * string * symbol_spec) -and -sort_policy - = DefaultSort (* Use command line sort option, else "seen" order *) - | SeenOrder (* Always use "seen" order *) - | ByName - | ByNameThenAlignment - | ByAlignment - | ByAlignmentThenName - | ByInitPriority -and -(* This mirrors the OutputSection constructor, except that the script elements have become - * output_section_composition_elements, and we might store the size here. *) -output_section_spec = - OutputSectionSpec of (output_guard * Nat_big_num.num option * string * ( output_section_composition_element list)) -and -allocated_sections_map = - AllocatedSectionsMap of (string, (output_section_spec (* OutputSection element idx *) * Nat_big_num.num)) Pmap.map -and -address_expr_fn - = AddressExprFn of address_expr_fn_ref - -type script_element = - DefineSymbol of (symbol_def_policy * string * symbol_spec) -| AdvanceAddress of address_expr_fn -| MarkAndAlignDataSegment of (Nat_big_num.num * Nat_big_num.num) (* maxpagesize, commonpagesize *) -| MarkDataSegmentEnd -| MarkDataSegmentRelroEnd (*of (allocated_sections_map -> (natural * (natural -> natural))) DPM: commented out because of positivity constrains in Isabelle *) -| OutputSection of (output_guard * ( (* address_expr *) address_expr_fn option) * string * script_element list) -| DiscardInput of input_selector - (* Input queries can only occur within an output section. - Output sections may not nest within other output sections. - (Ideally we would use something like polymorphic variants to encode this.) - *) -| InputQuery of (retain_policy * sort_policy * input_selector) - -(* A linker control script is a function from inputs to output elements. - * We can define them in syntax (using an interpreter) - * or in Lem directly (as functions). *) -type linker_control_script = script_element list -type labelled_linker_control_script = (script_element * Nat_big_num.num) list - -(*val all_suffixes : list char -> list (list char)*) -let rec all_suffixes chars:((char)list)list= - ((match chars with - [] -> [[]] - | c :: morecs -> chars :: (all_suffixes morecs) - )) - -(*val glob_match : list char -> list char -> bool*) -let rec glob_match pat str:bool= - ((match (pat, str) with - ([], []) -> true - | ('?':: morepat, _ :: morestr) -> glob_match morepat morestr - | ('*':: morepat, _) -> - (* if any suffix of the remaining string matches - * the remaining pattern, we've matched the pattern - * from '*' onwards. *) - let or_suffix_match = (fun matched -> (fun newlist -> - matched || glob_match morepat newlist)) - in - List.fold_left (or_suffix_match) false (all_suffixes str) - | (patc :: morepat, c :: morestr) -> (patc = c) && glob_match morepat morestr - | ([], _) -> (* ran out of pattern *) false - | (_, []) -> (* ran out of str *) false - )) - -(*val default_symbol_spec : symbol_spec*) -let default_symbol_spec:Nat_big_num.num*Uint32.uint32*Uint32.uint32= (Nat_big_num.of_int 0, Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0)), Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) -(*val hidden_symbol_spec : symbol_spec*) -let hidden_symbol_spec:Nat_big_num.num*Uint32.uint32*Uint32.uint32= (Nat_big_num.of_int 0, Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0)), Uint32.of_string (Nat_big_num.to_string stv_hidden)) - -(* These Lem functions replicate linker script functions or builtin behaviours. *) - -(*val only_sections : input_selector*) -let only_sections inputs:(input_spec)list= (Lem_list.mapMaybe - (fun i -> (match i with - | InputSection(_) -> Some(i) - | _ -> None - )) inputs) - -(*val filter_and_concat : (input_spec -> bool) -> input_selector*) (* a.k.a. list input_spec -> list input_spec *) -let filter_and_concat p inputs:(input_spec)list= (List.filter p inputs) - -(*val name_matches : string -> input_spec -> bool*) -let name_matches pat input:bool= - ((match input with - InputSection(inp) -> - (*let _ = errln ("Does section name `" ^ inp.secname ^ "' match glob pattern `" ^ pat ^ "'? ") in - let result = *)glob_match (Xstring.explode pat) (Xstring.explode inp.secname) (*in - let _ = errln (if result then "yes" else "no") - in result*) - | _ -> false - )) - -(*val file_matches : string -> input_spec -> bool*) -let file_matches pat input:bool= - ((match input with - InputSection(inp) -> glob_match (Xstring.explode pat) (Xstring.explode inp.fname) - | _ -> false - )) - -let compareInputSpecByNameThenAlignment i1 i2:int= - (let toPair = (fun is -> ((match is with - Common(idx1, fname1, img2, def) -> ("COMMON" (* FIXME: is this right? *), Ml_bindings.nat_big_num_of_uint64 def.def_syment.elf64_st_value) - | InputSection(isrec) -> (isrec.isec.elf64_section_name_as_string, isrec.isec.elf64_section_align) - ))) - in (pairCompare compare Nat_big_num.compare (toPair i1) (toPair i2))) - -let compareInputSpecByAlignment i1 i2:int= - (let toNatural = (fun is -> ((match is with - Common(idx1, fname1, img2, def) -> Ml_bindings.nat_big_num_of_uint64 def.def_syment.elf64_st_value - | InputSection(isrec) -> isrec.isec.elf64_section_align - ))) - in Nat_big_num.compare (toNatural i1) (toNatural i2)) - -let compareInputSpecByName i1 i2:int= - (let toString = (fun is -> ((match is with - Common(idx1, fname1, img2, def) -> "COMMON" - | InputSection(isrec) -> isrec.isec.elf64_section_name_as_string - ))) - in compare (toString i1) (toString i2)) - -let compareInputSpecByAlignmentThenName i1 i2:int= - (let toPair = (fun is -> ((match is with - Common(idx1, fname1, img2, def) -> (Ml_bindings.nat_big_num_of_uint64 def.def_syment.elf64_st_value, - "COMMON" (* FIXME: is this right? *)) - | InputSection(isrec) -> (isrec.isec.elf64_section_align, isrec.isec.elf64_section_name_as_string) - ))) - in (pairCompare Nat_big_num.compare compare (toPair i1) (toPair i2))) - -let compareInputSpecByInitPriority i1 i2:int= 0 (* FIXME *) - -(* DATA_SEGMENT_ALIGN is defined by two formulae - * (over pos and commonpagesize/maxpagesize) - * "... depending on whether the latter uses fewer COMMONPAGESIZE sized - pages for the data segment (area between the result of this - expression and `DATA_SEGMENT_END') than the former or not. If the - latter form is used, it means COMMONPAGESIZE bytes of runtime - memory will be saved at the expense of up to COMMONPAGESIZE wasted - bytes in the on-disk file." - - So the amount of padding that gets inserted here depends on the location - of something that comes *later*, namely DATA_SEGMENT_END. - So, we can't model it as a function of the current position. - Instead, we add MarkDataSegmentEnd and friends - to the script_element ADT. - *) - -let has_writability:'a ->input_spec ->bool= (fun writable -> (fun input_sec -> ( - (match input_sec with - Common(_, _, _, _) - -> (* all common symbols are potentially writable *) true - | InputSection(inp) - -> let (flags : Nat_big_num.num) = ((match elf_memory_image_section_by_index inp.shndx inp.img with - Some x -> x.elf64_section_flags - | None -> failwith ("impossible: no such section" (*(index " ^ (show inp.shndx) ^ ")""*)) - )) - in - flag_is_set shf_write flags - ) -))) - -(* LARGE_COMMON seems to have been defined in this patch set: - https://sourceware.org/ml/binutils/2005-07/txt00014.txt - and at the time was "only for x86-64". It seems to be analogous - to ".lbss", i.e. "large bss". libbfd defines SHF_X86_64_LARGE. - The best comment seems to be in llvm's Support/ELF.h: - -0814 // If an object file section does not have this flag set, then it may not hold -0815 // more than 2GB and can be freely referred to in objects using smaller code -0816 // models. Otherwise, only objects using larger code models can refer to them. -0817 // For example, a medium code model object can refer to data in a section that -0818 // sets this flag besides being able to refer to data in a section that does -0819 // not set it; likewise, a small code model object can refer only to code in a -0820 // section that does not set this flag. - - *) - -(*val address_zero : natural -> address_expr_fn_map allocated_sections_map -> - (natural * address_expr_fn_map allocated_sections_map * address_expr_fn)*) -let address_zero fresh alloc_map:Nat_big_num.num*((Nat_big_num.num),(Nat_big_num.num ->allocated_sections_map ->Nat_big_num.num))Pmap.map*address_expr_fn= - (let alloc_map' = (Pmap.add fresh (fun pos -> (fun secs ->Nat_big_num.of_int 0)) alloc_map) in - let fresh' = (Nat_big_num.add(Nat_big_num.of_int 1) fresh) in - (fresh', alloc_map', AddressExprFn fresh)) - -(* -val output_sec_composition_size : list output_section_composition_element -> natural -let output_sec_composition_size comp = List.foldl (+) 0 (List.map size_of_output_section_composition_element comp) -*) -(*val do_output_section_layout_starting_at_addr : natural -> allocated_sections_map -> list output_section_composition_element -> (natural * list natural)*) -let do_output_section_layout_starting_at_addr start_addr (AllocatedSectionsMap secs) comps:Nat_big_num.num*(Nat_big_num.num)list= -( - (* map out where we plumb in each section, accounting for their alignment *)List.fold_left (fun (next_free_addr, addr_list) -> (fun comp_el -> (match comp_el with - IncludeInputSection(retain_pol, irec (* fname, linkable_idx, shndx, isec, img *)) -> - let aligned_next_free = (align_up_to irec.isec.elf64_section_align next_free_addr) - in - (*let _ = errln ("Aligned start address up to 0x" ^ hex_string_of_natural aligned_next_free ^ - " (align 0x" ^ (hex_string_of_natural irec.isec.elf64_section_align) ^ - ") for included output section `" ^ - irec.isec.elf64_section_name_as_string ^ "' from file `" ^ irec.fname ^ "'") - in*) - ( Nat_big_num.add aligned_next_free irec.isec.elf64_section_size, List.rev_append (List.rev addr_list) [aligned_next_free]) - | IncludeCommonSymbol(retain_pol, fname1, linkable_idx, def, img2) -> - let aligned_next_free = (align_up_to (Ml_bindings.nat_big_num_of_uint64 def.def_syment.elf64_st_value) next_free_addr) - in - ( Nat_big_num.add aligned_next_free (Ml_bindings.nat_big_num_of_uint64 def.def_syment.elf64_st_size), List.rev_append (List.rev addr_list) [aligned_next_free]) - (*| Hole(AddressExprFn f) -> (f next_free_addr secs, addr_list ++ [next_free_addr])*) - | ProvideSymbol(pol, name1, spec) -> (next_free_addr, List.rev_append (List.rev addr_list) [next_free_addr]) - ) - )) (start_addr, []) comps) - -(*val output_sec_composition_size_given_start_addr : natural -> allocated_sections_map -> list output_section_composition_element -> natural*) -let output_sec_composition_size_given_start_addr start_addr secs comp:Nat_big_num.num= - (let (end_addr, comp_addrs) = (do_output_section_layout_starting_at_addr start_addr secs comp) - in Nat_big_num.sub_nat - end_addr start_addr) - -(*val sizeof : string -> allocated_sections_map -> natural*) -let sizeof secname1 (AllocatedSectionsMap secs):Nat_big_num.num= - ((match Pmap.lookup secname1 secs with - Some(OutputSectionSpec (_, maybe_addr, _, comp), _) -> (match maybe_addr with - Some addr -> output_sec_composition_size_given_start_addr addr (AllocatedSectionsMap secs) comp - | None -> failwith ("error: sizeof applied to section without defined start address") - ) - | None -> failwith ("error: sizeof applied to non-existent section name " ^ secname1) - )) - -(*val alignof_output_section_composition_element : output_section_composition_element -> natural*) -let alignof_output_section_composition_element comp:Nat_big_num.num= - ((match comp with - IncludeInputSection(_, irec) -> irec.isec.elf64_section_align - | IncludeCommonSymbol(_, _, _, def, _) -> Ml_bindings.nat_big_num_of_uint64 def.def_syment.elf64_st_value - | _ ->Nat_big_num.of_int 1 (* CHECK *) - )) - -(*val alignof_output_section : list output_section_composition_element -> natural*) -let alignof_output_section comps:Nat_big_num.num= - (let aligns = (Lem_list.map alignof_output_section_composition_element comps) - in - List.fold_left (fun acc_lcm -> fun next -> lcm acc_lcm next)(Nat_big_num.of_int 1) aligns) - -(*val default_linker_control_script : natural -> address_expr_fn_map allocated_sections_map -> - abi any_abi_feature -> maybe natural -> maybe natural -> maybe natural -> - natural -> (natural * address_expr_fn_map allocated_sections_map * linker_control_script)*) -let default_linker_control_script fresh alloc_map a user_text_segment_start user_data_segment_start user_rodata_segment_start elf_headers_size:Nat_big_num.num*((Nat_big_num.num),(Nat_big_num.num ->allocated_sections_map ->Nat_big_num.num))Pmap.map*(script_element)list= - (let segment_start name1 default= ((match name1 with - "ldata-segment" -> (match user_data_segment_start with - None -> default - | Some addr -> (* fun _ -> *) addr - ) - | "text-segment" -> (match user_text_segment_start with - None -> default - | Some addr -> (* fun _ -> *) addr - ) - )) - in - let is_large_common = (fun inp -> (* FIXME: treat large commons separately *) false - ) - in - let is_common = (fun isec1 -> (match isec1 with - Common(idx1, fname1, img2, def) -> (*let _ = errln ("Common or large-common symbol: " ^ def.def_symname) in *) - not (is_large_common isec1) - | _ -> false - )) - in - let alloc_fn1 = (fun _ -> (fun _ -> Nat_big_num.add (segment_start "text-segment" ( Nat_big_num.mul(Nat_big_num.of_int 4)(Nat_big_num.of_int 1048576))) elf_headers_size)) in - let alloc_fn1_ref = fresh in - let alloc_map = (Pmap.add alloc_fn1_ref alloc_fn1 alloc_map) in - let fresh = (Nat_big_num.add(Nat_big_num.of_int 1) fresh) in - let alloc_fn2 = (fun addr -> (fun _ -> Nat_big_num.sub_nat - (* (align_up_to a.maxpagesize addr) - (natural_land (a.maxpagesize - addr) (a.maxpagesize - 1)) *) - (* - FIXME: understand the intention of this assignment. - Evaluating a simple example of this (from true-static-uClibc) - - (ALIGN (0x200000) - ((0x200000 - .) & 0x1fffff)) - - starting from 0x00000000004017dc - means - 0x600000 - ((0x200000 - 0x4017dc) & 0x1fffff) - i.e. - 0x600000 - (((-0x2017dc)) & 0x1fffff) - i.e. - 0x600000 - ( -0x2017dc - & 0x1fffff ) - - which really does come to (according to bash) 0x4017dc - i.e. we subtract 0x1fe824 from 0x600000 - and end up back where we started. - - What does ANDing a negative number mean? - It doesn't seem to work for us. - Well, to take the negation we flip every bit and add one. - So if we don't want to do a subtraction that might go negative, - we can instead add the complement. - *) - (align_up_to a.maxpagesize addr) (Nat_big_num.bitwise_and ( Nat_big_num.add a.maxpagesize (compl64 addr)) ( Nat_big_num.sub_nat a.maxpagesize(Nat_big_num.of_int 1))))) in - let (fresh, alloc_map, (address_zero_fn : address_expr_fn)) = (address_zero fresh alloc_map) in - let alloc_fn2_ref = fresh in - let alloc_map = (Pmap.add alloc_fn2_ref alloc_fn2 alloc_map) in - let fresh = (Nat_big_num.add(Nat_big_num.of_int 1) fresh) in - let alloc_fn3 = (fun pos -> (fun secs -> align_up_to (if Nat_big_num.equal pos(Nat_big_num.of_int 0) then (Nat_big_num.div(Nat_big_num.of_int 64)(Nat_big_num.of_int 8)) else Nat_big_num.of_int 1) pos)) in - let alloc_fn3_ref = fresh in - let alloc_map = (Pmap.add alloc_fn3_ref alloc_fn3 alloc_map) in - let fresh = (Nat_big_num.add(Nat_big_num.of_int 1) fresh) in - let alloc_fn4 = (fun pos -> (fun secs -> align_up_to (Nat_big_num.div(Nat_big_num.of_int 64)(Nat_big_num.of_int 8)) pos)) in - let alloc_fn4_ref = fresh in - let alloc_map = (Pmap.add alloc_fn4_ref alloc_fn4 alloc_map) in - let fresh = (Nat_big_num.add(Nat_big_num.of_int 1) fresh) in - let alloc_fn5 = (fun pos -> (fun secs -> segment_start "ldata-segment" pos)) in - let alloc_fn5_ref = fresh in - let alloc_map = (Pmap.add alloc_fn5_ref alloc_fn5 alloc_map) in - let fresh = (Nat_big_num.add(Nat_big_num.of_int 1) fresh) in - let alloc_fn6 = (fun pos -> fun secs -> align_up_to ( Nat_big_num.add a.maxpagesize ( Nat_big_num.sub_nat(Nat_big_num.bitwise_and pos a.maxpagesize)(Nat_big_num.of_int 1))) pos) in - let alloc_fn6_ref = fresh in - let alloc_map = (Pmap.add alloc_fn6_ref alloc_fn6 alloc_map) in - let fresh = (Nat_big_num.add(Nat_big_num.of_int 1) fresh) in - let alloc_fn7 = (fun pos -> (fun secs -> (if not (Nat_big_num.equal pos(Nat_big_num.of_int 0)) then Nat_big_num.div(Nat_big_num.of_int 64)(Nat_big_num.of_int 8) else Nat_big_num.of_int 1))) in - let alloc_fn7_ref = fresh in - let alloc_map = (Pmap.add alloc_fn7_ref alloc_fn7 alloc_map) in - let fresh = (Nat_big_num.add(Nat_big_num.of_int 1) fresh) in - let alloc_fn8 = (fun pos -> (fun secs -> align_up_to (Nat_big_num.div(Nat_big_num.of_int 64)(Nat_big_num.of_int 8)) pos)) in - let alloc_fn8_ref = fresh in - let alloc_map = (Pmap.add alloc_fn8_ref alloc_fn8 alloc_map) in - let fresh = (Nat_big_num.add(Nat_big_num.of_int 1) fresh) in - (fresh, alloc_map, [ - (* For now, we base our script on the GNU bfd linker's scripts. - Here's the static -z combreloc one. - -/* Script for -z combreloc: combine and sort reloc sections */ -/* Copyright (C) 2014 Free Software Foundation, Inc. - Copying and distribution of this script, with or without modification, - are permitted in any medium without royalty provided the copyright - notice and this notice are preserved. */ -OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", - "elf64-x86-64") -OUTPUT_ARCH(i386:x86-64) -ENTRY(_start) -SEARCH_DIR("=/usr/x86_64-linux-gnu/lib64"); SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib/x86_64-linux-gnu"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS; - .interp : { *(.interp) } - .note.gnu.build-id : { *(.note.gnu.build-id) } - .hash : { *(.hash) } - .gnu.hash : { *(.gnu.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - .rela.dyn : - { - *(.rela.init) - *(.rela.text .rela.text.* .rela.gnu.linkonce.t.* ) - *(.rela.fini) - *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.* ) - *(.rela.data .rela.data.* .rela.gnu.linkonce.d.* ) - *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.* ) - *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.* ) - *(.rela.ctors) - *(.rela.dtors) - *(.rela.got) - *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.* ) - *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.* ) - *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.* ) - *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.* ) - *(.rela.ifunc) - } - .rela.plt : - { - *(.rela.plt) - PROVIDE_HIDDEN (__rela_iplt_start = .); - *(.rela.iplt) - PROVIDE_HIDDEN (__rela_iplt_end = .); - } - .init : - { - KEEP ( *(SORT_NONE(.init))) - } - .plt : { *(.plt) *(.iplt) } - .plt.bnd : { *(.plt.bnd) } - .text : - { - *(.text.unlikely .text.*_unlikely .text.unlikely.* ) - *(.text.exit .text.exit.* ) - *(.text.startup .text.startup.* ) - *(.text.hot .text.hot.* ) - *(.text .stub .text.* .gnu.linkonce.t.* ) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - } - .fini : - { - KEEP ( *(SORT_NONE(.fini))) - } - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.* ) } - .rodata1 : { *(.rodata1) } - .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : ONLY_IF_RO { KEEP ( *(.eh_frame)) } - .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table - .gcc_except_table.* ) } - /* These sections are generated by the Sun/Oracle C++ compiler. */ - .exception_ranges : ONLY_IF_RO { *(.exception_ranges - .exception_ranges* ) } - /* Adjust the address for the data segment. We want to adjust up to - the same address within the page on the next page up. */ - . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); - /* Exception handling */ - .eh_frame : ONLY_IF_RW { KEEP ( *(.eh_frame)) } - .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.* ) } - .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges* ) } - /* Thread Local Storage sections */ - .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.* ) } - .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.* ) *(.tcommon) } - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP ( *(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP ( *(SORT_BY_INIT_PRIORITY(.init_array.* ) SORT_BY_INIT_PRIORITY(.ctors.* ))) - KEEP ( *(.init_array EXCLUDE_FILE ( *crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) - PROVIDE_HIDDEN (__init_array_end = .); - } - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP ( *(SORT_BY_INIT_PRIORITY(.fini_array.* ) SORT_BY_INIT_PRIORITY(.dtors.* ))) - KEEP ( *(.fini_array EXCLUDE_FILE ( *crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) - PROVIDE_HIDDEN (__fini_array_end = .); - } - .ctors : - { - /* gcc uses crtbegin.o to find the start of - the constructors, so we make sure it is - first. Because this is a wildcard, it - doesn't matter if the user does not - actually link against crtbegin.o; the - linker won't look for a file to match a - wildcard. The wildcard also means that it - doesn't matter which directory crtbegin.o - is in. */ - KEEP ( *crtbegin.o(.ctors)) - KEEP ( *crtbegin?.o(.ctors)) - /* We don't want to include the .ctor section from - the crtend.o file until after the sorted ctors. - The .ctor section from the crtend file contains the - end of ctors marker and it must be last */ - KEEP ( *(EXCLUDE_FILE ( *crtend.o *crtend?.o ) .ctors)) - KEEP ( *(SORT(.ctors.* ))) - KEEP ( *(.ctors)) - } - .dtors : - { - KEEP ( *crtbegin.o(.dtors)) - KEEP ( *crtbegin?.o(.dtors)) - KEEP ( *(EXCLUDE_FILE ( *crtend.o *crtend?.o ) .dtors)) - KEEP ( *(SORT(.dtors.* ))) - KEEP ( *(.dtors)) - } - .jcr : { KEEP ( *(.jcr)) } - .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.* ) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.* ) } - .dynamic : { *(.dynamic) } - .got : { *(.got) *(.igot) } - . = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .); - .got.plt : { *(.got.plt) *(.igot.plt) } - .data : - { - *(.data .data.* .gnu.linkonce.d.* ) - SORT(CONSTRUCTORS) - } - .data1 : { *(.data1) } - _edata = .; PROVIDE (edata = .); - . = .; - __bss_start = .; - .bss : - { - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.* ) - *(COMMON) - /* Align here to ensure that the .bss section occupies space up to - _end. Align after .bss to ensure correct alignment even if the - .bss section disappears because there are no input sections. - FIXME: Why do we need it? When there is no .bss section, we don't - pad the .data section. */ - . = ALIGN(. != 0 ? 64 / 8 : 1); - } - .lbss : - { - *(.dynlbss) - *(.lbss .lbss.* .gnu.linkonce.lb.* ) - *(LARGE_COMMON) - } - . = ALIGN(64 / 8); - . = SEGMENT_START("ldata-segment", .); - .lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : - { - *(.lrodata .lrodata.* .gnu.linkonce.lr.* ) - } - .ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : - { - *(.ldata .ldata.* .gnu.linkonce.l.* ) - . = ALIGN(. != 0 ? 64 / 8 : 1); - } - . = ALIGN(64 / 8); - _end = .; PROVIDE (end = .); - . = DATA_SEGMENT_END (.); - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.* ) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* DWARF 3 */ - .debug_pubtypes 0 : { *(.debug_pubtypes) } - .debug_ranges 0 : { *(.debug_ranges) } - /* DWARF Extension. */ - .debug_macro 0 : { *(.debug_macro) } - .gnu.attributes 0 : { KEEP ( *(.gnu.attributes)) } - /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_* ) } -} - *) - - (* function from - inputs and configuration - to - output sections-with-address-and-policy, output symbols-with-address-and-attributes, - discards, orphans - BUT - 1. policy is not a property of output sections, but of *inputs within outputs* - i.e. KEEP( *(.init)) - - what's helpful for writing such functions? - - e.g. only_if_ro (input_query) (output ): - - i.e. ++ only_if_ro OutputSection(AlwaysOutput, Nothing, ".eh_frame", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".eh_frame"))]) - - want to take a bunch of outputs - and return a bunch of outputs? - - if so, need to return a "current address" - - *) - (DefineSymbol(ProvideIfUsed, "__executable_start", default_symbol_spec)) - ; AdvanceAddress(AddressExprFn alloc_fn1_ref) - ; OutputSection(AlwaysOutput, None, ".interp", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".interp"))]) - ; OutputSection(AlwaysOutput, None, ".note.gnu.build-id", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".note.gnu.build-id"))]) - ; OutputSection(AlwaysOutput, None, ".hash", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".hash"))]) - ; OutputSection(AlwaysOutput, None, ".gnu.hash", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".gnu.hash"))]) - ; OutputSection(AlwaysOutput, None, ".dynsym", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".dynsym"))]) - ; OutputSection(AlwaysOutput, None, ".dynstr", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".dynstr"))]) - ; OutputSection(AlwaysOutput, None, ".gnu.version", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".gnu.version"))]) - ; OutputSection(AlwaysOutput, None, ".gnu.version_d", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".gnu.version_d"))]) - ; OutputSection(AlwaysOutput, None, ".gnu.version_r", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".gnu.version_r"))]) - ; OutputSection(AlwaysOutput, None, ".rela.dyn", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".rela.init")) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".rela.text" s || (name_matches ".rela.text.*" s || name_matches ".rela.gnu.linkonce.t.*" s))) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".rela.rodata" s || (name_matches ".rela.rodata.*" s || name_matches ".rela.gnu.linkonce.r.*" s))) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".rela.data" s || (name_matches ".rela.data.*" s || name_matches ".rela.gnu.linkonce.d.*" s))) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".rela.tdata" s || (name_matches ".rela.tdata.*" s || name_matches ".rela.gnu.linkonce.td.*" s))) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".rela.tbss" s || (name_matches ".rela.tbss.*" s || name_matches ".rela.gnu.linkonce.tb.*" s))) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".rela.ctors")) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".rela.got")) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".rela.bss" s || (name_matches ".rela.bss.*" s || name_matches ".rela.gnu.linkonce.b.*" s))) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".rela.ldata" s || (name_matches ".rela.ldata.*" s || name_matches ".rela.gnu.linkonce.l.*" s))) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".rela.lbss" s || (name_matches ".rela.lbss.*" s || name_matches ".rela.gnu.linkonce.lb.*" s))) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".rela.ifunc")) - ]) - ; OutputSection(AlwaysOutput, None, ".rela.plt", [ - InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".rela.plt")) - ; DefineSymbol(ProvideIfUsed, "__rela_iplt_start", (Nat_big_num.of_int 0, make_symbol_info stb_local stt_notype (* FIXME *), make_symbol_other stv_hidden)) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".rela.iplt")) - ; DefineSymbol(ProvideIfUsed, "__rela_iplt_end", (Nat_big_num.of_int 0, make_symbol_info stb_local stt_notype (* FIXME *), make_symbol_other stv_hidden)) - ]) - ; OutputSection(AlwaysOutput, None, ".init", [ - InputQuery(KeepEvenWhenGC, SeenOrder, filter_and_concat (name_matches ".init")) - ]) - ; OutputSection(AlwaysOutput, None, ".plt", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".plt")) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".iplt")) - ]) - ; OutputSection(AlwaysOutput, None, ".plt.bnd", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".plt.bnd"))]) - ; OutputSection(AlwaysOutput, None, ".text", [ - InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".text.unlikely" s || (name_matches ".text.*_unlikely" s || name_matches ".text.unlikely.*" s) - )) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".text.exit" s || name_matches ".text.exit.*" s)) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".text.startup" s || name_matches ".text.startup.*" s)) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".text.hot" s || name_matches ".text.hot.*" s)) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".text" s || (name_matches ".stub" s || (name_matches ".text.*" s || name_matches ".gnu.linkonce.t.*" s)))) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - (* ".gnu.warning sections are handled specially by elf32.em." - * GAH. That means that what we specify here is not (completely) what - * needs to happen with these sections. *) - fun s -> name_matches ".gnu_warning" s)) - ]) - ; OutputSection(AlwaysOutput, None, ".fini", [ - InputQuery(KeepEvenWhenGC, SeenOrder, filter_and_concat (name_matches ".fini")) - ]) - ; DefineSymbol(ProvideIfUsed, "__etext", default_symbol_spec) - ; DefineSymbol(ProvideIfUsed, "_etext", default_symbol_spec) - ; DefineSymbol(ProvideIfUsed, "etext", default_symbol_spec) - ; OutputSection(AlwaysOutput, None, ".rodata", [ - InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".rodata" s || (name_matches ".rodata.*" s || name_matches ".gnu.linkonce.r.*" s) - ))]) - ; OutputSection(AlwaysOutput, None, ".eh_frame_hdr", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".eh_frame_hdr")) ]) - ; OutputSection(OnlyIfRo, None, ".eh_frame", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".eh_frame"))]) - ; OutputSection(OnlyIfRo, None, ".gcc_except_table", [InputQuery(DefaultKeep, DefaultSort, - filter_and_concat (fun s -> name_matches ".gcc_except_table" s || name_matches ".gcc_except_table.*" s))]) - ; OutputSection(OnlyIfRo, None, ".exception_ranges", [InputQuery(DefaultKeep, DefaultSort, - filter_and_concat (fun s -> name_matches ".exception_ranges" s || name_matches ".exception_ranges*" s))]) - ; AdvanceAddress(AddressExprFn alloc_fn2_ref) - ; MarkAndAlignDataSegment( Nat_big_num.mul (Nat_big_num.mul(Nat_big_num.of_int (* a.maxpagesize *)2)(Nat_big_num.of_int 1024))(Nat_big_num.of_int 1024) (* <-- for some reason binutils assumes 2MB max page size, - even if ABI says smaller *), a.commonpagesize) - ; OutputSection(OnlyIfRw, None, ".eh_frame", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".eh_frame"))]) - ; OutputSection(OnlyIfRw, None, ".gcc_except_table", [InputQuery(DefaultKeep, DefaultSort, - filter_and_concat (fun s -> name_matches ".gcc_except_table" s || name_matches ".gcc_except_table.*" s))]) - ; OutputSection(OnlyIfRw, None, ".exception_ranges", [InputQuery(DefaultKeep, DefaultSort, - filter_and_concat (fun s -> name_matches ".exception_ranges" s || name_matches ".exception_ranges*" s))]) - ; OutputSection(AlwaysOutput, None, ".tdata", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat - (fun s -> name_matches ".tdata" s || (name_matches ".tdata.*" s || name_matches ".gnu.linkonce.td.*" s)))]) - ; OutputSection(AlwaysOutput, None, ".tbss", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat - (fun s -> name_matches ".tbss" s || (name_matches ".tbss.*" s || name_matches ".gnu.linkonce.tb.*" s))) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".tcommon"))]) - ; OutputSection(AlwaysOutput, None, ".preinit_array", [ - DefineSymbol(ProvideIfUsed, "__preinit_array_start", default_symbol_spec) - ; InputQuery(KeepEvenWhenGC, DefaultSort, filter_and_concat (fun s -> name_matches ".preinit_array" s)) - ; DefineSymbol(ProvideIfUsed, "__preinit_array_end", default_symbol_spec) - ]) - ; OutputSection(AlwaysOutput, None, ".init_array", [ - DefineSymbol(ProvideIfUsed, "__init_array_start", default_symbol_spec) - ; InputQuery(KeepEvenWhenGC, ByInitPriority, filter_and_concat (fun s -> name_matches ".init_array.*" s)) - ; InputQuery(KeepEvenWhenGC, ByInitPriority, filter_and_concat (fun s -> name_matches ".ctors.*" s)) - ; InputQuery(KeepEvenWhenGC, ByInitPriority, filter_and_concat - (fun s -> name_matches ".init_array" s - || (name_matches ".ctors" s && not (file_matches "*crtbegin.o" s || (file_matches "*crtbegin?.o" s - || (file_matches "*crtend.o" s || file_matches "*crtend?.o " s))))) - ) - ; DefineSymbol(ProvideIfUsed, "__init_array_end", default_symbol_spec) - ]) - ; OutputSection(AlwaysOutput, None, ".fini_array", [ - DefineSymbol(ProvideIfUsed, "__fini_array_start", default_symbol_spec) - ; InputQuery(KeepEvenWhenGC, ByInitPriority, filter_and_concat (fun s -> name_matches ".fini_array.*" s)) - ; InputQuery(KeepEvenWhenGC, ByInitPriority, filter_and_concat (fun s -> name_matches ".dtors.*" s)) - ; InputQuery(KeepEvenWhenGC, ByInitPriority, filter_and_concat - (fun s -> name_matches ".fini_array" s - || (name_matches ".dtors" s && not (file_matches "*crtbegin.o" s || (file_matches "*crtbegin?.o" s - || (file_matches "*crtend.o" s || file_matches "*crtend?.o " s))))) - ) - ; DefineSymbol(ProvideIfUsed, "__fini_array_end", default_symbol_spec) - ]) - ; OutputSection(AlwaysOutput, None, ".ctors", [ - InputQuery(KeepEvenWhenGC, DefaultSort, filter_and_concat (fun s -> file_matches "*crtbegin.o" s && name_matches ".ctors" s)) - ; InputQuery(KeepEvenWhenGC, DefaultSort, filter_and_concat (fun s -> file_matches "*crtbegin?.o" s && name_matches ".ctors" s)) - ; InputQuery(KeepEvenWhenGC, DefaultSort, filter_and_concat - (fun s -> not (file_matches "*crtend.o" s || file_matches "*crtend?.o" s) && name_matches ".ctors" s)) - ; InputQuery(KeepEvenWhenGC, ByName, filter_and_concat (fun s -> name_matches ".ctors.*" s)) - ; InputQuery(KeepEvenWhenGC, DefaultSort, filter_and_concat - (fun s -> (file_matches "*crtend.o" s || file_matches "*crtend?.o" s) && name_matches ".ctors" s)) - (* NOTE: this exclusion is implicit in the usual linker script, - * because it won't match an input section more than once. We should - * just replicate this behaviour, since other parts of the script might rely on it - * less obviously. *) - ]) - ; OutputSection(AlwaysOutput, None, ".dtors", [ - InputQuery(KeepEvenWhenGC, DefaultSort, filter_and_concat (fun s -> file_matches "*crtbegin.o" s && name_matches ".dtors" s)) - ; InputQuery(KeepEvenWhenGC, DefaultSort, filter_and_concat (fun s -> file_matches "*crtbegin?.o" s && name_matches ".dtors" s)) - ; InputQuery(KeepEvenWhenGC, DefaultSort, filter_and_concat - (fun s -> not (file_matches "*crtend.o" s || file_matches "*crtend?.o" s) && name_matches ".dtors" s)) - ; InputQuery(KeepEvenWhenGC, ByName, filter_and_concat (fun s -> name_matches ".dtors.*" s)) - ; InputQuery(KeepEvenWhenGC, DefaultSort, filter_and_concat - (fun s -> (file_matches "*crtend.o" s || file_matches "*crtend?.o" s) && name_matches ".dtors" s)) - ]) - ; OutputSection(AlwaysOutput, None, ".jcr", [InputQuery(KeepEvenWhenGC, DefaultSort, filter_and_concat (name_matches ".jcr"))]) - ; OutputSection(AlwaysOutput, None, ".data.rel.ro", [ - InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".data.rel.ro.local*" s || name_matches ".gnu.linkonce.d.rel.ro.local.*" s - )); - InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".data.rel.ro" s || (name_matches ".data.rel.ro.*" s || name_matches ".gnu.linkonce.d.rel.ro.*" s) - )) - ]) - ; OutputSection(AlwaysOutput, None, ".dynamic", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".dynamic"))]) - ; OutputSection(AlwaysOutput, None, ".got", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".got")) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".igot")) - ]) - ; MarkDataSegmentRelroEnd (*(fun secs -> (if (sizeof ".got.plt" secs) >= 24 then 24 else 0, (fun pos -> pos)))*) - ; OutputSection(AlwaysOutput, None, ".got.plt", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".got.plt")) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".igot.plt")) - ]) - ; OutputSection(AlwaysOutput, None, ".data", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".data" s || (name_matches ".data.*" s || name_matches ".gnu.linkonce.d.*" s))) - (* the script also has SORT(CONSTRUCTORS) here, but it has no effect for ELF (I think) *) - ]) - ; OutputSection(AlwaysOutput, None, ".data1", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".data1"))]) - ; DefineSymbol(AlwaysDefine, "_edata", default_symbol_spec) - ; DefineSymbol(ProvideIfUsed, "edata", default_symbol_spec) - ; (* . = .; <-- does this do anything? YES! It forces an output section to be emitted. - Since it occurs *outside* any output section, - it is assumed to start - *) - DefineSymbol(AlwaysDefine, "__bss_start", default_symbol_spec) - ; OutputSection(AlwaysOutput, None, ".bss", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".dynbss")) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".bss" s || (name_matches ".bss.*" s || name_matches ".gnu.linkonce.b.*" s))) - ; InputQuery(DefaultKeep, DefaultSort, (fun inputlist -> - (*let _ = errln "Looking for commons" in *) - let result = (filter_and_concat is_common inputlist) - in - (*let _ = errln ("Got " ^ (show (length (result))) ^ " commons; sanity check: input list contains " ^ - (show (length inputlist)) ^ " of which " ^ - (show (length (List.filter (fun inp -> match inp with - Common _ -> true - | _ -> false - end) inputlist))) ^ " are commons." - ) - in*) result) - ) - ]) - ; AdvanceAddress(AddressExprFn alloc_fn3_ref) - ; OutputSection(AlwaysOutput, None, ".lbss", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".dynlbss")) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".dynlbss")) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".lbss" s || (name_matches ".lbss.*" s || name_matches ".gnu.linkonce.lb.*" s) - )) - ; InputQuery(DefaultKeep, DefaultSort, filter_and_concat (is_large_common)) - ]) - ; AdvanceAddress(AddressExprFn alloc_fn4_ref) - ; AdvanceAddress(AddressExprFn alloc_fn5_ref) - ; OutputSection(AlwaysOutput, Some (AddressExprFn alloc_fn6_ref), - ".lrodata", - [InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".lrodata" s || (name_matches ".lrodata.*" s || name_matches ".gnu.linkonce.lr.*" s) - )) - ; AdvanceAddress(AddressExprFn alloc_fn7_ref) - ]) - ; AdvanceAddress(AddressExprFn alloc_fn8_ref) - ; DefineSymbol(AlwaysDefine, "_end", default_symbol_spec) - ; DefineSymbol(ProvideIfUsed, "end", default_symbol_spec) - ; MarkDataSegmentEnd - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".stab", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".stab"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".stabstr", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".stabstr"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".stab.excl", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".stab.excl"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".stab.exclstr", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".stab.exclstr"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".stab.index", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".stab.index"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".stab.indexstr", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".stab.indexstr"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".comment", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".comment"))]) - (* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. *) - (* DWARF 1 *) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".debug"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".line", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".line"))]) - (* GNU DWARF 1 extensions *) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_srcinfo", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".debug_srcinfo"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_sfnames", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".debug_sfname"))]) - (* DWARF 1.1 and DWARF 2 *) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_aranges", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".debug_aranges"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_pubnames", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".debug_pubnames"))]) - (* DWARF 2 *) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_info", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".debug_info" s || name_matches ".gnu.linkonce.wi.*" s))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_abbrev", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".debug_abbrev"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_line", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat ( - fun s -> name_matches ".debug_line" s || (name_matches ".debug_line.*" s || name_matches ".debug_line_end" s)))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_frame", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".debug_frame"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_str", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".debug_str"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_loc", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".debug_loc"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_macinfo", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".debug_macinfo"))]) - (* SGI/MIPS DWARF 2 extensions *) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_weaknames", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".debug_weaknames"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_funcnames", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".debug_funcnames"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_typenames", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".debug_typenames"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_varnames", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".debug_varnames"))]) - (* DWARF 3 *) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_pubtypes", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".debug_pubtypes"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_ranges", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".debug_ranges"))]) - (* DWARF Extension. *) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".debug_macro", [InputQuery(DefaultKeep, DefaultSort, filter_and_concat (name_matches ".debug_macro"))]) - ; OutputSection(AlwaysOutput, Some address_zero_fn, ".gnu.attributes", [InputQuery(KeepEvenWhenGC, DefaultSort, filter_and_concat (name_matches ".gnu.attributes"))]) - ; DiscardInput(filter_and_concat (fun s -> name_matches ".note.GNU-stack" s || (name_matches ".gnu_debuglink" s || name_matches ".gnu.lto_*" s))) - (* NOTE: orphan sections are dealt with in the core linking logic, - not the script. *) - ])) - -let interpret_guard guard comp name1:bool= - ((match guard with - always0 -> true - | OnlyIfRo -> - let v = (List.for_all (fun comp_el -> (match comp_el with - IncludeInputSection(retainpol, (* fname, linkable_idx, shndx, isec, img *) irec) -> Nat_big_num.equal(Nat_big_num.of_int - (* is this section read-only? if it doesn't have shf_write, yes *)0) (Nat_big_num.bitwise_and irec.isec.elf64_section_flags shf_write) - | _ -> (* holes, common symbols and provided symbols shouldn't prevent ONLY_IF_RO *) true - )) comp) - in (*let _ = errln ("only_if_ro evaluated " ^ (show v) ^ " for output section " ^ name) - in*) v - | OnlyIfRw -> - let v = (List.for_all (fun comp_el -> (match comp_el with - IncludeInputSection(retainpol, (* fname, linkable_idx, shndx, isec, img *) irec) -> not (Nat_big_num.equal(Nat_big_num.of_int - (* is this section read-only? if it doesn't have shf_write, yes *)0) (Nat_big_num.bitwise_and irec.isec.elf64_section_flags shf_write)) - | _ -> (* holes etc. shouldn't prevent ONLY_IF_RW *) true - )) comp) - in (*let _ = errln ("only_if_rw evaluated " ^ (show v) ^ " for output section " ^ name) - in *)v - )) - -(* Passes over the script: - * - * 1. assign input sections to output sections (or discard) and define symbols. - * - * 2. compute def-use and optionally GC, removing unwanted sections and symbols - * - * 3. build image, assigning addresses as we go. - * - * Some passes require matching/retrieving what a previous pass on the same node did. - * So we give each script element a natural "idx" label. - *) -(*val label_script_aux : natural -> linker_control_script -> labelled_linker_control_script*) -let label_script_aux start script1:(script_element*Nat_big_num.num)list= - (mapi (fun i -> fun el -> (el, ( Nat_big_num.add start (Nat_big_num.of_int i)))) script1) - -(*val label_script : linker_control_script -> labelled_linker_control_script*) -let label_script script1:(script_element*Nat_big_num.num)list= (label_script_aux(Nat_big_num.of_int 0) script1) - -type input_output_assignment = ( input_spec list * (output_section_spec * Nat_big_num.num) list) - -(*val assign_inputs_to_output_sections : - input_output_assignment -> (* accumulator: list of discards, list of output compositions (these include symbols) *) - set (natural * natural) -> (* used sections *) - set (natural * natural * natural) -> (* used commons *) - list input_spec -> (* remaining inputs *) - maybe (output_section_spec * natural) -> (* cur_sec -- the current output section spec and its OutputSection script item idx *) - maybe input_spec -> (* last input section to be output -- might not have one *) - (input_spec -> input_spec -> Basic_classes.ordering) (* "seen ordering" *) -> - labelled_linker_control_script -> - input_output_assignment*) (* accumulated result *) -let rec assign_inputs_to_output_sections acc used_sections used_commons inputs (cur_output_sec : (output_section_spec * Nat_big_num.num)option) last_input_sec seen_ordering script1:(input_spec)list*(output_section_spec*Nat_big_num.num)list= - (let (rev_discards, rev_outputs) = acc in - let flush_output_sec - = (fun maybe_output_sec_and_idx -> (match (maybe_output_sec_and_idx : (output_section_spec * Nat_big_num.num)option) with - Some (OutputSectionSpec (guard, addr, name1, comp), script_idx) -> - (*let _ = errln ("Guardedly flushing output section named " ^ name ^ " with " ^ ( - match addr with Nothing -> "no address yet" | Just a -> "address 0x" ^ (hex_string_of_natural a) end - ) ^ " and composed of " ^ (show (length comp)) ^ " constituents.") - in*) - (* evaluate the guard *) - if interpret_guard guard comp name1 - then (* do it *) (rev_discards, (((OutputSectionSpec (guard, addr, name1, comp)), script_idx) :: rev_outputs)) - else (* ignore it *) acc - | None -> (* for convenience, make this a no-op rather than error *) - (* failwith "internal error: flushing output section with no current output section" *) - acc - )) - in - (match script1 with - [] -> flush_output_sec cur_output_sec - | (element1, idx1) :: more_elements_and_idx -> - let do_nothing = (acc, used_sections, used_commons, cur_output_sec, last_input_sec) - in - let (new_acc, new_used_sections, new_used_commons, (new_cur_output_sec : (output_section_spec * Nat_big_num.num)option), new_last_input_sec) - = ((match element1 with - DefineSymbol(symdefpol, name1, (symsize, syminfo, symother)) -> - (* Label the current section in the image - * with a new symbol definition. If there isn't - * a current section, use the ABS section (what is that labelling?). *) - (acc, - used_sections, - used_commons, - (match (cur_output_sec : (output_section_spec * Nat_big_num.num)option) with - None -> (*let _ = errln ("FIXME: for defining `" ^ name ^ "': ABS symbol defs not yet supported") in*) None - | Some ((OutputSectionSpec (guard, maybe_addr, secname1, comp)), output_script_idx) -> - (*let _ = errln ("Including a symbol named `" ^ name ^ " in composition of output section `" ^ secname ^ "'") in*) - Some ((OutputSectionSpec (guard, maybe_addr, secname1, - List.rev_append (List.rev comp) [ProvideSymbol(symdefpol, name1, (symsize, syminfo, symother))])) - , output_script_idx) - ), - last_input_sec) - | AdvanceAddress(AddressExprFn advance_fn) -> - (* If we're inside a section, insert a hole, - * else just update the logical address *) - (*let _ = errln ("Advancing location counter") in*) - (match cur_output_sec with - None -> do_nothing - (* This assignment is setting a new LMA. *) - (* (acc, *) - | Some (sec, idx1) -> do_nothing - ) - | MarkAndAlignDataSegment(maxpagesize1, commonpagesize1) -> - (* The "data segment end" is a distinguished label, - * so we can encode the whole thing into a conditional. *) - (*let _ = errln ("Mark/aligning data segment") in*) - do_nothing - | MarkDataSegmentEnd -> - (*let _ = errln ("Marking data segment end") in*) - do_nothing - | MarkDataSegmentRelroEnd(*(fun_from_secs_to_something)*) -> - (*let _ = errln ("Marking data segment relro end") in*) - do_nothing - | OutputSection(outputguard, maybe_expr, name1, sub_elements) -> - (* If we have a current output section, finish it and add it to the image. - * Q. Where do guards ("ONLY_IF_RO" etc) get evaluated? - * A. Inside flush_output_sec. *) - (*let _ = errln ("Recursively composing a new output section `" ^ name ^ "'...") in*) - let acc_with_output_sec = (flush_output_sec cur_output_sec) - in - let new_cur_output_sec = (Some((OutputSectionSpec(outputguard, (* maybe_expr pos secs *) None, name1, [])), idx1)) - in - (* Recurse down the list of input queries, assigning them to this output sec - * Note that output sections may not nest within other output sections. - * At the end of the list of sub_elements, we will flush the section we built up. - *) - let final_acc - = (assign_inputs_to_output_sections acc used_sections used_commons inputs new_cur_output_sec last_input_sec seen_ordering (label_script sub_elements)) - in - (* NOTE that this sub-accumulation will never add a new output section - * because output sections can't nest. *) - (final_acc, used_sections, used_commons, (* cur_output_sec *) None, last_input_sec) - | DiscardInput(selector) -> - let selected = (selector inputs) - in - let (rev_discards, rev_outputs) = acc in - (*let _ = Missing_pervasives.errln ("Processing discard rule; selected " ^ (show (length selected)) - ^ " inputs.") - in*) - (( List.rev_append (List.rev (List.rev (let x2 = - ([]) in List.fold_right (fun i x2 -> if true then i :: x2 else x2) selected x2))) rev_discards, rev_outputs), used_sections, used_commons, cur_output_sec, last_input_sec) - | InputQuery(retainpol, sortpol, selector) -> - (* Input queries can only occur within an output section. *) - (match cur_output_sec with - None -> failwith "linker script error: input query without output section" - | Some ((OutputSectionSpec (output_guard1, output_sec_addr, output_sec_name, output_composition)), output_script_idx) -> - (* Add them to the current output spec. We have to be careful about ordering: - * according to the GNU ld manual (and observed behaviour), by default - * "the linker will place files and sections matched by wildcards in the order - * in which they are seen during the link". For .o files on the command line, - * this means the command line order. But for members of archives, it means - * the order in which they were "pulled in" during input enumeration. We - * actually don't compute this here; it is passed in from our caller in link.lem. *) - let sortfun = ((match sortpol with - DefaultSort -> List.sort seen_ordering (* FIXME: pay attention to command line *) - | SeenOrder -> List.sort seen_ordering - | ByName -> List.sort compareInputSpecByName - | ByNameThenAlignment -> List.sort compareInputSpecByNameThenAlignment - | ByAlignment -> List.sort compareInputSpecByAlignment - | ByAlignmentThenName -> List.sort compareInputSpecByAlignmentThenName - | ByInitPriority -> List.sort compareInputSpecByInitPriority - )) - in - let selected = (selector inputs) - in - let selected_deduplicated = (List.filter (fun inp -> (match inp with - InputSection(irec) -> not ( Pset.mem(irec.idx, irec.shndx) used_sections) - | Common(idx1, fname1, img2, def) -> not ( Pset.mem(idx1, def.def_sym_scn, def.def_sym_idx) used_commons) - )) selected) - in - (*let _ = errln ("Evaluated an input query, yielding " ^ - (show (length selected)) ^ " undeduplicated and " ^ - (show (length selected_deduplicated)) ^ - " deduplicated results, to be added to composition currently of " ^ - (show (length output_composition)) ^ " items.") in*) - (* Search input memory images for matching sections. *) - let sorted_selected_inputs = (sortfun selected_deduplicated) - in - let (sectionMatchList : input_section_rec list) = (Lem_list.mapMaybe (fun inp -> - (match inp with - InputSection(x) -> - (*let _ = errln ("Matched an input section named " ^ x.isec.elf64_section_name_as_string ^ - " in a file " ^ x.fname ^ " with first 20 bytes " ^ (show (take 20 - (let maybe_elname = elf_memory_image_element_coextensive_with_section x.shndx x.img - in - match maybe_elname with - Nothing -> failwith ("impossible: no such element (matching shndx " ^ (show x.shndx) ^ ")") - | Just idstr -> - match Map.lookup idstr x.img.elements with - Just el -> el.contents - | Nothing -> failwith "no such element" - end - end - )))) - in*) - Some x - | _ -> None - )) sorted_selected_inputs) - in - let commonMatchList = (Lem_list.mapMaybe (fun inp -> - (match inp with - | Common(idx1, fname1, img2, def) -> Some(idx1, fname1, img2, def) - | _ -> None - )) sorted_selected_inputs) - in - - (acc, - Pset.(union) used_sections (let x2 =(Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) - []) in List.fold_right - (fun irec x2 -> if true then Pset.add (irec.idx, irec.shndx) x2 else x2) - sectionMatchList x2), - Pset.(union) used_commons (let x2 =(Pset.from_list (tripleCompare Nat_big_num.compare Nat_big_num.compare Nat_big_num.compare) - []) in List.fold_right - (fun(idx1, fname1, img2, def) x2 -> - if true then Pset.add (idx1, def.def_sym_scn, def.def_sym_idx) x2 else x2) - commonMatchList x2), - (* new_cur_output_spec *) Some ( - (OutputSectionSpec(output_guard1, output_sec_addr, output_sec_name, - List.rev_append (List.rev (List.rev_append (List.rev output_composition) (let x2 = - ([]) in List.fold_right - (fun input_sec x2 -> - if true then - IncludeInputSection - (retainpol, (* input_sec.fname, input_sec.idx, input_sec.shndx, input_sec.isec, input_sec.img *) input_sec) - :: x2 else x2) sectionMatchList x2))) (let x2 = ([]) in List.fold_right - (fun(idx1, fname1, img2, def) x2 -> - if true then - IncludeCommonSymbol (DefaultKeep, fname1, idx1, def, img2) :: x2 else - x2) commonMatchList x2) - )), output_script_idx), - last_input_sec - ) - ) - )) - in - (*let _ = match new_cur_output_sec with - Just (OutputSectionSpec (guard, addr, name, comp), script_idx) -> - errln ("Now output section `" ^ name ^ "' is composed of " ^ (show (length comp)) ^ " elements.") - | Nothing -> () - end in*) - assign_inputs_to_output_sections new_acc new_used_sections new_used_commons - (inputs : input_spec list) - (new_cur_output_sec) - (new_last_input_sec : input_spec option) - seen_ordering - (more_elements_and_idx : labelled_linker_control_script) - )) - -(* NOTE: this is also responsible for deleting any PROVIDEd symbols that - * were not actually referenced. BUT HOW, if we haven't built the image and - * hence haven't added the symbols yet? Symbols affect reachability, so - * we're going to have to figure this out. Really we want a memory image that - * does not yet have addresses assigned, but does have the symbols inserted. - * BUT even that is not right, because we want to be able to remove some - * sections (GC them). So the section composition is not yet fixed. So we have - * a problem. - * - * Note that the only symbols we have to remove are ones that were PROVIDEd - * in our output composition. So doing the GC on output compositions seems - * sane. We can get the graph's edge list by inspecting the constituent memory - * images from which each output section composition element is drawn. - * Collecting sections and collecting symbols seems fair. Note that symbols - * can never be placed mid-section (I don't think?? they can use arbitrary - * expressions, but not that depend on whether an input section is included - * or not) so removing a section should never imply the removal of a symbol. - * - * So that implies we need not yet build a memory image. - *) -(*val compute_def_use_and_gc : allocated_sections_map -> allocated_sections_map*) -let compute_def_use_and_gc outputs_by_name:allocated_sections_map= outputs_by_name (* FIXME: implement GC *) - -let output_section_type comp:Nat_big_num.num= -( - (* are we composed entirely of nobits sections and common symbols? *)let all_nobits = (List.for_all (fun comp_el -> - (match comp_el with - IncludeInputSection(retain_pol,(* fname, linkable_idx, shndx, isec, img *) irec) -> Nat_big_num.equal - irec.isec.elf64_section_type sht_nobits - | IncludeCommonSymbol(retain_pol, fname1, linkable_idx, def, img2) -> true - | _ -> (* padding and symdefs can be nobits *) true - )) comp) - in - if all_nobits then sht_nobits else sht_progbits) - -let output_section_flags comp:Nat_big_num.num= - (let writable = (List.exists (fun comp_el -> - (match comp_el with - IncludeInputSection(retain_pol, (* fname, linkable_idx, shndx, isec, img *) irec) -> - flag_is_set shf_write irec.isec.elf64_section_flags - | IncludeCommonSymbol(retain_pol, fname1, linkable_idx, def, img2) -> - (* assume common symbols are writable *) true - | _ -> (* padding and symdefs do not make a section writable *) false - )) comp) - in - let executable = (List.exists (fun comp_el -> - (match comp_el with - IncludeInputSection(retain_pol,(* fname, linkable_idx, shndx, isec, img *) irec) -> - flag_is_set shf_execinstr irec.isec.elf64_section_flags - | IncludeCommonSymbol(retain_pol, fname1, linkable_idx, def, img2) -> - (* assume common symbols are not executable, since they're zeroed *) false - | _ -> (* padding and symdefs do not make a section executable -- HMM *) false - )) comp) - in - let alloc = (List.exists (fun comp_el -> - (match comp_el with - IncludeInputSection(retain_pol, (* fname, linkable_idx, shndx, isec, img *) irec) -> - flag_is_set shf_alloc irec.isec.elf64_section_flags - | IncludeCommonSymbol(retain_pol, fname1, linkable_idx, def, img2) -> - (* common symbols are allocatable *) true - | ProvideSymbol(pol, name1, spec) -> - (* symbols make a section allocatable? HMM *) true - | _ -> (* padding does not make a section allocatable *) false - )) comp) - in - let is_thread_local_yesnomaybe = (fun comp_el -> - (match comp_el with - IncludeInputSection(retain_pol, (* fname, linkable_idx, shndx, isec, img *) irec) -> - Some(flag_is_set shf_tls irec.isec.elf64_section_flags) - | IncludeCommonSymbol(retain_pol, fname1, linkable_idx, def, img2) -> - (* FIXME: support tcommon *) Some(false) - | ProvideSymbol(pol, name1, spec) -> - (* linker script symbols shouldn't be defined here, unless they can be declared thread-local (FIXME: can they?) *) - Some false - | _ -> (* padding does not make a section thread-local, or non-. *) None - ) - ) - in - let thread_local = ( - (* Is any element positively thread-local? *) - let v = (List.fold_left (fun acc_ynm -> fun comp_el -> - let new_ynm = (is_thread_local_yesnomaybe comp_el) - in - (match (acc_ynm, new_ynm) with - (None, None) -> None - | (None, Some x) -> Some x - | (Some x, None) -> Some x - | (Some true, Some false) -> Some true - | (Some true, Some true) -> Some true - | (Some false, Some false) -> Some false - | (Some true, Some false) -> Some true - )) None comp) - in - if (Lem.option_equal (=) v (Some(true))) && not ( (Lem.option_equal (=)(Some(true)) (* are *all* either don't-care or positively thread-local? *) - (List.fold_left (fun acc_ynm -> fun comp_el -> - let new_ynm = (is_thread_local_yesnomaybe comp_el) - in - (match (acc_ynm, new_ynm) with - (None, None) -> None - | (None, Some x) -> Some x - | (Some x, None) -> Some x - | (Some true, Some false) -> Some false - | (Some true, Some true) -> Some true - | (Some false, Some false) -> Some false - | (Some true, Some false) -> Some false - )) None comp))) then failwith "error: section mixes thread-local and non-thread-local inputs" - else (match v with - None -> false - | Some x -> x - ) - ) - in - Nat_big_num.bitwise_or - (if thread_local then shf_tls else Nat_big_num.of_int 0) - (Nat_big_num.bitwise_or - (if executable then shf_execinstr else Nat_big_num.of_int 0) - (Nat_big_num.bitwise_or - (if writable then shf_write else Nat_big_num.of_int 0) - (if alloc then shf_alloc else Nat_big_num.of_int 0) - ) - )) - -let symbol_def_for_provide_symbol name1 size2 info other control_script_linkable_idx:symbol_definition= - ({ - def_symname = (*let _ = errln ("Linker script is defining symbol called `" ^ name ^ "'") in*) name1 - ; def_syment = ({ - elf64_st_name = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) (* ignored *) - ; elf64_st_info = info - ; elf64_st_other = other - ; elf64_st_shndx = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_st_value = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) (* ignored *) - ; elf64_st_size = (Uint64.of_string (Nat_big_num.to_string size2)) - }) - ; def_sym_scn =(Nat_big_num.of_int 0) - ; def_sym_idx =(Nat_big_num.of_int 0) - ; def_linkable_idx = control_script_linkable_idx - }) - -(*val assign_dot_to_itself : natural -> address_expr_fn_map allocated_sections_map -> (natural * address_expr_fn_map allocated_sections_map * address_expr_fn)*) -let assign_dot_to_itself fresh alloc_map:Nat_big_num.num*((Nat_big_num.num),(Nat_big_num.num ->allocated_sections_map ->Nat_big_num.num))Pmap.map*address_expr_fn= - (let fn = (fun dot -> fun _ -> dot) in - let alloc_map' = (Pmap.add fresh fn alloc_map) in - let fresh' = (Nat_big_num.add(Nat_big_num.of_int 1) fresh) in - (fresh', alloc_map', AddressExprFn fresh)) - -(*val build_image : - address_expr_fn_map allocated_sections_map -> (* global dictionary of address_expr_fn_ref -> address_expr_fn *) - elf_memory_image -> (* accumulator *) - natural -> (* location counter *) - allocated_sections_map -> (* outputs constructed earlier *) - (Map.map string (list (natural * binding))) -> (* bindings_by_name *) - labelled_linker_control_script -> - natural -> (* control_script_linkable_idx *) - (Map.map string (list symbol_definition)) -> (* linker_defs_by_name *) - (elf_memory_image * allocated_sections_map)*) (* accumulated result *) -let rec build_image alloc_map acc pos (AllocatedSectionsMap outputs_by_name) bindings_by_name script1 control_script_linkable_idx linker_defs_by_name:(any_abi_feature)annotated_memory_image*allocated_sections_map= - (let (add_output_section : (Nat_big_num.num * elf_memory_image) -> output_section_spec -> (Nat_big_num.num * elf_memory_image * Nat_big_num.num * output_section_spec)) - = (fun ((*scn_idx, *)pos, acc_img) -> - (fun (OutputSectionSpec (guard, addr, secname1, comp)) -> - (*let _ = errln ("Computing composition of output section `" ^ secname ^ "' from " ^ (show (length comp)) ^ " elements") - in*) - let unaligned_start_addr = ((match addr with - Some a -> failwith ("internal error: section " ^ (secname1 ^ ": did not expect address to be assigned yet")) - | None -> pos - )) - in - let align = (alignof_output_section comp) - in - (*let _ = errln ("Aligning start of output section " ^ secname ^ " up to a " ^ (show align) ^ "-byte address boundary") - in*) - let output_section_start_addr = (align_up_to align unaligned_start_addr) - in - let (end_addr, comp_addrs) = (do_output_section_layout_starting_at_addr output_section_start_addr (AllocatedSectionsMap outputs_by_name) comp) - in - let size2 = (Nat_big_num.sub_nat end_addr output_section_start_addr) - in - (*let _ = Missing_pervasives.outln ( - if List.null comp then secname else ( - ((space_padded_and_maybe_newline 16 secname) ^ - ("0x" ^ (left_zero_padded_to 16 (hex_string_of_natural output_section_start_addr))) ^ " " ^ - (left_space_padded_to 10 ("0x" ^ (hex_string_of_natural size)))) - ) - ) - in*) - let (concatenated_content, final_addr, new_range_tag_pairs) = (List.fold_left (fun (accum_pat, accum_current_addr, accum_meta) -> (fun (comp_el, comp_addr) -> - (*let _ = errln ("Adding an element to composition of output section `" ^ secname ^ "', current address 0x" ^ (hex_string_of_natural accum_current_addr)) - in*) - let make_line = (fun namestr -> (fun addrstr -> (fun szstr -> (fun rhs -> ( - (space_padded_and_maybe_newline(Nat_big_num.of_int 16) (" " ^ namestr)) ^ - (("0x" ^ (left_zero_padded_to(Nat_big_num.of_int 16) addrstr)) ^ (" " ^ - ((left_space_padded_to(Nat_big_num.of_int 10) ("0x" ^ szstr)) ^ (" " ^ rhs)))) - ))))) - in - let (sz, comp_el_pat, this_el_meta) = ((match comp_el with - | IncludeInputSection(retainpolicy, (* fname, linkable_idx, shndx, isec, img *) irec) -> - (* We want to get the input section as a byte pattern *) - (*let _ = errln ("Processing inclusion of input section `" ^ irec.isec.elf64_section_name_as_string - ^ "' from file `" ^ irec.fname - ^ "' into output section `" ^ secname - ^ "'") - in*) - let maybe_secname = (elf_memory_image_element_coextensive_with_section irec.shndx irec.img) - in - (match maybe_secname with - None -> failwith ("impossible: no such section" (*(matching irec.shndx " ^ (show irec.shndx) ^ ")""*)) - | Some idstr -> - (*let _ = errln ("Found element named " ^ idstr ^ " coextensive with section named " ^ - irec.isec.elf64_section_name_as_string ^ " in file " ^ irec.fname) - in*) - (match Pmap.lookup idstr irec.img.elements with - Some el -> - (*let _ = Missing_pervasives.outln (make_line irec.isec.elf64_section_name_as_string - (hex_string_of_natural comp_addr) (hex_string_of_natural irec.isec.elf64_section_size) - irec.fname) - in*) - let section_el_name = (get_unique_name_for_section_from_index irec.shndx irec.isec irec.img) - in - (*let _ = errln ("Copying metadata for output section `" ^ section_el_name ^ "'") in*) - let range_or_sym_is_in_this_sec = (fun maybe_range -> (fun tag -> - (* is it within the section we're outputting? - * first we needs its element name. *) - (* filter out ones that don't overlap *) - (match maybe_range with - Some(el_name, (start, len)) -> - (* img and shndx came as a unit, so they're definitely - * talking about the same file *) - (* shndx = sym_shndx *) - section_el_name = el_name - | None -> - (* ABS symbols have this property *) - (match tag with - SymbolDef(def) -> - (* don't match section symbols, or we'll be inundated *) - let sym_shndx = (Nat_big_num.of_string (Uint32.to_string def.def_syment.elf64_st_shndx)) - in - if not (Nat_big_num.equal sym_shndx shn_abs) || ( not (Nat_big_num.equal (get_elf64_symbol_type def.def_syment) stt_section)) then false - else ( - let abs_address = (Ml_bindings.nat_big_num_of_uint64 def.def_syment.elf64_st_value) - in - (* check it against our section *) - let section_end_addr = (Nat_big_num.add accum_current_addr irec.isec.elf64_section_size) - in - ( Nat_big_num.greater_equal abs_address accum_current_addr - && Nat_big_num.less abs_address section_end_addr) - (* FIXME: argument that this should be <=, i.e. can mark end addr *) - (* PROBLEM: this is all very well, but there's no reason why - * ABS symbols need to point at an address within some output - * section. They can just be arbitrary values. This is a bit of an - * abuse if we do it within the C language (to get the value, you - * have to do "(int) &sym", i.e. create a meaningless pointer - * intermediate) but arguably is okay in an impl-def way. - * - * WHAT to do? well, just always output the ABS symbols, for now. - * - * The example that provoked this is in glibc's - * locale/lc-address.c, which compiles down to create - * the following ABS symbol: - * - * 0000000000000001 g *ABS* 0000000000000000 _nl_current_LC_ADDRESS_used - * - * ... i.e. the _nl_current_LC_ADDRESS_used appears to be just a flag. - * - * Where can we handle this? We don't see ABS symbols since they - * aren't associated with sections. We simply need to copy over - * all the ABS symbols appearing in included input objects. - * That means there's no point doing anything with them here - * while we're fiddling with sections. Do it later in a whole- - * -image pass. - *) - && false (* ... at least until we see a better way *) - ) - | _ -> false - ) - ) - )) - in - let ranges_and_tags = (let x2 = - ([]) in List.fold_right - (fun(maybe_range, tag) x2 -> - if range_or_sym_is_in_this_sec maybe_range tag then - (maybe_range, tag) :: x2 else x2) (Pset.elements irec.img.by_range) - x2) - in - let included_defs = (let x2 = - ([]) in List.fold_right - (fun(maybe_range, def) x2 -> - if range_or_sym_is_in_this_sec maybe_range (SymbolDef (def)) then - def :: x2 else x2) - (elf_memory_image_defined_symbols_and_ranges irec.img) x2) - in - let included_global_defs = (let x2 = - ([]) in List.fold_right - (fun def x2 -> - if not - (Nat_big_num.equal - ( - (* filter out locals *) get_elf64_symbol_binding def.def_syment) - stb_local) then def :: x2 else x2) included_defs x2) - in - (* What symbol defs are being included? *) - (* For each global symbol defined in the section, output a line. *) - (*let _ = Missing_pervasives.outs (List.foldl (^) "" ( - List.map (fun def -> (make_line "" - (hex_string_of_natural (comp_addr + (natural_of_elf64_addr def.def_syment.elf64_st_value))) - (hex_string_of_natural (natural_of_elf64_xword def.def_syment.elf64_st_size)) - (" " ^ def.def_symname)) ^ "\n" - ) included_global_defs - )) - in*) - let (new_ranges_and_tags : (( element_range option) * ( any_abi_feature range_tag)) Pset.set) - = (Lem_set.setMapMaybe - (instance_Basic_classes_SetType_tup2_dict - (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) - instance_Basic_classes_SetType_var_dict) (instance_Basic_classes_SetType_tup2_dict - (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) - instance_Basic_classes_SetType_var_dict) (fun (maybe_range, tag) -> - (* How do we update existing metadata? In general, - * we get a new range. *) - let new_range = ((match maybe_range with - None -> None - | Some(el_name, (start, len)) -> - Some(secname1, -( (* FIXME: pass this through a section-to-element gensym. - We can just (for now) define output element names - to equal the section names, since we have no unnamed - output sections and no output common symbols. *)let new_start_off = (Nat_big_num.add start ( Nat_big_num.sub_nat comp_addr output_section_start_addr)) - in - (*let _ = errln ("Calculated element offset 0x" ^ (hex_string_of_natural new_start_off) ^ - " in element " ^ secname ^ " for tag at address 0x" ^ (hex_string_of_natural accum_current_addr) ^ - " , start offset 0x" ^ (hex_string_of_natural start) ^ ", output section start addr 0x" ^ - (hex_string_of_natural output_section_start_addr) ^ ", comp_addr 0x" ^ (hex_string_of_natural comp_addr)) - in*) - (new_start_off, - len))) - )) - in - (match tag with - (* If it's a section, we discard it. - * We will add a new section record at the end. (FIXME) *) - | FileFeature(ElfSection(idx1, isec1)) -> None - (* If it's a symbol def, we propagate it. - * We record its linkable idx, so we can - * match it later with the bindings we formed - * earlier. - * FIXME: this is a bit nasty. Perhaps we - * should replace syment with a minimal structure - * that avoids duplication. Same for isecs. *) - | SymbolDef(def) -> - (* if get_elf64_symbol_type def.def_syment = stt_section - then Nothing FIXME: also re-create the section symbol when we create the ElfSection - else *) (* This doesn't work -- some refs might be bound to this symbol. - Instead, strip the symbol when we generate the output symtab (FIXME). *) - (*let _ = errln ("Copying symbol named `" ^ def.def_symname ^ "'") - in*) - Some(new_range, SymbolDef({ - def_symname = (def.def_symname) - ; def_syment = (def.def_syment) - ; def_sym_scn = (def.def_sym_scn) - ; def_sym_idx = (def.def_sym_idx) - ; def_linkable_idx = (irec.idx) - })) - | AbiFeature(x) -> Some(new_range, AbiFeature(x)) - (* If it's a symbol ref with no reloc site, we discard it? *) - | SymbolRef(r) -> - (*let _ = if r.ref.ref_symname = "_start" then errln ("Saw ref to _start, " - ^ "in section " ^ irec.isec.elf64_section_name_as_string ^ " of linkable " ^ (show irec.idx)) - else () - in*) - let get_binding_for_ref = (fun symref -> (fun linkable_idx -> (fun fname1 -> - let name_matches1 = ((match Pmap.lookup symref.ref_symname bindings_by_name with Some x -> x | None -> [] )) - in - (match List.filter (fun (bi, ((r_idx, r, r_item), m_d)) -> Nat_big_num.equal r_idx linkable_idx && (r = symref)) name_matches1 with - [(b_idx, b)] -> (b_idx, b) - | [] -> failwith "no binding found" - | _ -> failwith ("ambiguous binding found for symbol `" ^ (symref.ref_symname ^ ("' in file " ^ fname1))) - ) - ))) - in - let (bi, b) = (get_binding_for_ref r.ref irec.idx irec.fname) - in - let ((ref_idx, ref1, ref_linkable), maybe_def) = b - in - (match r.maybe_reloc with - None -> None - (* If it's a reloc site, we need to somehow point it - * at the *definition* that it was bound to. YES. - * reloc_sites are - - type reloc_site = <| - ref_relent : elf64_relocation_a - ; ref_rel_scn : natural --the relocation section idx - ; ref_rel_idx : natural --the index of the relocation rec - ; ref_src_scn : natural --the section *from which* the reference logically comes - |> - - type elfNN_relocation_a = - <| elfNN_ra_offset : elf32_addr --Address at which to relocate - ; elfNN_ra_info : elf32_word --Symbol table index/type of relocation to apply - ; elfNN_ra_addend : elf32_sword --Addend used to compute value to be stored - |> - - * ... of which ref_src_scn, ref_rel_idx, - * ref_rel_scn and elfNN_ra_offset can be ignored. - * - * What *is* important is that we somehow point at - * the symbol definition (or perhaps *un*definition, - * if we're generating a shared library) that it - * refers to. - * - * For that, we update ra_info use the 1 + binding_idx, - * i.e. consider that there is a fresh symbol table - * and that it has a distinct entry for each binding. - * - * FIXME: we also need to account for - * reloc decisions -- MakePIC etc. - *) - | Some(rs) -> Some(new_range, SymbolRef( - { ref = ({ - (* This is not the place to be fixing up - * symbol references. We can't yet patch the element content, - * because we haven't yet decided on the address of everything. - * - * That said, we *do* need to represent the old ref in the new - * linked-image context. That's *all* we should be doing, right now. - * - *) - ref_symname = (ref1.ref_symname) - ; ref_syment = - ({ elf64_st_name = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) (* unused *) - ; elf64_st_info = (ref1.ref_syment.elf64_st_info) - ; elf64_st_other = (ref1.ref_syment.elf64_st_other) - ; elf64_st_shndx = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int (* shn_abs *)0))) - ; elf64_st_value = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_st_size = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - }) - ; ref_sym_scn =(Nat_big_num.of_int 0) - ; ref_sym_idx =(Nat_big_num.of_int 0) - (* match maybe_def with Just _ -> 1+bi | Nothing -> 0 end *) - }) - ; maybe_reloc = (Some { - ref_relent = ({ - elf64_ra_offset = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) (* ignored *) - ; elf64_ra_info = (Uint64.logor - (* HACK: use bi as the symbol index. *) - (Uint64.of_string (Nat_big_num.to_string (get_elf64_relocation_a_type rs.ref_relent))) - (Uint64.shift_left - (* ... actually, don't, now we have maybe_def_bound_to *) - (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int (* (1+bi) *)0)))( 32) - ) - ) - ; elf64_ra_addend = (rs.ref_relent.elf64_ra_addend) - }) - ; ref_rel_scn =(Nat_big_num.of_int 0) - ; ref_rel_idx =(Nat_big_num.of_int 0) - ; ref_src_scn =(Nat_big_num.of_int 0) - }) - ; maybe_def_bound_to = -( - (* Re-search the bindings list for a match, because we might have - * re-bound this symbol since we created the image. FIXME: since - * we do this, is there anything gained from populating this field - * earlier? Probably best not to. *)let (possible_bindings : (Nat_big_num.num * binding) list) - = ((match Pmap.lookup ref1.ref_symname bindings_by_name with - Some l -> if ref1.ref_symname = "__fini_array_end" then - (*let _ = errln ("Found " ^ (show (length l)) ^ " bindings for __fini_array_end, of which " ^ - (show (length (List.filter (fun (bi, (r, maybe_d)) -> maybe_d <> Nothing) l))) ^ - " are with definition") - in*) l - else l - | None -> [] - )) - in - (* what's the actual binding? *) - (match r.maybe_def_bound_to with - None -> failwith ("at this stage, all references must have a decision: `" ^ (ref1.ref_symname ^ "'")) - | Some(decision, _) -> - (* Search the list of bindings for a possibly-updated - * binding for this reference. *) - let matching_possibles = (List.filter (fun (bi, ((ref_idx, ref1, ref_item), maybe_d)) -> - (match maybe_d with - None -> false - | Some (def_idx, def, def_item) -> Nat_big_num.equal - (* match the *reference*, whose linkable we're processing now *) - irec.idx ref_idx - && (Nat_big_num.equal r.ref.ref_sym_scn ref1.ref_sym_scn - && Nat_big_num.equal r.ref.ref_sym_idx ref1.ref_sym_idx) - - (* - def.def_syment = sd.def_syment - && def.def_sym_scn = sd.def_sym_scn - && def.def_sym_idx = sd.def_sym_idx - && def_idx = sd.def_linkable_idx *) - ) - ) possible_bindings) - in - (*let _ = errln ("For a ref to `" ^ ref.ref_symname ^ - "', possibles list is: " ^ ( - List.foldl (fun x -> fun y -> x ^ ", " ^ y) "" (List.map (fun (bi, ((_, _, _), maybe_d)) -> - match maybe_d with - Just(def_idx, def, def_item) -> - "`" ^ def.def_symname ^ "' " ^ - "in linkable " ^ (show def_idx) ^ - ", section " ^ (show def.def_sym_scn) ^ - ", sym idx " ^ (show def.def_sym_idx) - | _ -> failwith "impossible: just filtered out no-def bindings" - end - ) matching_possibles) - )) - in*) - let new_bound_to = ((match matching_possibles with - [] -> Some(ApplyReloc, None) - | [(bi, ((rl, r, ri), maybe_d))] -> - Some(decision, - (match maybe_d with - Some (def_idx, def, def_item) -> Some { - def_symname = (def.def_symname) - ; def_syment = (def.def_syment) - ; def_sym_scn = (def.def_sym_scn) - ; def_sym_idx = (def.def_sym_idx) - ; def_linkable_idx = def_idx - } - | None -> None - )) - | _ -> failwith ("After linker script, ambiguous bindings for `" ^ (ref1.ref_symname ^ "'")) - )) - in - if not ((Lem.option_equal (Lem.pair_equal (=) (Lem.option_equal (=))) new_bound_to r.maybe_def_bound_to)) then - (*let _ = errln ("Changed binding for reference to `" ^ ref.ref_symname ^ - "' in linkable " ^ (show irec.idx)) - in*) - new_bound_to - else if (Lem.option_equal (Lem.pair_equal (=) (Lem.option_equal (=))) new_bound_to None) then failwith "really need a decision by now" - else new_bound_to - )) - - (* if irec.fname = "libc.a(__uClibc_main.os)" - && irec.isec.elf64_section_name_as_string = ".data.rel.local" - then - let _ = errln ("Saw the bugger: " ^ (match r.maybe_def_bound_to with - Just(decision, Just(sd)) -> show sd.def_syment - | _ -> "(not complete)" - end)) - in r.maybe_def_bound_to - else r.maybe_def_bound_to - *) - } - )) - ) (* match maybe_reloc *) - ) (* match tag *) - ) ((Pset.from_list (pairCompare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))) compare) ranges_and_tags))) (* end mapMaybe fn *) - in - let isec_sz = (irec.isec.elf64_section_size) in - let maybe_el_sz = (el.length1) in - let contents_sz = (length el.contents) in - let (actual_sz, padded_contents) = - ((match maybe_el_sz with - Some el_sz -> - let diff = (Nat_big_num.sub_nat el_sz contents_sz) in - if Nat_big_num.less diff(Nat_big_num.of_int 0) then - (* contents greater than what the el says, so chop the end off *) - (*let _ = Missing_pervasives.errln ("Warning: size mismatch for section " ^ irec.isec.elf64_section_name_as_string ^ - " from " ^ irec.fname) - in*) - (el_sz, take0 el_sz el.contents) - else (el_sz, List.rev_append (List.rev el.contents) (replicate0 diff None)) - | None -> - if not (Nat_big_num.equal (length el.contents) isec_sz) - then failwith "input section size not equal to its content pattern length" - else (isec_sz, el.contents) - )) - in - (*let _ = errln ("Saw first 20 bytes of section " ^ irec.isec.elf64_section_name_as_string ^ - " from " ^ irec.fname ^ " as " ^ (show (take 20 padded_contents))) - in*) - (actual_sz, padded_contents, new_ranges_and_tags) - | _ -> failwith "impossible: no such element" - ) (* match Map.lookup idstr img.elements *) - ) (* match maybe_secname *) - | IncludeCommonSymbol(retain_pol, fname1, linkable_idx, def, img2) -> - (*let _ = errln ("Including common symbol called `" ^ def.def_symname ^ "'") - in*) - (* We want to get the common symbol as a byte pattern *) - let sz = (Ml_bindings.nat_big_num_of_uint64 def.def_syment.elf64_st_size) - in - let content = (Missing_pervasives.replicate0 sz (Some(Char.chr (Nat_big_num.to_int (Nat_big_num.of_int 0))))) - in - (*let _ = Missing_pervasives.outln (make_line "COMMON" (hex_string_of_natural comp_addr) - (hex_string_of_natural sz) fname) - in*) - (sz, content,(Pset.from_list (pairCompare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))) compare) [(Some(secname1, ( Nat_big_num.sub_nat comp_addr output_section_start_addr, sz)), SymbolDef({ - def_symname = (def.def_symname) - ; def_syment = (def.def_syment) - ; def_sym_scn = (def.def_sym_scn) - ; def_sym_idx = (def.def_sym_idx) - ; def_linkable_idx = linkable_idx - }))])) -(* | Hole(AddressExprFn f) -> - let next_addr = f addr (AllocatedSectionsMap outputs_by_name) - in - let n = next_addr - addr - in - let content = Missing_pervasives.replicate n Nothing - in - let _ = Missing_pervasives.outln (make_line "*fill*" (hex_string_of_natural comp_addr) - (hex_string_of_natural n) - "") - in - (next_addr - addr, content, {}) *) - | ProvideSymbol(pol, name1, (size2, info, other)) -> - (*let _ = errln ("Creating symbol definition named `" ^ name ^ "' in output section `" ^ secname ^ "'") - in*) - let symaddr = accum_current_addr (* FIXME: support others *) - in - (*let _ = Missing_pervasives.outln (make_line "" (hex_string_of_natural symaddr) "" ("PROVIDE (" ^ name ^ ", .)")) - in*) - (Nat_big_num.of_int (* sz *)0, (* comp_el_pat *) [],(Pset.from_list (pairCompare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))) compare) [( - Some(secname1, (( Nat_big_num.sub_nat symaddr output_section_start_addr),Nat_big_num.of_int 0)), - SymbolDef(symbol_def_for_provide_symbol name1 size2 info other control_script_linkable_idx) - )]) - ) - )) (* match comp_el_pat *) - in - (*let _ = errln ("Appending byte pattern to section " ^ secname ^ ", first 20 bytes: " ^ - (show (take 20 comp_el_pat))) - in*) - let new_content = (append_to_byte_pattern_at_offset ( Nat_big_num.sub_nat comp_addr output_section_start_addr) accum_pat comp_el_pat) - in - let new_addr = (Nat_big_num.add comp_addr sz) - in - let new_meta = (Pset.(union) accum_meta this_el_meta) - in - (new_content, new_addr, new_meta) - )) ([], output_section_start_addr,(Pset.from_list (pairCompare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))) compare) [])) (list_combine comp comp_addrs)) - in - let concat_sec_el = ({ - Memory_image.startpos = (Some(output_section_start_addr)) - ; Memory_image.length1 = (Some(size2)) - ; Memory_image.contents = concatenated_content - }) - in - (*let _ = Missing_pervasives.outln "" in*) - (* Make a new element in the image, also transferring metadata from input elements - * as appropriate. *) - let new_by_range_list = - ((Some(secname1, (Nat_big_num.of_int 0, size2)), FileFeature(ElfSection(Nat_big_num.of_int (* We don't yet konw where this'll come in the output file, so ... *) (* scn_idx *)0, - { elf64_section_name =(Nat_big_num.of_int 0) (* ignored *) - ; elf64_section_type = (output_section_type comp) - ; elf64_section_flags = (output_section_flags comp) - ; elf64_section_addr =(Nat_big_num.of_int 0) (* ignored -- covered by element *) - ; elf64_section_offset =(Nat_big_num.of_int 0) (* ignored -- will be replaced when file offsets are assigned *) - ; elf64_section_size =(Nat_big_num.of_int 0) (* ignored *) - ; elf64_section_link =(Nat_big_num.of_int 0) (* HMM *) - ; elf64_section_info =(Nat_big_num.of_int 0) (* HMM *) - ; elf64_section_align = (alignof_output_section comp) - ; elf64_section_entsize =(Nat_big_num.of_int 0) (* HMM *) - ; elf64_section_body = Byte_sequence.empty (* ignored *) - ; elf64_section_name_as_string = secname1 (* can't rely on this being ignored *) - } - ))) :: Pset.elements new_range_tag_pairs) - in - (*let _ = errln ("Metadata for new section " ^ secname ^ " consists of " ^ (show (length new_by_range_list)) ^ " tags.") - in*) - let new_by_range = (List.fold_left (fun m -> fun (maybe_range, tag) -> - let new_s = (Pset.add (maybe_range, tag) m) - in - (* let _ = errln ("Inserting an element into by_range; before: " ^ (show (Set.size m)) ^ "; after: " ^ (show (Set.size new_s))) - in *) - new_s - ) acc_img.by_range new_by_range_list) - in - let new_by_tag = (by_tag_from_by_range - (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) instance_Basic_classes_SetType_var_dict new_by_range) - in - let _ = - (let section_tags_bare = (List.filter (fun (maybe_range, tag) -> - (match tag with - | FileFeature(ElfSection(idx1, isec1)) -> true - | _ -> false - )) (Pset.elements new_by_range)) - in - (* errln ("Total metadata now includes " ^ (show (length section_tags_bare)) ^ " sections; are by_range and " - ^ "by_tag consistent? " ^ (show (new_by_tag = by_tag_from_by_range new_by_range))) *) ()) - in - (* this expression is the return value of add_output_section *) - ( Nat_big_num.add - (* new_pos *) output_section_start_addr size2, - (* new_acc *) { - elements = (Pmap.add secname1 concat_sec_el acc_img.elements) - (* tag it as a section, and transfer any tags *) - ; by_range = (* let _ = errln ("Returning from add_output_section a by_range with " ^ - (show (Set.size new_by_range))) in *) new_by_range - ; by_tag = new_by_tag - }, - (* sec_sz *) size2, - (* replacement_output_sec *) (OutputSectionSpec (guard, Some(output_section_start_addr), secname1, comp)) - ) - )) (* end add_output_section *) - in - (match script1 with - [] -> (acc, (AllocatedSectionsMap outputs_by_name)) - | (element1, el_idx) :: more_elements_and_idx -> - let do_nothing = (acc, pos, (AllocatedSectionsMap outputs_by_name)) in - let (new_acc, new_pos, new_outputs_by_name) = - ((match element1 with - DefineSymbol(symdefpol, name1, (symsize, syminfo, symother)) -> - (* We've already added this to the output composition. *) - do_nothing - | AdvanceAddress(AddressExprFn advance_fn_ref) -> - let advance_fn = -((match Pmap.lookup advance_fn_ref alloc_map with - | Some m -> m - | None -> failwith "alloc_map invariant failure" - )) - in - let new_pos = (advance_fn pos (AllocatedSectionsMap outputs_by_name)) - in - (acc, new_pos, (AllocatedSectionsMap outputs_by_name)) - (* FIXME: the allocated sections map is the subset of the outputs_by_name map - * that has been allocated -- meaning *both* sized *and* placed. - * Since we're a multi-pass interpreter, we've sized everything already, but - * only a subset has been placed. So we need to weed out all elements from - * outputs_by_name that don't correspond to a section in the accumulated image. - * We should probably include the section's range_tag in the allocated_sections_map, - * which would force us to do this, but at the moment neither of these is done. *) - | MarkAndAlignDataSegment(maxpagesize1, commonpagesize1) -> - (* GNU linker manual says: - - "DATA_SEGMENT_ALIGN(MAXPAGESIZE, COMMONPAGESIZE) - is equivalent to either - (ALIGN(MAXPAGESIZE) + (. & (MAXPAGESIZE - 1))) - or - (ALIGN(MAXPAGESIZE) + (. & (MAXPAGESIZE - COMMONPAGESIZE))) - depending on whether the latter uses fewer COMMONPAGESIZE sized - pages for the data segment (area between the result of this - expression and `DATA_SEGMENT_END') than the former or not. If the - latter form is used, it means COMMONPAGESIZE bytes of runtime - memory will be saved at the expense of up to COMMONPAGESIZE wasted - bytes in the on-disk file." - - In other words, we're marking the beginning of the data segment - by aligning our position upwards by an amount that - - - guarantees we're on a new page... - - - ... but (option 1) at an address that's congruent, modulo the max page size - (e.g. for 64kB maxpage, 4kB commonpage, we AND with 0xffff) - - - ... (option 2) at an offset that's at the commonpagesize boundary - immediately preceding the lowest congruent address - (e.g. for 64kB maxpage, 4kB commonpage, we AND with 0xf000, - so if we're at pos 0x1234, we bump up to 0x11000). - - FIXME: - - The GNU linker seems to bump up to 0x12000 here, not 0x11000. - Specifically, - - DATA_SEGMENT_ALIGN (0x200000, 0x1000) - - bumps 0x4017dc up to 0x602000. - - This is indeed better, because it allows the next section - to be output without a big gap in the file. - - LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 - 0x00000000000017dc 0x00000000000017dc R E 200000 - LOAD 0x0000000000002000 0x0000000000602000 0x0000000000602000 - 0x0000000000000120 0x0000000000000ce8 RW 200000 - - ... whereas if the second LOAD began at address 0x601000, - the file offset of its first section would have to be 0x11000. - - So what *should* the formula be? - It needs to calculate the next address which - - - is a commonpagesize boundary; - - - is minimally >= the current address, modulo the commonpagesize - - - is minimally >= the current address, modulo the maxpagesize. - - The AND operation gives us something that is minimally *below* - the commonpagesize boundary. I think we need to add COMMONPAGESIZE. - - The code does this (in ldexp.c around line 478 as of binutils 2.25): - - expld.result.value = align_n (expld.dot, maxpage); - /* omit relro phase */ - if (expld.dataseg.phase == exp_dataseg_adjust) - { - if (commonpage < maxpage) - expld.result.value += ((expld.dot + commonpage - 1) - & (maxpage - commonpage)); - } - else - { - expld.result.value += expld.dot & (maxpage - 1); - - Which amounts to: - - 1. first, align up to maxpage. So for our example, we're now 0x10000. - or for our real example, we're now 0x600000 - - THEN since the first phase (expld_dataseg_none) - hits the final "else" case, - we immediately restore the modulus of the address, - giving 0x60188c. - or 0x6019ac the second time around (FIXME: why two?) - - 2. next, on the relevant phase (pass) of the script interpreter, - i.e. OPTION 2 - if commonpage < maxpage, - bump up the *non-maxpage-aligned non-modulo-restored* address - by - (. + commonpage - 1) & (maxpage - commonpage) - - i.e. for our example earlier - (0x01234 + 0x1000 - 1) & (0xf000) - = - 0x02233 & 0xf000 - = - 0x02000 - - i.e. for our real example - (0x4019ac + 0x1000 - 1) & (0x1ff000) - = - 0x4019ac + 0x1000 - 1) & 0x1ff000 - = - 0x002000 - - 3. OPTION 1 is implemented by the trailing "else {" - -- it restores the modulus. - - So the problem with our original logic (below) was that - it did what the manual says, not what the code does. - Specifically, the code for option 2 does - - (. + commonpagesize - 1) & (maxpagesize - commonpagesize) - - and NOT simply - - . & (maxpagesize - commonpagesize). - - FIXME: report this bug. - - - Note that intervening commands can do arbitrary things to the location - counter, so we can't do any short-cut arithmetic based on section sizes; - we actually have to run the layout procedure til we hit the end of the - data segment, and then see how we do. - - We run this function *forward* with the first option on a subset - of the script ending with the end of the data segment. - We then see what comes back. - - *) - (* let num_pages_used *) - (*let _ = errln ("Option 1 congruence add-in from pos 0x" ^ (hex_string_of_natural pos) ^ ", maxpagesize 0x" ^ - (hex_string_of_natural maxpagesize) ^ " is 0x" ^ (hex_string_of_natural (natural_land pos (maxpagesize - 1)))) - in*) - let option1 = (Nat_big_num.add (align_up_to maxpagesize1 pos) (Nat_big_num.bitwise_and pos ( Nat_big_num.sub_nat maxpagesize1(Nat_big_num.of_int 1)))) - in - (*let _ = errln ("Mark/align data segment: option 1 is to bump pos to 0x" ^ (hex_string_of_natural option1)) - in*) - let option2 = (Nat_big_num.add (align_up_to maxpagesize1 pos) (Nat_big_num.bitwise_and ( Nat_big_num.sub_nat (Nat_big_num.add pos commonpagesize1)(Nat_big_num.of_int 1)) ( Nat_big_num.sub_nat maxpagesize1 commonpagesize1))) - in - (*let _ = errln ("Mark/align data segment: option 2 is to bump pos to 0x" ^ (hex_string_of_natural option2)) - in*) - let data_segment_endpos = (fun startpos1 -> - (* run forward from here until MarkDataSegmentEnd, - * accumulating the actually-made outputs by name and their sizes *) - let (endpos, _) = (List.fold_left (fun (curpos, seen_end) -> fun (new_script_item, new_script_item_idx) -> - (*let _ = errln ("Folding at pos 0x" ^ (hex_string_of_natural curpos)) - in*) - if seen_end - then (curpos, true) - else let (newpos, new_seen) = ((match new_script_item with - | MarkDataSegmentEnd -> - (*let _ = errln "data segment end" - in*) - (* break the loop early here *) - (curpos, true) - | OutputSection(outputguard, maybe_expr, name1, sub_elements) -> - (*let _ = errln ("output section " ^ name) - in*) - let maybe_found = (Pmap.lookup name1 outputs_by_name) - in - let (OutputSectionSpec (guard, addr, secname1, comp), seen_script_el_idx) = ((match maybe_found with - Some (f, seen_script_el_idx) -> (f, seen_script_el_idx) - | None -> failwith "internal error: output section not found" - )) - in - (* Sometimes a given output section name, say .eh_frame, can come from multiple - * script elements with disjoint guard conditions (only_if_ro and only_if_rw, say). - * Only one of them will actually be selected when the guard is being evaluated. - * So when we "replay" the sections' output here, we want to skip the ones whose - * guards were false. The way we implement this is to store the originating script - * element idx in the allocated_output_sections map. We can test that against our - * current script element_idx here *) - let replay_output = ( Nat_big_num.equal seen_script_el_idx el_idx) - in - if replay_output - then ( - let unaligned_start_addr = curpos - in - let start_addr = (align_up_to (alignof_output_section comp) unaligned_start_addr) - in - let (end_addr, comp_addrs) = (do_output_section_layout_starting_at_addr start_addr (AllocatedSectionsMap outputs_by_name) comp) - in - let size2 = (Nat_big_num.sub_nat end_addr start_addr) - in - (end_addr, (* seen_end *) false) - ) - else (curpos, (* seen_end *) false) - | AdvanceAddress(AddressExprFn advance_fn_ref) -> - (*let _ = errln "Advance address" - in*) - let advance_fn = -((match Pmap.lookup advance_fn_ref alloc_map with - | Some m -> m - | None -> failwith "alloc_map invariant failed" - )) - in - let new_pos = (advance_fn curpos (AllocatedSectionsMap outputs_by_name)) - in - (new_pos, false) - | _ -> (curpos, seen_end) - )) - in - if Nat_big_num.less newpos curpos then failwith "went backwards" else (newpos, new_seen) - ) (startpos1, false) more_elements_and_idx) - in endpos - ) - in - let endpos_option1 = (data_segment_endpos option1) - in - let endpos_option2 = (data_segment_endpos option2) - in - (*let _ = errln ("Mark/align data segment: option 1 gives an endpos of 0x" ^ (hex_string_of_natural endpos_option1)) - in*) - (*let _ = errln ("Mark/align data segment: option 2 gives an endpos of 0x" ^ (hex_string_of_natural endpos_option2)) - in*) - let npages = (fun startpos1 -> (fun endpos -> Nat_big_num.div - ( Nat_big_num.sub_nat(align_up_to commonpagesize1 endpos) - (round_down_to commonpagesize1 startpos1)) commonpagesize1 - )) - in - let npages_option1 = (npages option1 endpos_option1) - in - let npages_option2 = (npages option2 endpos_option1) - in - (*let _ = errln ("Mark/align data segment: option 1 uses " ^ (show npages_option1) ^ " COMMONPAGESIZE-sized pages") - in*) - (*let _ = errln ("Mark/align data segment: option 2 uses " ^ (show npages_option2) ^ " COMMONPAGESIZE-sized pages") - in*) - if Nat_big_num.less npages_option1 npages_option2 - then (*let _ = errln "Choosing option 1" in*) (acc, option1, (AllocatedSectionsMap outputs_by_name)) - else (*let _ = errln "Choosing option 2" in*) (acc, option2, (AllocatedSectionsMap outputs_by_name)) - | MarkDataSegmentEnd -> do_nothing - | MarkDataSegmentRelroEnd(*(fun_from_secs_to_something)*) -> do_nothing - | OutputSection(outputguard, maybe_expr, name1, sub_elements) -> - (* Get the composition we computed earlier, and actually put it in - * the image, assigning an address to it. *) - let maybe_found = (Pmap.lookup name1 outputs_by_name) - in - let (found, seen_script_el_idx) = ((match maybe_found with - Some (f, saved_idx) -> (f, saved_idx) - | None -> failwith "internal error: output section not found" - )) - in - let (OutputSectionSpec (guard, addr, secname1, comp)) = found - in - (* let next_free_section_idx = 1 + naturalFromNat (Map.size outputs_by_name) - in *) - let count_sections_in_image = (fun img2 -> ( - let (section_tags, section_ranges) = (elf_memory_image_section_ranges img2) - in - let section_tags_bare = (Lem_list.map (fun tag -> - (match tag with - | FileFeature(ElfSection(idx1, isec1)) -> true - | _ -> false - )) section_tags) - in - length section_tags_bare - )) - in - (* Do we actually want to add an output section? Skip empty sections. - * CARE: we actually want to heed the proper ld semantics for empty sections - * (e.g. ". = ." will force output). From the GNU ld manual: - - The linker will not normally create output sections with no contents. - This is for convenience when referring to input sections that may or - may not be present in any of the input files. For example: - .foo : { *(.foo) } - will only create a `.foo' section in the output file if there is a - `.foo' section in at least one input file, and if the input sections - are not all empty. Other link script directives that allocate space in - an output section will also create the output section. So too will - assignments to dot even if the assignment does not create space, except - for `. = 0', `. = . + 0', `. = sym', `. = . + sym' and `. = ALIGN (. != - 0, expr, 1)' when `sym' is an absolute symbol of value 0 defined in the - script. This allows you to force output of an empty section with `. = - .'. - - The linker will ignore address assignments ( *note Output Section - Address::) on discarded output sections, except when the linker script - defines symbols in the output section. In that case the linker will - obey the address assignments, possibly advancing dot even though the - section is discarded. - - * It follows that we might discard the output section, - * but *retain* the symbol definitions within it, - * and keep the dot-advancements that - * In other words, we care about two things: - * - * -- whether there are any non-empty input sections, *or* - * non-excluded assignments to dot, inside the composition: - * this controls whether the section is output - - * -- whether the script defines symbols in the section; if so - * then *even if the section is discarded* - * we must honour the address assignments, - * which means using the ending address of do_output_section_layout_starting_at_addr, - * *and* - * we must retain the symbol definitions (which now could - * end up going in some other section? HMM...) - *) - let comp_element_allocates_space = (fun comp_el -> (match comp_el with - IncludeInputSection(_, irec) -> Nat_big_num.greater - (*let _ = errln ("Saw an input section named `" ^ irec.isec.elf64_section_name_as_string ^ - "' of size " ^ (show irec.isec.elf64_section_size)) - in*) - irec.isec.elf64_section_size(Nat_big_num.of_int 0) - | IncludeCommonSymbol(retain_pol, fname1, idx1, def, img2) -> Nat_big_num.greater -(Ml_bindings.nat_big_num_of_uint64 def.def_syment.elf64_st_size)(Nat_big_num.of_int 0) - | ProvideSymbol(pol, name1, spec) -> true (* HACK: what else makes sense here? *) - | Hole(AddressExprFn(address_fn_ref)) -> - let address_fn = -((match Pmap.lookup address_fn_ref alloc_map with - | Some m -> m - | None -> failwith "alloc_map invariant failed" - )) - in - let assignment_is_excluded = (fun f -> - (* really makes you wish you were programming in Lisp *) - let always_gives_0 = - ( Nat_big_num.equal(f(Nat_big_num.of_int 0) (AllocatedSectionsMap outputs_by_name))(Nat_big_num.of_int 0) - && Nat_big_num.equal (f(Nat_big_num.of_int 42) (AllocatedSectionsMap outputs_by_name))(Nat_big_num.of_int 0)) (* FIXME: this is wrong *) - in - let always_gives_dot = - ( Nat_big_num.equal(f(Nat_big_num.of_int 0) (AllocatedSectionsMap outputs_by_name))(Nat_big_num.of_int 0) - && Nat_big_num.equal (f(Nat_big_num.of_int 42) (AllocatedSectionsMap outputs_by_name))(Nat_big_num.of_int 42)) (* FIXME: this is wrong *) - in - (* FIXME: what are the semantics of function equality in Lem? *) - always_gives_0 || (always_gives_dot (*&& (AddressExprFn(f)) <> assign_dot_to_itself*) (* FIXME DPM: almost certainly not what is meant... *))) - in - not (assignment_is_excluded address_fn) - )) - in - let section_contains_non_empty_inputs = -(List.exists comp_element_allocates_space comp) - in - (* See note in MarkDataSegmentEnd case about script element idx. Short version: - * multiple output section stanzas, for a given section name, may be in the script, - * but only one was activated by the section composition pass. Ignore the others. *) - let do_output = (( Nat_big_num.equal seen_script_el_idx el_idx) && section_contains_non_empty_inputs) - in - if not do_output then - (*let _ = errln ("At pos 0x" ^ (hex_string_of_natural pos) ^ ", skipping output section " ^ name ^ - " because " ^ (if not section_contains_non_empty_inputs - then "it contains no non-empty inputs" - else "it was excluded by its output guard")) - in*) - (acc, pos, (AllocatedSectionsMap outputs_by_name)) - else ( - (* let _ = errln ("Before adding output section, we have " ^ (show (count_sections_in_image acc)) - ^ " sections.") - in *) - let (new_pos, new_acc, sec_sz, replacement_output_sec) - = (add_output_section ((* next_free_section_idx, *) pos, acc) found) - in - (*let _ = errln ("At pos 0x" ^ (hex_string_of_natural pos) ^ ", adding output section " ^ name ^ - " composed of " ^ (show (length comp)) ^ " items, new pos is 0x" ^ (hex_string_of_natural new_pos)) - in*) - (* let _ = errln ("Received from add_output_section a by_range with " ^ (show (Set.size new_acc.by_range)) - ^ " metadata records of which " ^ (show (Set.size { - (r, t) - | forall ((r, t) IN new_acc.by_range) - | match t with FileFeature(ElfSection(x)) -> true | _ -> false end - } - )) ^ " are ELF sections; one more time: " ^ (show (Set.size { - (t, r) - | forall ((t, r) IN new_acc.by_tag) - | match t with FileFeature(ElfSection(x)) -> true | _ -> false end - } - )) ^ "; count_sections_in_image says " ^ (show ( - length (Multimap.lookupBy Memory_image_orderings.tagEquiv (FileFeature(ElfSection(0, null_elf64_interpreted_section))) new_acc.by_tag) - )) - ) - in *) - (* let _ = errln ("After adding output section, we have " ^ (show (count_sections_in_image new_acc)) - ^ " sections.") - in *) - (new_acc, new_pos, (AllocatedSectionsMap (Pmap.add name1 (replacement_output_sec, el_idx) (Pmap.remove name1 outputs_by_name)))) - ) - | DiscardInput(selector) -> do_nothing - | InputQuery(retainpol, sortpol, selector) -> do_nothing - )) - in - (* recurse *) - build_image alloc_map new_acc new_pos new_outputs_by_name bindings_by_name more_elements_and_idx control_script_linkable_idx linker_defs_by_name - )) - -(* -let rec consecutive_commons rev_acc l = - match l with - [] -> reverse rev_acc - | IncludeCommonSymbol(pol, fname, def, img) :: rest -> - consecutive_commons ((pol, fname, def, img) :: rev_acc) rest - | _ -> reverse rev_acc -end -*) - -(*val default_place_orphans : input_output_assignment -> list input_spec -> input_output_assignment*) -let default_place_orphans (discards, outputs) inputs:(input_spec)list*(output_section_spec*Nat_big_num.num)list= -( - (* Try to emulate the GNU linker. - * Its docs say: - - "It attempts to place orphan sections after - non-orphan sections of the same attribute, such as code vs data, - loadable vs non-loadable, etc. If there is not enough room to do this - then it places at the end of the file. - - - For ELF targets, the attribute of the section includes section type - as well as section flag." - - * It places the .tm_clone_table orphan - - [ 9] .tm_clone_table PROGBITS 0000000000000000 00000160 - 0000000000000000 0000000000000000 WA 0 0 8 - - as - - .data 0x0000000000602120 0x0 crtend.o - .data 0x0000000000602120 0x0 crtn.o - - .tm_clone_table - 0x0000000000602120 0x0 - .tm_clone_table - 0x0000000000602120 0x0 crtbeginT.o - .tm_clone_table - 0x0000000000602120 0x0 crtend.o - - .data1 - *(.data1) - 0x0000000000602120 _edata = . - - i.e. between .data and .data1. In the script: - - .got.plt : { *(.got.plt) *(.igot.plt) } - .data : - { - *(.data .data.* .gnu.linkonce.d.* ) - SORT(CONSTRUCTORS) - } - .data1 : { *(.data1) } - _edata = .; PROVIDE (edata = .); - . = .; - __bss_start = .; - - i.e. no clear reason for why between .data and .data1. In the code: - - (see elf32em.c line 1787 in binutils 2.25) - - ... the key bit of code is as follows. - - place = NULL; - if ((s->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0) - place = &hold[orphan_nonalloc]; - else if ((s->flags & SEC_ALLOC) == 0) - ; - else if ((s->flags & SEC_LOAD) != 0 - && ((iself && sh_type == SHT_NOTE) - || (!iself && CONST_STRNEQ (secname, ".note")))) - place = &hold[orphan_interp]; - else if ((s->flags & (SEC_LOAD | SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) == 0) - place = &hold[orphan_bss]; - else if ((s->flags & SEC_SMALL_DATA) != 0) - place = &hold[orphan_sdata]; - else if ((s->flags & SEC_THREAD_LOCAL) != 0) - place = &hold[orphan_tdata]; - else if ((s->flags & SEC_READONLY) == 0) - place = &hold[orphan_data]; - else if (((iself && (sh_type == SHT_RELA || sh_type == SHT_REL)) - || (!iself && CONST_STRNEQ (secname, ".rel"))) - && (s->flags & SEC_LOAD) != 0) - place = &hold[orphan_rel]; - else if ((s->flags & SEC_CODE) == 0) - place = &hold[orphan_rodata]; - else - place = &hold[orphan_text]; - - - .. we replicate it here. - *)let output_irecs = (List.fold_left (fun acc -> fun outp -> ((match outp with - (OutputSectionSpec(guard, maybe_addr, name1, comp), script_el_idx) -> - let all_irecs = (List.fold_left (fun inner_acc -> fun comp_el -> (match comp_el with - IncludeInputSection(_, irec) -> Pset.add irec inner_acc - | _ -> inner_acc - ))(Pset.from_list compare []) comp) - in - Pset.(union) all_irecs acc - | _ -> acc - )))(Pset.from_list compare []) outputs) - in - let (orphans : input_spec list) = (List.filter (fun inp -> (match inp with - InputSection(irec) -> let v = (not ( Pset.mem irec output_irecs)) - in (*let _ = if v then errln ("Saw an orphan input section: " ^ - irec.secname ^ " in " ^ irec.fname) else () - in*) v - | _ -> false - )) inputs) - in - let place_one_orphan = (fun acc -> fun input -> ( - let irec = ((match input with - InputSection(irec) -> irec - | _ -> failwith "impossible: orphan section is not a section" - )) - in - let (discards, outputs) = acc in - let find_output = (fun maybe_name -> fun maybe_type -> fun flags_must_have -> fun flags_must_not_have -> ( - Missing_pervasives.find_index0 (fun (OutputSectionSpec (guard, maybe_addr, name1, comp), script_el_idx) -> - let flags = (output_section_flags comp) in - (match maybe_name with Some n -> n = name1 | None -> true ) - && ((match maybe_type with Some t -> Nat_big_num.equal (output_section_type comp) t | None -> true ) - && (Pset.for_all (fun x -> flag_is_set x flags) flags_must_have - && Pset.for_all (fun x -> not (flag_is_set x flags)) flags_must_not_have)) - ) outputs - )) - in - let place_after_nonalloc = (find_output None None(Pset.from_list Nat_big_num.compare [])(Pset.from_list Nat_big_num.compare [ shf_alloc ])) in - let place_after_interp = (find_output (Some(".interp")) (Some(sht_progbits))(Pset.from_list Nat_big_num.compare [ shf_alloc ])(Pset.from_list Nat_big_num.compare [])) in - let place_after_bss = (find_output (Some(".bss")) (Some(sht_nobits))(Pset.from_list Nat_big_num.compare [ shf_alloc; shf_write])(Pset.from_list Nat_big_num.compare [])) in - let place_after_rodata = (find_output (Some(".rodata")) (Some(sht_progbits))(Pset.from_list Nat_big_num.compare [ shf_alloc ])(Pset.from_list Nat_big_num.compare [ shf_write ])) in - let place_after_rel = (find_output (Some(".rela.dyn")) (Some(sht_rela))(Pset.from_list Nat_big_num.compare [])(Pset.from_list Nat_big_num.compare [])) in - let place_after_data = (find_output (Some(".data")) (Some(sht_progbits))(Pset.from_list Nat_big_num.compare [ shf_alloc; shf_write ])(Pset.from_list Nat_big_num.compare [])) in - let place_after_text = (find_output (Some(".text")) (Some(sht_progbits))(Pset.from_list Nat_big_num.compare [ shf_alloc; shf_execinstr ])(Pset.from_list Nat_big_num.compare [])) in - let (place_after : Nat_big_num.num option) = ((match input with - InputSection(irec) -> - (* HACK: simulates GNU linker, but this logic ought to go elsewhere *) - if irec.isec.elf64_section_name_as_string = ".note.GNU-stack" then None - else - if not (flag_is_set shf_alloc irec.isec.elf64_section_flags) - && (* not flag_is_set shf_alloc irec.isec.elf64_section_flags *) (* no debugging, for now *) true - then place_after_nonalloc - else (* FIXME: reinstate alloc-debugging case *) - if Nat_big_num.equal irec.isec.elf64_section_type sht_note (* FIXME: replicate iself logic *) - || (irec.isec.elf64_section_name_as_string = ".note") - then place_after_interp - else if Nat_big_num.equal irec.isec.elf64_section_type sht_nobits - then place_after_bss - else (* FIXME: implement thread-local case *) - if not (flag_is_set shf_write irec.isec.elf64_section_flags) - && not (flag_is_set shf_execinstr irec.isec.elf64_section_flags) - then place_after_rodata - else if flag_is_set shf_write irec.isec.elf64_section_flags - && not (flag_is_set shf_execinstr irec.isec.elf64_section_flags) - then place_after_data - else place_after_text - )) - in - let (discards, outputs) = acc in - (match place_after with - Some idx1 -> (* The section exists and has the flags we expected, and is at output idx *) - (discards, mapi (fun i -> fun output -> - (* FIXME: also fix up flags, alignment etc. *) - let (OutputSectionSpec (guard, maybe_addr, name1, comp), script_el_idx) = output in - if Nat_big_num.equal (Nat_big_num.of_int i) idx1 then (OutputSectionSpec(guard, maybe_addr, name1, List.rev_append (List.rev comp) [IncludeInputSection(DefaultKeep, irec)]), script_el_idx) else output - ) outputs - ) - | None -> - (*let _ = errln ("Warning: discarding orphan section `" ^ irec.isec.elf64_section_name_as_string - ^ "' from file `" ^ irec.fname ^ "'") - in*) - ( List.rev_append (List.rev discards) [input], outputs) - ) - )) - in - List.fold_left place_one_orphan (discards, outputs) orphans) - -(*val interpret_linker_control_script : - address_expr_fn_map allocated_sections_map -> - linker_control_script - -> linkable_list - -> natural (* control_script_linkable_idx *) - -> abi any_abi_feature - -> list input_spec - -> (input_spec -> input_spec -> ordering) (* seen ordering *) - -> (input_output_assignment -> list input_spec -> input_output_assignment) (* place orphans *) - -> (Map.map string (list (natural * binding))) (* initial_bindings_by_name *) - -> (elf_memory_image * Map.map string (list (natural * binding)))*) -let interpret_linker_control_script alloc_map script1 linkables control_script_linkable_idx a inputs seen_ordering place_orphans initial_bindings_by_name:(any_abi_feature)annotated_memory_image*((string),((Nat_big_num.num*binding)list))Pmap.map= - (let labelled_script = (label_script script1) - in - (*let _ = List.mapi (fun i -> fun input -> - errln ("Input " ^ (show i) ^ " is " ^ - match input with - InputSection(inp) -> - "input section, name `" ^ inp.secname ^ - "', from file `" ^ inp.fname ^ "' (linkable idx " ^ (show inp.idx) ^ ")" - | Common(idx, symname, img, def) -> - "common symbol `" ^ symname ^ "'" - end - ) - ) inputs - in*) - let (discards_before_orphans, outputs_before_orphans) - = (assign_inputs_to_output_sections ([], [])(Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) [])(Pset.from_list (tripleCompare Nat_big_num.compare Nat_big_num.compare Nat_big_num.compare) []) inputs None None seen_ordering labelled_script) - in - (* place orphans *) - let (discards, outputs) = (place_orphans (discards_before_orphans, outputs_before_orphans) inputs) - in - (* In assigning inputs to outputs, we may also have defined some symbols. These affect the - * bindings that are formed. So, we rewrite the bindings here. Note that we have to do so here, - * not in the caller, because these extra bindings can affect the reachability calculation - * during GC. *) - let (linker_defs_by_name, (bindings_by_name : ( (string, ( (Nat_big_num.num * binding)list))Pmap.map))) = ( - let (script_defs_by_name : (string, ( (symbol_definition * symbol_def_policy)list)) Pmap.map) - = (List.fold_left (fun acc -> (fun ((OutputSectionSpec (guard, maybe_addr, secname1, comp)), script_el_idx) -> - List.fold_left (fun inner_acc -> fun comp_el -> ( - (match comp_el with - ProvideSymbol(pol, name1, (size2, info, other)) -> - (*let _ = errln ("Linker script defining symbol `" ^ name ^ "'") - in*) - let def = (symbol_def_for_provide_symbol name1 size2 info other control_script_linkable_idx) - in - let v = ((match Pmap.lookup name1 inner_acc with - None -> [(def, pol)] - | Some l -> (def, pol) :: l - )) - in - Pmap.add name1 v inner_acc - | _ -> inner_acc - ) - )) (acc : (string, ( (symbol_definition * symbol_def_policy)list)) Pmap.map) comp - )) (Pmap.empty compare) outputs) - in - (* Now that we've made these definitions, what bindings are affected? - * We also use this opportunity to bind references to linker-generated symbols, - * such as _GLOBAL_OFFSET_TABLE_, since any definitions of these should now be merged - * into our inputs. *) - (* bit of a HACK: reconstruct the linkable img and idx from the input items *) - let idx_to_img = (List.fold_left (fun acc_m -> fun item -> - (match item with - Common(idx1, _, img2, symdef) -> Pmap.add idx1 img2 (Pmap.remove idx1 acc_m) - | InputSection(irec) -> Pmap.add irec.idx irec.img (Pmap.remove irec.idx acc_m) - ) - ) (Pmap.empty Nat_big_num.compare) inputs) - in - let (lowest_idx : Nat_big_num.num) = ((match Pset.min_elt_opt (Pmap.domain idx_to_img) - with Some x -> x - | None -> failwith "internal error: no linkable items" - )) - in - let first_linkable_item = ((match linkables with x :: more -> x | _ -> failwith "internal error: no linkables" )) - in - let (control_script_input_item : input_item) = ( - "(built-in control script)", - ControlScript, - (BuiltinControlScript, [Builtin]) - ) - in - let (control_script_linkable_item : linkable_item) = ( - ControlScriptDefs, control_script_input_item, - { item_fmt = "" - ; item_check_sections = false - ; item_copy_dt_needed = false - ; item_force_output = true - } - ) - in - let updated_bindings_and_new_defs = (Pmap.map (fun b_list_initial -> - Lem_list.map (fun (b_idx, b_initial) -> - let ((iref_idx, iref, iref_item), maybe_idef) = b_initial - in - (*let _ = errln ("Looking for linker script or linker-generated defs of symbol `" ^ iref.ref_symname ^ "'") - in*) - let possible_script_defs = ((match Pmap.lookup iref.ref_symname script_defs_by_name with - Some l -> l - | None -> [] - )) - in - let (possible_linker_generated_def : symbol_definition option) = - (if a.symbol_is_generated_by_linker iref.ref_symname - then (* can we find a definition by this name? *) - ((match Pmap.lookup lowest_idx idx_to_img with - None -> failwith "no lowest idx found" - | Some img2 -> - (match List.filter (fun def -> def.def_symname = iref.ref_symname) (defined_symbols - instance_Basic_classes_Ord_Abis_any_abi_feature_dict instance_Abi_classes_AbiFeatureTagEquiv_Abis_any_abi_feature_dict img2) with - [] -> None - | [def] -> Some(def) - | _ -> failwith ("first linkable has multiple defs of name `" ^ (iref.ref_symname ^ "'")) - ) - )) - else None) - in - (* If the binding has no def, we always use the def we have. - * If the binding has a def, we use our def only if the policy is AlwaysDefine. *) - (*let _ = errs ("Do we override binding " ^ (show b_idx) ^ ", symbol named `" ^ - iref.ref_symname ^ "'? ") - in*) - (* FIXME: check real semantics of defining symbols like '_GLOBAL_OFFSET_TABLE_' in linker script or input objects. - * This is really just a guess. *) - let new_b_and_maybe_new_def = ((match (maybe_idef, possible_script_defs, possible_linker_generated_def) with - | (_, [], None) -> (*let _ = errln "no" in *) - (((iref_idx, iref, iref_item), maybe_idef), None) - | (None, [], Some(def)) -> (*let _ = errln "yes (was undefined)" in*) - (((iref_idx, iref, iref_item), Some(lowest_idx, def, first_linkable_item)), Some(def)) - | (_, [(def, AlwaysDefine)], _) -> (*let _ = errln "yes (linker script provides unconditional def)" in*) - (((iref_idx, iref, iref_item), Some (control_script_linkable_idx, def, control_script_linkable_item)), Some(def)) - | (Some existing_def, ([(def, ProvideIfUsed)]), _) -> (*let _ = errln "no" in*) - (((iref_idx, iref, iref_item), Some existing_def), None) - | (None, [(def, ProvideIfUsed)], _) -> (*let _ = errln "yes (linker script provides if-used def)" in*) - (((iref_idx, iref, iref_item), Some (control_script_linkable_idx, def, control_script_linkable_item)), Some(def)) - | (_, pair1 :: pair2 :: more, _) -> (*let _ = errln "error" in*) - failwith "ambiguous symbol binding in linker control script" - )) - in - (b_idx, new_b_and_maybe_new_def) - ) b_list_initial - ) initial_bindings_by_name) - in - let (new_symbol_defs_map : (string, ( ( symbol_definition option)list)) Pmap.map) - = (Pmap.map (fun b_pair_list -> Lem_list.map (fun (b_idx, (new_b, maybe_new_def)) -> maybe_new_def) b_pair_list) updated_bindings_and_new_defs) - in - let (new_symbol_defs_by_name : (string, ( symbol_definition list)) Pmap.map) = (Pmap.map - (fun v -> Lem_list.mapMaybe id0 v) new_symbol_defs_map) - in - (* { List.mapMaybe id maybe_def_list | forall ((_, maybe_def_list) IN (Map.toSet new_symbol_defs_map)) | true } - in*) - (*let new_symbol_defs = List.concat (Set_extra.toList new_symbol_def_list_set) - in*) - let updated_bindings = (Pmap.map (fun b_pair_list -> Lem_list.map (fun (b_idx, (new_b, maybe_new_def)) -> (b_idx, new_b)) b_pair_list) updated_bindings_and_new_defs) - in - (new_symbol_defs_by_name, updated_bindings) - ) - in - (*let _ = errln ("For __fini_array_end, we have " ^ - (let all_bs = match Map.lookup "__fini_array_end" bindings_by_name with - Just l -> l - | Nothing -> [] - end - in - ((show (length all_bs)) ^ - " bindings, of which " ^ - (show (length (List.filter (fun (bi, ((ref_idx, ref, ref_item), maybe_def)) -> - match maybe_def with - Just _ -> true - | _ -> false - end - ) all_bs))) ^ " have defs"))) - in*) - let outputs_by_name = - (let insert_fun = (fun m -> (fun (OutputSectionSpec(guard, maybe_addr, name1, compos), script_idx) -> Pmap.add name1 ((OutputSectionSpec (guard, maybe_addr, name1, compos)), script_idx) m)) - in - List.fold_left insert_fun (Pmap.empty compare) outputs) - in - (* Print the link map's "discarded input sections" output. *) - (*let _ = Missing_pervasives.outln "\nDiscarded input sections\n" - in*) - let discard_line = (fun i -> ((match i with - InputSection(s) -> - let lpadded_secname = (" " ^ s.secname) - in - lpadded_secname ^ ((space_padding_and_maybe_newline(Nat_big_num.of_int 16) lpadded_secname) ^ ("0x0000000000000000" (* FIXME *) - ^ (" 0x" ^ ((hex_string_of_natural s.isec.elf64_section_size) ^ (" " - ^ (s.fname ^ "\n")))))) - | Common(idx1, fname1, img2, def) -> "" (* don't print discard lines for discarded commons *) - ))) - in - (*let _ = Missing_pervasives.outs (List.foldl (fun str -> (fun input -> (str ^ (discard_line input)))) "" (reverse discards)) - in*) - let outputs_by_name_after_gc = (compute_def_use_and_gc (AllocatedSectionsMap outputs_by_name)) - in - (*let _ = Missing_pervasives.outs "\nMemory Configuration\n\nName Origin Length Attributes\n*default* 0x0000000000000000 0xffffffffffffffff\n" - in - let _ = Missing_pervasives.outln "\nLinker script and memory map\n" - in*) - (* FIXME: print LOAD and START_GROUP trace *) - let (img2, outputs_by_name_with_position) - = (build_image alloc_map empty_elf_memory_image(Nat_big_num.of_int 0) outputs_by_name_after_gc bindings_by_name labelled_script control_script_linkable_idx linker_defs_by_name) - in - (*let _ = errln ("Final image has " ^ (show (Map.size img.elements)) ^ " elements and " - ^ (show (Set.size img.by_tag)) ^ " metadata tags, of which " ^ ( - let (section_tags, section_ranges) = elf_memory_image_section_ranges img - in - let section_tags_bare = List.map (fun tag -> - match tag with - | FileFeature(ElfSection(idx, isec)) -> (idx, isec) - | _ -> failwith "not section tag" - end) section_tags - in - show (length section_tags_bare) - ) ^ " are sections.") - in*) - (* The link map output for the section/address assignment basically mirrors our notion of - * output section composition. In the following: - - 0x0000000000400000 PROVIDE (__executable_start, 0x400000) - 0x0000000000400190 . = (0x400000 + SIZEOF_HEADERS) - -.interp - *(.interp) - -.note.ABI-tag 0x0000000000400190 0x20 - .note.ABI-tag 0x0000000000400190 0x20 crt1.o - -.note.gnu.build-id - 0x00000000004001b0 0x24 - *(.note.gnu.build-id) - .note.gnu.build-id - 0x00000000004001b0 0x24 crt1.o - -.hash - *(.hash) - -.gnu.hash - *(.gnu.hash) - -... we can see that - - - symbol provision, holes and output sections all get lines - - - each output section appears with its name left-aligned, and its address, - if any, appearing afterwards; if so, the section's total size also follows. - - - each input query is printed verbatim, e.g. "*(.note.gnu.build-id)" - - - underneath this, a line is printed for each input section that was included, - with its address and size. This can spill onto a second line in the usual way. - - - holes are shown as "*fill*" - - - provided symbols are shown as in the linker script source. - - PROBLEM: we don't have the script in source form, so we can't print the queries verbatim. - I should really annotate each query with its source form; when the script is parsed from source, - this can be inserted automatically. For the moment, what to do? I could annotate each script - element manually. For the moment, for diffing purposes, filter out lines with asterisks. - - *) - (img2, bindings_by_name)) diff --git a/lib/ocaml_rts/linksem/main_elf.ml b/lib/ocaml_rts/linksem/main_elf.ml deleted file mode 100644 index c5a31ebe..00000000 --- a/lib/ocaml_rts/linksem/main_elf.ml +++ /dev/null @@ -1,374 +0,0 @@ -(*Generated by Lem from main_elf.lem.*) -(** [main_elf], the main module for the test program of the ELF development. - * Run like so: - * ./main_elf.opt --FLAG BINARY - * where: - * BINARY is an ELF binary - * FLAG is in the set { file-header, program-headers, section-headers, - * dynamic, relocs, symbols } - * - *) - -open Lem_basic_classes -open Lem_function -open Lem_maybe -open Lem_list -open Lem_num -open Lem_string -open Lem_tuple - -open Byte_sequence -open Default_printing -open Error -open Hex_printing -open Missing_pervasives -open Show -open Lem_assert_extra - -open Endianness - -open Elf_dynamic -open Elf_header -open Elf_file -open Elf_program_header_table -open Elf_section_header_table -open Elf_types_native_uint - -open Harness_interface -open Sail_interface - -open Abi_aarch64_relocation - -open Abi_amd64_elf_header -open Abi_amd64_relocation -open Abi_amd64_serialisation - -open Abi_power64_dynamic - -open Abi_x86_relocation - -open Abi_power64_relocation - -open Gnu_ext_dynamic -open Gnu_ext_program_header_table -open Gnu_ext_section_header_table - -open Dwarf - -let default_hdr_bdl:('a ->string)*('b ->string)= - (default_os_specific_print, default_proc_specific_print) - -let default_pht_bdl:('a ->string)*('b ->string)= - (default_os_specific_print, default_proc_specific_print) - -let default_sht_bdl:('b ->string)*('a ->string)*('c ->string)= - (default_os_specific_print, default_proc_specific_print, default_user_specific_print) - - -(* unrolled and made tail recursive for efficiency on large ELF files...*) -(*val chunks : list string -> list (list string) -> list (list string) * nat*) -let rec chunks (ss : string list) (accum : ( string list) list):((string)list)list*int= - ((match ss with - | s1::s2::s3::s4::s5::s6::s7::s8::s9::s10::s11::s12::s13::s14::s15::s16::ss -> - chunks ss ([(s2^s1);(s4^s3);(s6^s5);(s8^s7);(s10^s9);(s12^s11);(s14^s13);(s16^s15)]::accum) - | s1::s2::s3::s4::s5::s6::s7::s8::s9::s10::s11::s12::s13::s14::s15::[] -> - let buff = ([(s2^s1);(s4^s3);(s6^s5);(s8^s7);(s10^s9);(s12^s11);(s14^s13);("00"^s15)]) in - ( List.rev_append (List.rev (List.rev accum)) [buff], 15) - | s1::s2::s3::s4::s5::s6::s7::s8::s9::s10::s11::s12::s13::s14::ss -> - let bits = (replicate0(Nat_big_num.of_int 1) " ") in - let fixed = (intercalate " " bits) in - let buff = (List.rev_append (List.rev [(s2^s1);(s4^s3);(s6^s5);(s8^s7);(s10^s9);(s12^s11);(s14^s13)]) [concatS fixed]) in - ( List.rev_append (List.rev (List.rev accum)) [buff], 14) - | s1::s2::s3::s4::s5::s6::s7::s8::s9::s10::s11::s12::s13::[] -> - let bits = (replicate0(Nat_big_num.of_int 1) " ") in - let fixed = (intercalate " " bits) in - let buff = (List.rev_append (List.rev [(s2^s1);(s4^s3);(s6^s5);(s8^s7);(s10^s9);(s12^s11);("00"^s13)]) [concatS fixed]) in - ( List.rev_append (List.rev (List.rev accum)) [buff], 13) - | s1::s2::s3::s4::s5::s6::s7::s8::s9::s10::s11::s12::[] -> - let bits = (replicate0(Nat_big_num.of_int 2) " ") in - let fixed = (intercalate " " bits) in - let buff = (List.rev_append (List.rev [(s2^s1);(s4^s3);(s6^s5);(s8^s7);(s10^s9);(s12^s11)]) [concatS fixed]) in - ( List.rev_append (List.rev (List.rev accum)) [buff], 12) - | s1::s2::s3::s4::s5::s6::s7::s8::s9::s10::s11::[] -> - let bits = (replicate0(Nat_big_num.of_int 2) " ") in - let fixed = (intercalate " " bits) in - let buff = (List.rev_append (List.rev [(s2^s1);(s4^s3);(s6^s5);(s8^s7);(s10^s9);("00"^s11)]) [concatS fixed]) in - ( List.rev_append (List.rev (List.rev accum)) [buff], 11) - | s1::s2::s3::s4::s5::s6::s7::s8::s9::s10::[] -> - let bits = (replicate0(Nat_big_num.of_int 3) " ") in - let fixed = (intercalate " " bits) in - let buff = (List.rev_append (List.rev [(s2^s1);(s4^s3);(s6^s5);(s8^s7);(s10^s9)]) [concatS fixed]) in - ( List.rev_append (List.rev (List.rev accum)) [buff], 10) - | s1::s2::s3::s4::s5::s6::s7::s8::s9::[] -> - let bits = (replicate0(Nat_big_num.of_int 3) " ") in - let fixed = (intercalate " " bits) in - let buff = (List.rev_append (List.rev [(s2^s1);(s4^s3);(s6^s5);(s8^s7);("00"^s9)]) [concatS fixed]) in - ( List.rev_append (List.rev (List.rev accum)) [buff], 9) - | s1::s2::s3::s4::s5::s6::s7::s8::[] -> - let bits = (replicate0(Nat_big_num.of_int 4) " ") in - let fixed = (intercalate " " bits) in - let buff = (List.rev_append (List.rev [(s2^s1);(s4^s3);(s6^s5);(s8^s7)]) [concatS fixed]) in - ( List.rev_append (List.rev (List.rev accum)) [buff], 8) - | s1::s2::s3::s4::s5::s6::s7::[] -> - let bits = (replicate0(Nat_big_num.of_int 4) " ") in - let fixed = (intercalate " " bits) in - let buff = (List.rev_append (List.rev [(s2^s1);(s4^s3);(s6^s5);("00"^s7)]) [concatS fixed]) in - ( List.rev_append (List.rev (List.rev accum)) [buff], 7) - | s1::s2::s3::s4::s5::s6::[] -> - let bits = (replicate0(Nat_big_num.of_int 5) " ") in - let fixed = (intercalate " " bits) in - let buff = (List.rev_append (List.rev [(s2^s1);(s4^s3);(s6^s5)]) [concatS fixed]) in - ( List.rev_append (List.rev (List.rev accum)) [buff], 6) - | s1::s2::s3::s4::s5::[] -> - let bits = (replicate0(Nat_big_num.of_int 5) " ") in - let fixed = (intercalate " " bits) in - let buff = (List.rev_append (List.rev [(s2^s1);(s4^s3);("00"^s5)]) [concatS fixed]) in - ( List.rev_append (List.rev (List.rev accum)) [buff], 5) - | s1::s2::s3::s4::[] -> - let bits = (replicate0(Nat_big_num.of_int 6) " ") in - let fixed = (intercalate " " bits) in - let buff = (List.rev_append (List.rev [(s2^s1);(s4^s3)]) [concatS fixed]) in - ( List.rev_append (List.rev (List.rev accum)) [buff], 4) - | s1::s2::s3::[] -> - let bits = (replicate0(Nat_big_num.of_int 6) " ") in - let fixed = (intercalate " " bits) in - let buff = (List.rev_append (List.rev [(s2^s1);("00"^s3)]) [concatS fixed]) in - ( List.rev_append (List.rev (List.rev accum)) [buff], 3) - | s1::s2::[] -> - let bits = (replicate0(Nat_big_num.of_int 7) " ") in - let fixed = (intercalate " " bits) in - let buff = (List.rev_append (List.rev [(s2^s1)]) [concatS fixed]) in - ( List.rev_append (List.rev (List.rev accum)) [buff], 2) - | s1::[] -> - let bits = (replicate0(Nat_big_num.of_int 7) " ") in - let fixed = (intercalate " " bits) in - let buff = (List.rev_append (List.rev [("00"^s1)]) [concatS fixed]) in - ( List.rev_append (List.rev (List.rev accum)) [buff], 1) - | [] -> (List.rev accum, 0) - )) - -(*val provide_offsets : (list (list string) * nat) -> list (string * list string)*) -let provide_offsets (ss, ed):(string*(string)list)list= - - (List.rev_append (List.rev (Lem_list.mapi (fun i x -> - let hx = (unsafe_hex_string_of_natural( 7) ( Nat_big_num.mul(Nat_big_num.of_int i)(Nat_big_num.of_int 16))) in - (hx, x)) ss)) (if ed = 0 then - [(unsafe_hex_string_of_natural( 7) ( Nat_big_num.mul(Nat_big_num.of_int (List.length ss))(Nat_big_num.of_int 16)), [])] - else - [(unsafe_hex_string_of_natural( 7) ( Nat_big_num.add( Nat_big_num.mul(Nat_big_num.of_int ( Nat_num.nat_monus(List.length ss)( 1)))(Nat_big_num.of_int 16)) (Nat_big_num.of_int ed)), [])])) - -(*val create_chunks : byte_sequence -> list (string * list string)*) -let create_chunks bs0:(string*(string)list)list= - (let ss = (Lem_list.map (fun x -> - unsafe_hex_string_of_natural( 2) (natural_of_byte x)) - (Byte_sequence.byte_list_of_byte_sequence bs0)) - in - provide_offsets (chunks ss [])) - -(*val print_chunk : string * list string -> string*) -let print_chunk (off, ss):string= - ((match ss with - | [] -> off - | _ -> off ^ (" " ^ concatS (intercalate " " ss)) - )) - -(*val obtain_abi_specific_string_of_reloc_type : natural -> (natural -> string)*) -let obtain_abi_specific_string_of_reloc_type mach:Nat_big_num.num ->string= - (if Nat_big_num.equal mach elf_ma_ppc64 then - string_of_ppc64_relocation_type - else if Nat_big_num.equal mach elf_ma_386 then - string_of_x86_relocation_type - else if Nat_big_num.equal mach elf_ma_aarch64 then - string_of_aarch64_relocation_type - else if Nat_big_num.equal mach elf_ma_x86_64 then - string_of_amd64_relocation_type - (*else if mach = elf_ma_mips then - string_of_mips64_relocation_type*) - else - (fun y->"Cannot deduce ABI")) - -let ( _:unit) = -(let res = -(let (flag, arg) = -((match Ml_bindings.argv_list with - | progname::flag::fname1::more -> (flag, fname1) - | _ -> failwith "usage: main_elf <flag> <fname>" - )) - in - Byte_sequence.acquire arg >>= (fun bs0 -> - repeatM' Elf_header.ei_nident bs0 (read_unsigned_char Endianness.default_endianness) >>= (fun (ident, bs) -> - (match Lem_list.list_index ident( 4) with - | None -> failwith "ELF ident transcription error" - | Some c -> - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string c)) Elf_header.elf_class_32 then - let ret = -(if flag = "--file-header" then - Elf_header.read_elf32_header bs0 >>= (fun (hdr, _) -> - return (Harness_interface.harness_string_of_elf32_file_header hdr)) - else if flag = "--program-headers" then - Elf_file.read_elf32_file bs0 >>= (fun f1 -> - get_elf32_file_section_header_string_table f1 >>= (fun stbl -> - return (Harness_interface.harness_string_of_elf32_program_headers - string_of_gnu_ext_segment_type - (fun x -> - Nat_big_num.to_string x) - f1.elf32_file_header - f1.elf32_file_program_header_table - f1.elf32_file_section_header_table - stbl - bs0))) - else if flag = "--section-headers" then - Elf_file.read_elf32_file bs0 >>= (fun f1 -> - get_elf32_file_section_header_string_table f1 >>= (fun stbl -> - return (Harness_interface.harness_string_of_elf32_section_headers - string_of_gnu_ext_section_type - (fun x -> Nat_big_num.to_string x) - (fun x -> Nat_big_num.to_string x) - f1.elf32_file_header - f1.elf32_file_section_header_table - stbl))) - else if flag = "--relocs" then - Elf_file.read_elf32_file bs0 >>= (fun f1 -> - let print_reloc = (obtain_abi_specific_string_of_reloc_type (Nat_big_num.of_string (Uint32.to_string f1.elf32_file_header.elf32_machine))) in - return (Harness_interface.harness_string_of_elf32_relocs - f1 - print_reloc - bs0)) -(* else if flag = "--symbols" then - Harness_interface.harness_string_of_elf32_syms - f1 - show - show - bs0 *) - else if flag = "--dynamic" then - Elf_file.read_elf32_file bs0 >>= (fun f1 -> - let so = (is_elf32_shared_object_file f1.elf32_file_header) in - return (Harness_interface.harness_string_of_elf32_dynamic_section - f1 - bs0 - gnu_ext_os_additional_ranges - (fun x -> gnu_ext_tag_correspondence_of_tag x) - (fun x -> gnu_ext_tag_correspondence_of_tag x) - (fun x -> string_of_dynamic_tag so x gnu_ext_os_additional_ranges string_of_gnu_ext_dynamic_tag (fun _ -> "proc: from main_elf")) - gnu_ext_elf32_value_of_elf32_dyn - (fun _ _ -> Error.fail "proc: from main_elf"))) - else if flag = "--in-out" then - Elf_file.read_elf32_file bs0 >>= (fun f1 -> - (match Elf_file.bytes_of_elf32_file f1 with - | Fail f -> return f - | Success s -> - let chunks1 = (create_chunks s) in - let lines = (concatS (intercalate "\n" (Lem_list.map print_chunk chunks1))) in - return lines - )) - else if flag = "--debug-dump=info" then - Elf_file.read_elf32_file bs0 >>= (fun f1 -> - get_elf32_file_section_header_string_table f1 >>= (fun stbl -> - return (Dwarf.harness_string_of_elf32_debug_info_section - f1 - bs0 - (*string_of_gnu_ext_section_type - (fun x -> show x) - (fun x -> show x) - f1.elf32_file_header - f1.elf32_file_section_header_table - stbl*) - ))) - else - failwith "Unrecognised flag") - in - ret - else if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string c)) Elf_header.elf_class_64 then - let ret = -(if flag = "--file-header" then - Elf_header.read_elf64_header bs0 >>= (fun (hdr, _) -> - return (Harness_interface.harness_string_of_elf64_file_header hdr)) - else if flag = "--program-headers" then - Elf_file.read_elf64_file bs0 >>= (fun f1 -> - get_elf64_file_section_header_string_table f1 >>= (fun stbl -> - return (Harness_interface.harness_string_of_elf64_program_headers - string_of_gnu_ext_segment_type - (fun x -> - Nat_big_num.to_string x) - f1.elf64_file_header - f1.elf64_file_program_header_table - f1.elf64_file_section_header_table - stbl - bs0))) - else if flag = "--section-headers" then - Elf_file.read_elf64_file bs0 >>= (fun f1 -> - get_elf64_file_section_header_string_table f1 >>= (fun stbl -> - return (Harness_interface.harness_string_of_elf64_section_headers - string_of_gnu_ext_section_type - (fun x -> Nat_big_num.to_string x) - (fun x -> Nat_big_num.to_string x) - f1.elf64_file_header - f1.elf64_file_section_header_table - stbl))) - else if flag = "--relocs" then - Elf_file.read_elf64_file bs0 >>= (fun f1 -> - let print_reloc = (obtain_abi_specific_string_of_reloc_type (Nat_big_num.of_string (Uint32.to_string f1.elf64_file_header.elf64_machine))) in - return (Harness_interface.harness_string_of_elf64_relocs - f1 - print_reloc - bs0)) - (*else if flag = "--symbols" then - Harness_interface.harness_string_of_elf64_syms - f1 - show - show - bs0*) - else if flag = "--dynamic" then - Elf_file.read_elf64_file bs0 >>= (fun f1 -> - let so = (is_elf64_shared_object_file f1.elf64_file_header) in - return (Harness_interface.harness_string_of_elf64_dynamic_section - f1 - bs0 - gnu_ext_os_additional_ranges - (fun x -> gnu_ext_tag_correspondence_of_tag x) - (fun x -> abi_power64_tag_correspondence_of_tag x) (* ABI! *) - (fun x -> string_of_dynamic_tag so x gnu_ext_os_additional_ranges string_of_gnu_ext_dynamic_tag string_of_abi_power64_dynamic_tag) - gnu_ext_elf64_value_of_elf64_dyn - abi_power64_elf64_value_of_elf64_dyn)) (* ABI! *) - else if flag = "--in-out" then - Elf_file.read_elf64_file bs0 >>= (fun f1 -> - (match Elf_file.bytes_of_elf64_file f1 with - | Fail f -> return f - | Success s -> - let chunks1 = (create_chunks s) in - let lines = (concatS (intercalate "\n" (Lem_list.map print_chunk chunks1))) in - return lines - )) - else if flag = "--debug-dump=info" then - Elf_file.read_elf64_file bs0 >>= (fun f1 -> - get_elf64_file_section_header_string_table f1 >>= (fun stbl -> - return (Dwarf.harness_string_of_elf64_debug_info_section - f1 - bs0 - (*string_of_gnu_ext_section_type - (fun x -> show x) - (fun x -> show x) - f1.elf64_file_header - f1.elf64_file_section_header_table - stbl*) - ))) - else - failwith "Unimplemented (for ELF64) or unrecognised flag") - in - ret - else - failwith "ELF ident transcription error" - )))) - in - (match res with - | Fail err -> prerr_endline ("[!]: " ^ err) - | Success e -> print_endline (string_of_string e) - )) - -(* -let _ = - match Sail_interface.populate_and_obtain_global_symbol_init_info "../test/mixed-binaries/tiny-istatic-with-malloc/tiny-tinystatic-with-malloc" with - | Fail err -> Missing_pervasives.errln ("[!]: " ^ err) - | Success (img, syms) -> Missing_pervasives.outln (Sail_interface.string_of_executable_process_image img) - end -*) diff --git a/lib/ocaml_rts/linksem/main_link.ml b/lib/ocaml_rts/linksem/main_link.ml deleted file mode 100644 index 82999d53..00000000 --- a/lib/ocaml_rts/linksem/main_link.ml +++ /dev/null @@ -1,158 +0,0 @@ -(*Generated by Lem from main_link.lem.*) -open Lem_basic_classes -open Lem_function -open Lem_string -open Lem_tuple -open Lem_bool -open Lem_list -open Lem_sorting -(*import Map*) -(*import Set*) -(*import Set_extra*) -open Lem_num -open Lem_maybe -open Lem_assert_extra - -open Byte_sequence -open Default_printing -open Error -open Missing_pervasives -open Show -open Endianness - -open Elf_header -open Elf_file -open Elf_interpreted_section -open Elf_interpreted_segment -open Elf_section_header_table -open Elf_program_header_table -open Elf_types_native_uint -open Elf_relocation -open String_table - -open Abi_amd64_elf_header -open Abi_amd64_serialisation -open Abis -(*import Gnu_ext_abi*) - -open Command_line -open Input_list -open Linkable_list - -open Memory_image -open Elf_memory_image -open Elf_memory_image_of_elf64_file -open Elf64_file_of_elf_memory_image - -open Linker_script -open Link - -(*val images_consistent : elf_memory_image -> elf_memory_image -> bool*) -let images_consistent img1 img2:bool= - (* img1.by_tag = img2.by_tag *) true - -(*val correctly_linked : abi any_abi_feature -> linkable_list -> list string -> set link_option -> elf64_file -> maybe elf_memory_image*) -let correctly_linked a linkables names options eout:((any_abi_feature)annotated_memory_image)option= - (let output_image = (elf_memory_image_of_elf64_file a "(output file)" eout) - in - let (fresh, alloc_map, script1) = (default_linker_control_script(Nat_big_num.of_int 0) (Pmap.empty Nat_big_num.compare) a - (* user_text_segment_start *) ((match Command_line.find_option_matching_tag (TextSegmentStart(Nat_big_num.of_int 0)) options with Some(TextSegmentStart(addr)) -> Some addr | _ -> None )) - (* user_data_segment_start *) None - (* user_rodata_segment_start *) ((match Command_line.find_option_matching_tag (RodataSegmentStart(Nat_big_num.of_int 0)) options with Some(RodataSegmentStart(addr)) -> Some addr | _ -> None )) - (* elf_headers_size *) - ( Nat_big_num.add(Nat_big_num.of_int - (* ELF header size *)64) (Nat_big_num.mul a.max_phnum(Nat_big_num.of_int 56)) (* size of one phdr *) - )) - in - let linked_image = (link alloc_map script1 a options linkables) - in - if images_consistent output_image linked_image then Some linked_image else None) - -(* We need to elaborate the command line to handle objects, archives - * and archive groups appropriately. - * We could imagine a relation between objects such that - * (o1, o2) is in the relation - * iff definitions in o1 might be used to satisfy references in o2. ("o1 supplies o2") - * If o1 is a .o, all other .o files are searched. - * If o1 comes from an archive and is not in a group, it only supplies *preceding* objects (whether from an archive or a .o). - * If o1 comes from an archive in a group, it supplies preceding objects and any objects from the same group. - * - * That doesn't capture the ordering, though: - * for each object, there's an ordered list of other objects - * in which to search for the *first* definition. *) - -let ( _:unit) = -(let res = -(let (input_units1, link_options1) = (command_line ()) - in - let items_and_options = (elaborate_input input_units1) - in - let (input_items, item_options) = (List.split items_and_options) - in - let _ = (prerr_endline ("Got " ^ ((Pervasives.string_of_int (List.length input_items)) ^ (" input items: {" - ^ ((List.fold_left (^) "" (Lem_list.map (fun item -> (string_of_triple - instance_Show_Show_string_dict instance_Show_Show_Input_list_input_blob_dict (instance_Show_Show_tup2_dict instance_Show_Show_Command_line_input_unit_dict - (instance_Show_Show_list_dict - instance_Show_Show_Input_list_origin_coord_dict)) item) ^ ",\n") input_items)) ^ "}"))))) - in - let output_filename = ((match Command_line.find_option_matching_tag (Command_line.OutputFilename("")) link_options1 with - None -> "impossible: no output file specified, despite default value of `a.out'" - | Some (Command_line.OutputFilename(s)) -> s - | _ -> "impossible: bad output filename option returned" - )) - in - Byte_sequence.acquire output_filename >>= (fun out -> - let _ = (prerr_endline ("Successfully opened output file")) in - Elf_file.read_elf64_file out >>= (fun eout -> - let _ = (prerr_endline ("Output file seems to be an ELF file")) in - let guessed_abi = (list_find_opt (fun a -> a.is_valid_elf_header eout.elf64_file_header) all_abis) - in - let a = ((match guessed_abi with - Some a -> if (* get_elf64_osabi eout.elf64_file_header = elf_osabi_gnu *) true - (* The GNU linker does not set the ABI to "GNU", but happily uses GNU extensions. - * FIXME: delegate to a personality function here - *) - then let _ = (prerr_endline "Using GNU-extended ABI") in Gnu_ext_abi.gnu_extend (Abis.tls_extend a) - else (Abis.tls_extend a) - | None -> failwith "output file does not conform to any known ABI" - )) - in - let make_linkable = (fun (it, opts) -> linkable_item_of_input_item_and_options a it opts) - in - let linkable_items_and_options = (Lem_list.map make_linkable items_and_options) - in - let names = (Lem_list.map - (string_of_triple instance_Show_Show_string_dict - instance_Show_Show_Input_list_input_blob_dict - (instance_Show_Show_tup2_dict - instance_Show_Show_Command_line_input_unit_dict - (instance_Show_Show_list_dict - instance_Show_Show_Input_list_origin_coord_dict))) input_items) - in - let maybe_symbolic_image = (correctly_linked a linkable_items_and_options names link_options1 eout) - in - let v = ((match maybe_symbolic_image with - None -> false - | Some img2 -> - (* generate some output, using the symbolic image we just got *) - let our_output_filename = (output_filename ^ ".test-out") - in - let f = (elf64_file_of_elf_memory_image a (fun x -> x) our_output_filename img2) - in - (match - bytes_of_elf64_file f >>= (fun bytes -> - Byte_sequence.serialise our_output_filename bytes) - with - Success _ -> true - | Fail s -> let _ = (print_endline ("error writing output: " ^ s)) in true - ) - )) - in - return (string_of_bool v)))) - in - (match res with - | Fail err -> prerr_endline ("[!]: " ^ err) - | Success e -> prerr_endline e - )) - - diff --git a/lib/ocaml_rts/linksem/memory_image.ml b/lib/ocaml_rts/linksem/memory_image.ml deleted file mode 100644 index fa9d1535..00000000 --- a/lib/ocaml_rts/linksem/memory_image.ml +++ /dev/null @@ -1,839 +0,0 @@ -(*Generated by Lem from memory_image.lem.*) -open Lem_basic_classes -open Lem_function -open Lem_string -open Lem_tuple -open Lem_bool -open Lem_list -open Lem_sorting -open Lem_map -(*import Map_extra*) -open Lem_set -open Lem_set_extra -open Multimap -open Lem_num -open Lem_maybe -open Lem_assert_extra -open Show - -open Byte_sequence -open Elf_file -open Elf_header -open Elf_interpreted_segment -open Elf_interpreted_section -open Elf_program_header_table -open Elf_section_header_table -open Elf_symbol_table -open Elf_types_native_uint -open Elf_relocation - -open Missing_pervasives - -(* Now we can define memory images *) - -type byte_pattern_element = char option -type byte_pattern = byte_pattern_element list - -(* An element might have an address/offset, and it has some contents. *) -type element = { startpos : Nat_big_num.num option - ; length1 : Nat_big_num.num option - ; contents : byte_pattern - } - -(* HMM -- ideally I want to fold these into the memory image notion - * and the startpos thingy. *) -type allocated_symbols_map = (string, (Nat_big_num.num * Nat_big_num.num)) Pmap.map (* start, length *) - -(* Instead of modelling address calculations (in linker scripts) like so: - -type address_expr = natural -> allocated_symbols_map -> natural - ( pos -> environment -> result address ) - - ... we model it as expressions in terms of CursorPosition. HMM. -*) - -type expr_operand = Var of string - | CursorPosition (* only valid in certain expressions... HMM *) - | Constant of Nat_big_num.num - | UnOp of (expr_unary_operation * expr_operand) - | BinOp of (expr_binary_operation * expr_operand * expr_operand) -and -expr_unary_operation = Neg of expr_operand - | BitwiseInverse of expr_operand -and -expr_binary_operation = Add of (expr_operand * expr_operand) - | Sub of (expr_operand * expr_operand) - | BitwiseAnd of (expr_operand * expr_operand) - | BitwiseOr of (expr_operand * expr_operand) - -type expr_binary_relation = - Lt - | Lte - | Gt - | Gte - | Eq - | Neq - -type expr = - False - | True - | Not of expr - | And of (expr * expr) - | Or of (expr * expr) - | BinRel of (expr_binary_relation * expr_operand) (* LH operand is the expr's value *) - -(* -val cond_expr : expr -> expr -> expr -> expr -let cond_expr expr1 expr2 expr3 = (Or((And(expr1, expr2)), (And((Not(expr1)), expr3)))) -*) - -(* Memory image elements all have identities. For convenience - * we make the identities strings. The string contents are arbitrary, - * and only their equality is relevant, but choosing friendly names - * like "ELF header" is good practice.*) -type memory_image = (string, element) Pmap.map - -type range = Nat_big_num.num * Nat_big_num.num (* start, length *) - -type element_range = string * range - -(* An "element" of an ELF image, in the linking phase, is either a section, - * the ELF header, the section header table or the program header table. - * - * PROBLEM: We'd like to use section names as the identifiers - * for those elements that are sections. - * but we can't, because they are not guaranteed to be unique. - * - * SOLUTION: Names that are unique in the file are used as keys. - * If not unique, the sections are treated as anonymous and given - * gensym'd string ids (FIXME: implement this). - *) - -(* Currently, our elements have unique names, which are strings. - * We *don't* want to encode any meaning onto these strings. - * All meaning should be encoded into labelled ranges. - * We want to be able to look up - * - * - elements - * - ranges within elements - * - * ... by their *labels* -- or sometimes just *part* of their labels. - *) - -(* ELF file features with which we can label ranges of the memory image. *) -type elf_file_feature = - ElfHeader of elf64_header - | ElfSectionHeaderTable of elf64_section_header_table (* do we want to expand these? *) - | ElfProgramHeaderTable of elf64_program_header_table - | ElfSection of (Nat_big_num.num * elf64_interpreted_section) (* SHT idx *) - | ElfSegment of (Nat_big_num.num * elf64_interpreted_segment) (* PHT idx *) - -type symbol_definition - = { def_symname : string - ; def_syment : elf64_symbol_table_entry (* definition's symtab entry *) - ; def_sym_scn : Nat_big_num.num (* symtab section index, to disamiguate dynsym *) - ; def_sym_idx : Nat_big_num.num (* index of symbol into the symtab *) - ; def_linkable_idx : Nat_big_num.num (* used to propagate origin linkable information to linked image *) - } - -let symDefCompare x1 x2:int= -(quintupleCompare compare elf64_symbol_table_entry_compare Nat_big_num.compare Nat_big_num.compare Nat_big_num.compare (x1.def_symname, x1.def_syment, x1.def_sym_scn, x1.def_sym_idx, x1.def_linkable_idx) - (x2.def_symname, x2.def_syment, x2.def_sym_scn, x2.def_sym_idx, x2.def_linkable_idx)) - -let instance_Basic_classes_Ord_Memory_image_symbol_definition_dict:(symbol_definition)ord_class= ({ - - compare_method = symDefCompare; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(symDefCompare f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (symDefCompare f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(symDefCompare f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (symDefCompare f1 f2)(Pset.from_list compare [1; 0])))}) - -type symbol_reference - = { ref_symname : string (* symbol name *) - ; ref_syment : elf64_symbol_table_entry (* likely-undefined (referencing) symbol *) - ; ref_sym_scn : Nat_big_num.num (* symtab section idx *) - ; ref_sym_idx : Nat_big_num.num (* index into symbol table *) - } - -let symRefCompare x1 x2:int= -(quadrupleCompare compare elf64_symbol_table_entry_compare Nat_big_num.compare Nat_big_num.compare (x1.ref_symname, x1.ref_syment, x1.ref_sym_scn, x1.ref_sym_idx) - (x2.ref_symname, x2.ref_syment, x2.ref_sym_scn, x2.ref_sym_idx)) - -let instance_Basic_classes_Ord_Memory_image_symbol_reference_dict:(symbol_reference)ord_class= ({ - - compare_method = symRefCompare; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(symRefCompare f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (symRefCompare f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(symRefCompare f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (symRefCompare f1 f2)(Pset.from_list compare [1; 0])))}) - -type reloc_site = { - ref_relent : elf64_relocation_a - ; ref_rel_scn : Nat_big_num.num (* the relocation section idx *) - ; ref_rel_idx : Nat_big_num.num (* the index of the relocation rec *) - ; ref_src_scn : Nat_big_num.num (* the section *from which* the reference logically comes *) -} - -let relocSiteCompare x1 x2:int= -(quadrupleCompare elf64_relocation_a_compare Nat_big_num.compare Nat_big_num.compare Nat_big_num.compare (x1.ref_relent, x1.ref_rel_scn, x1.ref_rel_idx, x1.ref_src_scn) - (x2.ref_relent, x2.ref_rel_scn, x2.ref_rel_idx, x2.ref_src_scn)) - -let instance_Basic_classes_Ord_Memory_image_reloc_site_dict:(reloc_site)ord_class= ({ - - compare_method = relocSiteCompare; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(relocSiteCompare f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (relocSiteCompare f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(relocSiteCompare f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (relocSiteCompare f1 f2)(Pset.from_list compare [1; 0])))}) - -type reloc_decision = LeaveReloc - | ApplyReloc - | ChangeRelocTo of (Nat_big_num.num * symbol_reference * reloc_site) - (* | MakePIC -- is now a kind of ChangeRelocTo *) - -let relocDecisionCompare x1 x2:int= - ((match (x1, x2) with - | (LeaveReloc, LeaveReloc) -> 0 - | (LeaveReloc, _) -> (-1) - | (ApplyReloc, ApplyReloc) -> 0 - | (ApplyReloc, ChangeRelocTo _) -> (-1) - | (ApplyReloc, LeaveReloc) -> 1 - | (ChangeRelocTo t1, ChangeRelocTo t2) -> (tripleCompare Nat_big_num.compare symRefCompare relocSiteCompare t1 t2) - | (ChangeRelocTo _, _) -> 1 - )) - -let instance_Basic_classes_Ord_Memory_image_reloc_decision_dict:(reloc_decision)ord_class= ({ - - compare_method = relocDecisionCompare; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(relocDecisionCompare f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (relocDecisionCompare f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(relocDecisionCompare f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (relocDecisionCompare f1 f2)(Pset.from_list compare [1; 0])))}) - -type symbol_reference_and_reloc_site = { - ref : symbol_reference - ; maybe_reloc : reloc_site option - ; maybe_def_bound_to : (reloc_decision * symbol_definition option)option - } - -let symRefAndRelocSiteCompare x1 x2:int= -(tripleCompare symRefCompare (maybeCompare relocSiteCompare) (maybeCompare (pairCompare relocDecisionCompare (maybeCompare symDefCompare))) (x1.ref, x1.maybe_reloc, x1.maybe_def_bound_to) - (x2.ref, x2.maybe_reloc, x2.maybe_def_bound_to)) - -let instance_Basic_classes_Ord_Memory_image_symbol_reference_and_reloc_site_dict:(symbol_reference_and_reloc_site)ord_class= ({ - - compare_method = symRefAndRelocSiteCompare; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(symRefAndRelocSiteCompare f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (symRefAndRelocSiteCompare f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(symRefAndRelocSiteCompare f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (symRefAndRelocSiteCompare f1 f2)(Pset.from_list compare [1; 0])))}) - -(* We can also annotate arbitrary ranges of bytes within an element - * with arbitrary metadata. - * - * Ideally we want to data-abstract this a bit. But it's hard to do - * so without baking in ELF-specific and/or (moreover) per-ABI concepts, - * like PLTs and GOTs. Ideally we would use something like polymorphic - * variants here. For now, this has to be the union of all the concepts - * that we find in the various ABIs we care about. To avoid ELFy things - * creeping in, we parameterise by 'a, and instantiate the 'a with the - * relevant ELFy thing when we use it. OH, but then 'a is different for - * every distinct ELF thing, which is no good. Can we define a mapping - * from an umbrella "ELF" type to the relevant types in each case? *) -type 'abifeature range_tag = (* forall 'abifeature . *) - ImageBase - | EntryPoint - | SymbolDef of symbol_definition - | SymbolRef of symbol_reference_and_reloc_site - | FileFeature of elf_file_feature (* file feature other than symdef and reloc *) - | AbiFeature of 'abifeature - -type 'abifeature annotated_memory_image = { - elements : memory_image - ; by_range : (( element_range option) * ( 'abifeature range_tag)) Pset.set - ; by_tag : (( 'abifeature range_tag), ( element_range option)) multimap -} - -(*val get_empty_memory_image : forall 'abifeature. unit -> annotated_memory_image 'abifeature*) -let get_empty_memory_image:unit ->'abifeature annotated_memory_image= (fun _ -> { - elements = (Pmap.empty compare) - ; by_range = (Pset.empty (pairCompare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))) compare)) - ; by_tag = (Pset.empty (pairCompare compare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))))) -}) - -(* Basic ELFy and ABI-y things. *) -(* "Special" sections are those that necessarily require special treatment by the - * linker. Examples include symbol tables and relocation tables. There are some - * grey areas, such as .eh_frame, debug info, and string tables. For us, the rule - * is that if we have special code to create them, i.e. that we don't rely on - * ordinary section concatenation during the linker script interpretation, they - * should be special -- it means strip_metadata_sections will remove them from - * the image, they won't be seen by the linker script, and that it's *our* job - * to reinstate them afterwards (as we do with symtab and strtab, for example). *) -(* FIXME: this shouldn't really be here, but needs to be in some low-lying module; - * keeping it out of elf_* for now to avoid duplication into elf64_, elf32_. *) -let elf_section_is_special s f:bool= (not (Nat_big_num.equal s.elf64_section_type sht_progbits) - && (not (Nat_big_num.equal s.elf64_section_type sht_nobits) - && (not (Nat_big_num.equal s.elf64_section_type sht_fini_array) - && not (Nat_big_num.equal s.elf64_section_type sht_init_array)))) - -(* This record collects things that ABIs may or must define. - * - * Since we want to put all ABIs in a list and select one at run time, - * we can't maintain a type-level distinction between ABIs; we have to - * use elf_memory_image any_abi_feature. To avoid a reference cycle, - * stay polymorphic in the ABI feature type until we define specific ABIs. - * In practice we'll use only any_abi_feature, because we need to pull - * the ABI out of a list at run time. - *) -type null_abi_feature = unit - -(* The reloc calculation is complicated, so we split up the big function - * type into smaller ones. *) - -(* Q. Do we want "existing", or is it a kind of addend? - * A. We do want it -- modelling both separately is necessary, - * because we model relocations bytewise, but some arches - * do bitfield relocations (think ARM). *) -type reloc_calculate_fn = Nat_big_num.num -> Nat_big_num.num -> Nat_big_num.num -> Nat_big_num.num (* symaddr -> addend -> existing -> relocated *) - -type 'abifeature reloc_apply_fn = 'abifeature - (* elf memory image: the context in which the relocation is being applied *) - annotated_memory_image -> - (* the site address *) - Nat_big_num.num -> - (* Typically there are two symbol table entries involved in a relocation. - * One is the reference, and is usually undefined. - * The other is the definition, and is defined (else absent, when we use 0). - * However, sometimes the reference is itself a defined symbol. - * Almost always, if so, *that* symbol *is* "the definition". - * However, copy relocs are an exception. - * - * In the case of copy relocations being fixed up by the dynamic - * linker, the dynamic linker must figure out which definition to - * copy from. This can't be as simple as "the first definition in - * link order", because *our* copy of that symbol is a definition - * (typically in bss). It could be as simple as "the first *after us* - * in link order". FIXME: find the glibc code that does this. - * - * Can we dig this stuff out of the memory image? If we pass the address - * being relocated, we can find the tags. But I don't want to pass - * the symbol address until the very end. It seems better to pass the symbol - * name, since that's the key that the dynamic linker uses to look for - * other definitions. - * - * Do we want to pass a whole symbol_reference? This has not only the - * symbol name but also syment, scn and idx. The syment is usually UND, - * but *could* be defined (and is for copy relocs). The scn and idx are - * not relevant, but it seems cleaner to pass the whole thing anyway. - *) - symbol_reference_and_reloc_site -> - (* Should we pass a symbol_definition too? Implicitly, we pass part of it - * by passing the symaddr argument (below). I'd prefer not to depend on - * others -- relocation calculations should look like "mostly address - * arithmetic", i.e. only the weird ones do something else. *) - (* How wide, in bytes, is the relocated field? this may depend on img - * and on the wider image (copy relocs), so it's returned *by* the reloc function. *) - (Nat_big_num.num (* width *) * reloc_calculate_fn) - -(* Some kinds of relocation necessarily give us back a R_*_RELATIVE reloc. - * We don't record this explicitly. Instead, the "bool" is a flag recording whether - * the field represents an absolute address. - * Similarly, some relocations can "fail" according to their ABI manuals. - * This just means that the result can't be represented in the field width. - * We detect this when actually applying the reloc in the memory image content - * (done elsewhere). *) -type 'abifeature reloc_fn = Nat_big_num.num -> (bool * 'abifeature reloc_apply_fn) - -(*val noop_reloc_calculate : natural -> integer -> natural -> natural*) -let noop_reloc_calculate symaddr addend existing:Nat_big_num.num= existing - -(*val noop_reloc_apply : forall 'abifeature. reloc_apply_fn 'abifeature*) -let noop_reloc_apply img2 site_addr ref1:Nat_big_num.num*(Nat_big_num.num ->Nat_big_num.num ->Nat_big_num.num ->Nat_big_num.num)= (Nat_big_num.of_int 0, noop_reloc_calculate) - -(*val noop_reloc : forall 'abifeature. natural -> (bool (* result is absolute addr *) * reloc_apply_fn 'abifeature)*) -let noop_reloc k:bool*('abifeature annotated_memory_image ->Nat_big_num.num ->symbol_reference_and_reloc_site ->Nat_big_num.num*reloc_calculate_fn)= (false, noop_reloc_apply) - -type 'abifeature abi = (* forall 'abifeature. *) - { is_valid_elf_header : elf64_header -> bool (* doesn't this generalise outrageously? is_valid_elf_file? *) - ; make_elf_header : Nat_big_num.num -> Nat_big_num.num -> Nat_big_num.num -> Nat_big_num.num -> Nat_big_num.num -> Nat_big_num.num -> Nat_big_num.num -> elf64_header - (* t entry shoff phoff phnum shnum shstrndx *) - ; reloc : 'abifeature reloc_fn - ; section_is_special : elf64_interpreted_section -> 'abifeature annotated_memory_image -> bool - ; section_is_large : elf64_interpreted_section -> 'abifeature annotated_memory_image -> bool - ; maxpagesize : Nat_big_num.num - ; minpagesize : Nat_big_num.num - ; commonpagesize : Nat_big_num.num - ; symbol_is_generated_by_linker : string -> bool - (*; link_inputs_tap : - ; link_output_sections_tap : - ; link_output_image_tap : *) - ; make_phdrs : Nat_big_num.num -> Nat_big_num.num -> Nat_big_num.num (* file type *) -> 'abifeature annotated_memory_image -> elf64_interpreted_section list -> elf64_program_header_table_entry list - ; max_phnum : Nat_big_num.num - ; guess_entry_point : 'abifeature annotated_memory_image -> Nat_big_num.num option - ; pad_data : Nat_big_num.num -> char list - ; pad_code : Nat_big_num.num -> char list - ; generate_support : (string * 'abifeature annotated_memory_image) (* list (list reloc_site_resolution) -> *)list -> 'abifeature annotated_memory_image - ; concretise_support : 'abifeature annotated_memory_image -> 'abifeature annotated_memory_image - ; get_reloc_symaddr : symbol_definition -> 'abifeature annotated_memory_image -> reloc_site option -> Nat_big_num.num - } - -(*val align_up_to : natural -> natural -> natural*) -let align_up_to align addr:Nat_big_num.num= - (let quot = (Nat_big_num.div addr align) - in - if Nat_big_num.equal (Nat_big_num.mul quot align) addr then addr else Nat_big_num.mul ( Nat_big_num.add quot(Nat_big_num.of_int 1)) align) - -(*val round_down_to : natural -> natural -> natural*) -let round_down_to align addr:Nat_big_num.num= - (let quot = (Nat_big_num.div addr align) - in Nat_big_num.mul - quot align) - -(*val uint32_max : natural*) -let uint32_max:Nat_big_num.num= (Nat_big_num.sub_nat ( Nat_big_num.pow_int(Nat_big_num.of_int 2)( 32))(Nat_big_num.of_int 1)) - -(*val uint64_max : natural*) -let uint64_max:Nat_big_num.num= (Nat_big_num.add (Nat_big_num.sub_nat (Nat_big_num.mul - (* HACK around Lem's inability to parse 18446744073709551615: - * the square of uint32_max is - * (2**32 - 1) (2**32 - 1) - * i.e. 2**64 - 2**32 - 2**32 + 1 - * So - * 2**64 - 1 = uint32_max * uint32_max + 2**32 + 2**32 - 2 - *) - uint32_max uint32_max)(Nat_big_num.of_int 2)) (Nat_big_num.pow_int(Nat_big_num.of_int 2)( 33))) - (* 18446744073709551615 *) (* i.e. 0x ffff ffff ffff ffff *) - (* HMM. This still overflows int64 *) - -(* The 2's complement of a value, at 64-bit width *) -(*val compl64 : natural -> natural*) -let compl64 v:Nat_big_num.num= (Nat_big_num.add(Nat_big_num.of_int 1) (Nat_big_num.bitwise_xor v uint64_max)) - -(*val gcd : natural -> natural -> natural*) -let rec gcd a b:Nat_big_num.num= - (if Nat_big_num.equal b(Nat_big_num.of_int 0) then a else gcd b ( Nat_big_num.modulus a b)) - -(*val lcm : natural -> natural -> natural*) -let lcm a b:Nat_big_num.num= (Nat_big_num.div - (* let _ = errln ("lcm of " ^ (show a) ^ " and " ^ (show b) ^ "?") - in *) - ( Nat_big_num.mul a b) (gcd a b)) - -(*val address_of_range : forall 'abifeature. element_range -> annotated_memory_image 'abifeature -> natural*) -let address_of_range el_range img2:Nat_big_num.num= - (let (el_name, (start, len)) = el_range - in - (match Pmap.lookup el_name img2.elements with - Some el -> - (match el.startpos with - Some addr -> Nat_big_num.add addr start - | None -> failwith "address_of_range called for element with no address" - ) - | None -> failwith "address_of_range called on nonexistent element" - )) - -(*val range_contains : (natural * natural) -> (natural * natural) -> bool*) -let range_contains (r1begin, r1len) (r2begin, r2len):bool= (Nat_big_num.greater_equal - (* r1 is at least as big as r2 *) - r2begin r1begin && Nat_big_num.less_equal ( Nat_big_num.add r2begin r2len) ( Nat_big_num.add r1begin r1len)) - -(*val range_overlaps : (natural * natural) -> (natural * natural) -> bool*) -let range_overlaps (r1begin, r1len) (r2begin, r2len):bool= - (( Nat_big_num.less r1begin ( Nat_big_num.add r2begin r2len) && Nat_big_num.greater ( Nat_big_num.add r1begin r1len) r2begin) - || ( Nat_big_num.less r2begin ( Nat_big_num.add r1begin r1len) && Nat_big_num.greater ( Nat_big_num.add r2begin r2len) r1begin)) - -(*val is_partition : list (natural * natural) -> list (natural * natural) -> bool*) -let is_partition rs ranges:bool= -( - (* 1. each element of the first list falls entirely within some element - * from the second list. *)let r_is_contained_by_some_range - = (fun r -> List.fold_left (||) false (Lem_list.map (fun range1 -> range_contains range1 r) ranges)) - in - List.for_all (fun r -> r_is_contained_by_some_range r) rs - && - (* 2. elements of the first list do not overlap *) - List.for_all (fun r -> List.for_all (fun r2 -> ( (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal r (* should be "=="? *) r2)) || (not (range_overlaps r r2))) rs) rs) - -(*val nat_range : natural -> natural -> list natural*) -let rec nat_range base len:(Nat_big_num.num)list= - ( - if(Nat_big_num.equal len (Nat_big_num.of_int 0)) then ([]) else - (base :: - (nat_range ( Nat_big_num.add base (Nat_big_num.of_int 1)) - ( Nat_big_num.sub_nat len (Nat_big_num.of_int 1))))) - -(* Expand a sorted list of ranges into a list of bool, where the list contains - * true if its index is included in one or more ranges, else false. *) -(*val expand_sorted_ranges : list (natural * natural) -> natural -> list bool -> list bool*) -let rec expand_sorted_ranges sorted_ranges min_length accum:(bool)list= - ((match sorted_ranges with - [] -> List.rev_append (List.rev accum) ( - let pad_length = (Nat_big_num.max(Nat_big_num.of_int 0) ( Nat_big_num.sub_nat min_length (Missing_pervasives.length accum))) - in - (* let _ = Missing_pervasives.errln ( - "padding ranges cares list with " ^ (show pad_length) ^ - " cares (accumulated " ^ (show (Missing_pervasives.length accum)) ^ - ", min length " ^ (show min_length) ^ ")") - in *) - Missing_pervasives.replicate0 pad_length true) - | (base, len) :: more -> - (* pad the accum so that it reaches up to base *) - let up_to_base = (Missing_pervasives.replicate0 ( Nat_big_num.sub_nat base (Missing_pervasives.length accum)) true) - in - let up_to_end_of_range = (List.rev_append (List.rev up_to_base) (Missing_pervasives.replicate0 len false)) - in - expand_sorted_ranges more min_length ( List.rev_append (List.rev accum) up_to_end_of_range) - )) - -(*val expand_unsorted_ranges : list (natural * natural) -> natural -> list bool -> list bool*) -let rec expand_unsorted_ranges unsorted_ranges min_length accum:(bool)list= - (expand_sorted_ranges (insertSortBy (fun (base1, len1) -> (fun (base2, len2) -> Nat_big_num.less base1 base2)) unsorted_ranges) min_length accum) - -(*val make_byte_pattern_revacc : list (maybe byte) -> list byte -> list bool -> list (maybe byte)*) -let rec make_byte_pattern_revacc revacc bytes cares:((char)option)list= - ((match bytes with - [] -> List.rev revacc - | b :: bs -> (match cares with - care :: more -> make_byte_pattern_revacc ((if not care then None else Some b) :: revacc) bs more - | _ -> failwith "make_byte_pattern: unequal length" - ) - )) - -(*val make_byte_pattern : list byte -> list bool -> list (maybe byte)*) -let rec make_byte_pattern bytes cares:((char)option)list= - (make_byte_pattern_revacc [] bytes cares) - -(*val relax_byte_pattern_revacc : list (maybe byte) -> list (maybe byte) -> list bool -> list (maybe byte)*) -let rec relax_byte_pattern_revacc revacc bytes cares:((char)option)list= - ((match bytes with - [] -> List.rev revacc - | b :: bs -> (match cares with - care :: more -> relax_byte_pattern_revacc ((if not care then None else b) :: revacc) bs more - | _ -> failwith ("relax_byte_pattern: unequal length") - ) - )) - -(*val relax_byte_pattern : list (maybe byte) -> list bool -> list (maybe byte)*) -let rec relax_byte_pattern bytes cares:((char)option)list= - (relax_byte_pattern_revacc [] bytes cares) - -type pad_fn = Nat_big_num.num -> char list - -(*val concretise_byte_pattern : list byte -> natural -> list (maybe byte) -> pad_fn -> list byte*) -let rec concretise_byte_pattern rev_acc acc_pad bs pad:(char)list= - ((match bs with - [] -> - let padding_bytes = (if Nat_big_num.greater acc_pad(Nat_big_num.of_int 0) then pad acc_pad else []) - in List.rev ( List.rev_append (List.rev (List.rev padding_bytes)) rev_acc) - | Some(b) :: more -> - (* flush accumulated padding *) - let padding_bytes = (if Nat_big_num.greater acc_pad(Nat_big_num.of_int 0) then pad acc_pad else []) - in - concretise_byte_pattern (b :: ( List.rev_append (List.rev (List.rev padding_bytes)) rev_acc))(Nat_big_num.of_int 0) more pad - | None :: more -> - concretise_byte_pattern rev_acc (Nat_big_num.add acc_pad(Nat_big_num.of_int 1)) more pad - )) - -(*val byte_option_matches_byte : maybe byte -> byte -> bool*) -let byte_option_matches_byte optb b:bool= - ((match optb with - None -> true - | Some some -> some = b - )) - -(*val byte_list_matches_pattern : list (maybe byte) -> list byte -> bool*) -let rec byte_list_matches_pattern pattern bytes:bool= - ((match pattern with - [] -> true - | optbyte :: more -> (match bytes with - [] -> false - | abyte :: morebytes -> - byte_option_matches_byte optbyte abyte - && byte_list_matches_pattern more morebytes - ) - )) - -(*val append_to_byte_pattern_at_offset : natural -> list (maybe byte) -> list (maybe byte) -> list (maybe byte)*) -let append_to_byte_pattern_at_offset offset pat1 pat2:((char)option)list= - (let pad_length = (Nat_big_num.sub_nat offset (Missing_pervasives.length pat1)) - in - if Nat_big_num.less pad_length(Nat_big_num.of_int 0) then failwith "can't append at offset already used" - else List.rev_append (List.rev (List.rev_append (List.rev pat1) (Lem_list.replicate (Nat_big_num.to_int pad_length) None))) pat2) - -(*val accum_pattern_possible_starts_in_one_byte_sequence : list (maybe byte) -> nat -> list byte -> nat -> natural -> list natural -> list natural*) -let rec accum_pattern_possible_starts_in_one_byte_sequence pattern pattern_len seq seq_len offset accum:(Nat_big_num.num)list= -( - (* let _ = Missing_pervasives.errs ("At offset " ^ (show offset) ^ "... ") - in *)(match pattern with - [] -> (* let _ = Missing_pervasives.errs ("terminating with hit (empty pattern)\n") in *) - offset :: accum - | bpe :: more_bpes -> (* nonempty, so check for nonempty seq *) - (match seq with - [] -> (*let _ = Missing_pervasives.errs ("terminating with miss (empty pattern)\n") - in *) accum (* ran out of bytes in the sequence, so no match *) - | byte1 :: more_bytes -> let matched_this_byte = - (byte_option_matches_byte bpe byte1) - in - (* let _ = Missing_pervasives.errs ("Byte " ^ (show byte) ^ " matched " ^ (show byte_pattern) ^ "? " ^ (show matched_this_byte) ^ "; ") - in *) - let sequence_long_enough = (seq_len >= pattern_len) - in - (* let _ = Missing_pervasives.errs ("enough bytes remaining (" ^ (show seq_len) ^ ") to match rest of pattern (" ^ (show pattern_len) ^ ")? " ^ (show sequence_long_enough) ^ "; ") - in *) - let matched_here = (matched_this_byte && (sequence_long_enough && - byte_list_matches_pattern more_bpes more_bytes)) - in - (* let _ = Missing_pervasives.errs ("matched pattern anchored here? " ^ (show matched_this_byte) ^ "\n") - in *) - accum_pattern_possible_starts_in_one_byte_sequence - pattern pattern_len - more_bytes ( Nat_num.nat_monus seq_len( 1)) - ( Nat_big_num.add offset(Nat_big_num.of_int 1)) - (if matched_here then offset :: accum else accum) - ) - )) - -let swap_pairs dict_Basic_classes_SetType_a dict_Basic_classes_SetType_b s:('a*'b)Pset.set= (let x2 =(Pset.from_list (pairCompare - dict_Basic_classes_SetType_a.setElemCompare_method dict_Basic_classes_SetType_b.setElemCompare_method) []) in Pset.fold (fun(k, v) x2 -> if true then Pset.add (v, k) x2 else x2) s x2) - -let by_range_from_by_tag dict_Basic_classes_SetType_a dict_Basic_classes_SetType_b:('a*'b)Pset.set ->('b*'a)Pset.set= - (swap_pairs dict_Basic_classes_SetType_b dict_Basic_classes_SetType_a) - -let by_tag_from_by_range dict_Basic_classes_SetType_a dict_Basic_classes_SetType_b:('a*'b)Pset.set ->('b*'a)Pset.set= - (swap_pairs dict_Basic_classes_SetType_b dict_Basic_classes_SetType_a) - -(*val filter_elements : forall 'abifeature. ((string * element) -> bool) -> - annotated_memory_image 'abifeature -> annotated_memory_image 'abifeature*) -let filter_elements pred img2:'abifeature annotated_memory_image= - (let new_elements = (Lem_map.fromList - (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) (let x2 = ([]) in List.fold_right - (fun(n, r) x2 -> - if - let result = (pred (n, r)) in - if not result then - (*let _ = Missing_pervasives.outln ("Discarding element named " ^ n) in*) result - else result then (n, r) :: x2 else x2) - (Pset.elements - ((Pmap.bindings (pairCompare compare compare) img2.elements))) - x2)) - in - let new_by_range = (Pset.filter (fun (maybe_range, tag) -> (match maybe_range with - None -> true - | Some (el_name, el_range) -> Pset.mem el_name (Pmap.domain new_elements) - )) img2.by_range) - in - let new_by_tag = (let x2 =(Pset.from_list (pairCompare compare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare)))) - []) in Pset.fold (fun(k, v) x2 -> if true then Pset.add (v, k) x2 else x2) - new_by_range x2) - in - { elements = new_elements - ; by_range = new_by_range - ; by_tag = new_by_tag - }) - -(*val tag_image : forall 'abifeature. range_tag 'abifeature -> string -> natural -> natural -> annotated_memory_image 'abifeature - -> annotated_memory_image 'abifeature*) -let tag_image t el_name el_offset tag_len img2:'abifeature annotated_memory_image= - (let (k, v) = (Some (el_name, (el_offset, tag_len)), t) - in - let new_by_range = (Pset.add (k, v) img2.by_range) - in - let new_by_tag = (Pset.add (v, k) img2.by_tag) - in - { elements = (img2.elements) - ; by_range = new_by_range - ; by_tag = new_by_tag - }) - -(*val address_to_element_and_offset : forall 'abifeature. natural -> annotated_memory_image 'abifeature -> maybe (string * natural)*) -let address_to_element_and_offset query_addr img2:(string*Nat_big_num.num)option= -( - (* Find the element with the highest address <= addr. - * What about zero-length elements? - * Break ties on the bigger size. *)let (maybe_highest_le : (Nat_big_num.num * string * element)option) - = (List.fold_left (fun maybe_current_max_le -> (fun (el_name, el_rec) -> - (*let _ = errln ("Saw element named `" ^ el_name ^ " with startpos " ^ ( - (match el_rec.startpos with Just addr -> ("0x" ^ (hex_string_of_natural addr)) | Nothing -> "(none)" end) - ^ " and length " ^ - (match el_rec.length with Just len -> ("0x" ^ (hex_string_of_natural len)) | Nothing -> "(none)" end) - )) - in*) - (match (maybe_current_max_le, el_rec.startpos) with - (None, None) -> None - | (None, Some this_element_pos) -> if Nat_big_num.less_equal this_element_pos query_addr - then Some (this_element_pos, el_name, el_rec) - else None - | (Some (cur_max_le, cur_el_name, cur_el_rec), None) -> maybe_current_max_le - | (Some (cur_max_le, cur_el_name, cur_el_rec), Some this_element_pos) -> if Nat_big_num.less_equal this_element_pos query_addr - && ( Nat_big_num.greater this_element_pos cur_max_le - || ( Nat_big_num.equal this_element_pos cur_max_le - && ( (Lem.option_equal Nat_big_num.equal cur_el_rec.length1 (Some(Nat_big_num.of_int 0)))))) - then Some (this_element_pos, el_name, el_rec) - else maybe_current_max_le - ) - )) None (Pmap.bindings_list img2.elements)) - in - (match maybe_highest_le with - Some (el_def_startpos, el_name, el_rec) -> - (* final sanity check: is the length definite, and if so, does the - * element span far enough? *) - (match el_rec.length1 with - Some l -> if Nat_big_num.greater_equal (Nat_big_num.add el_def_startpos l) query_addr - then Some (el_name, Nat_big_num.sub_nat query_addr el_def_startpos) - else - (*let _ = errln ("Discounting " ^ el_name ^ " because length is too short") in*) None - | None -> (*let _ = errln ("Gave up because element has unknown length") in*) None - ) - | None -> - (* no elements with a low enough assigned address, so nothing *) - (*let _ = errln ("Found no elements with low enough address") in*) None - )) - -(*val element_and_offset_to_address : forall 'abifeature. (string * natural) -> annotated_memory_image 'abifeature -> maybe natural*) -let element_and_offset_to_address (el_name, el_off) img2:(Nat_big_num.num)option= - ((match Pmap.lookup el_name img2.elements with - Some el -> (match el.startpos with - Some addr -> Some ( Nat_big_num.add addr el_off) - | None -> None - ) - | None -> failwith ("error: nonexistent element: " ^ el_name) - )) - -let null_symbol_reference:symbol_reference= ({ - ref_symname = "" - ; ref_syment = elf64_null_symbol_table_entry - ; ref_sym_scn =(Nat_big_num.of_int 0) - ; ref_sym_idx =(Nat_big_num.of_int 0) -}) - -let null_elf_relocation_a:elf64_relocation_a= - ({ elf64_ra_offset = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_ra_info = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_ra_addend = (Nat_big_num.to_int64(Nat_big_num.of_int 0)) - }) - - -let null_symbol_reference_and_reloc_site:symbol_reference_and_reloc_site= ({ - ref = null_symbol_reference - ; maybe_reloc = - (Some { ref_relent = null_elf_relocation_a - ; ref_rel_scn =(Nat_big_num.of_int 0) - ; ref_rel_idx =(Nat_big_num.of_int 0) - ; ref_src_scn =(Nat_big_num.of_int 0) - }) - ; maybe_def_bound_to = None - }) - -let null_symbol_definition:symbol_definition= ({ - def_symname = "" - ; def_syment = elf64_null_symbol_table_entry - ; def_sym_scn =(Nat_big_num.of_int 0) - ; def_sym_idx =(Nat_big_num.of_int 0) - ; def_linkable_idx =(Nat_big_num.of_int 0) -}) - -(*val pattern_possible_starts_in_one_byte_sequence : list (maybe byte) -> list byte -> natural -> list natural*) -let pattern_possible_starts_in_one_byte_sequence pattern seq offset:(Nat_big_num.num)list= -( - (* let _ = Missing_pervasives.errs ("Looking for matches of " ^ - (show (List.length pattern)) ^ "-byte pattern in " ^ (show (List.length seq)) ^ "-byte region\n") - in *)accum_pattern_possible_starts_in_one_byte_sequence pattern (List.length pattern) seq (List.length seq) offset []) - -(*val byte_pattern_of_byte_sequence : byte_sequence -> list (maybe byte)*) -let byte_pattern_of_byte_sequence seq:((char)option)list= ((match seq with - Sequence(bs) -> Lem_list.map (fun b -> Some b) bs -)) - -(*val compute_virtual_address_adjustment : natural -> natural -> natural -> natural*) -let compute_virtual_address_adjustment max_page_size offset vaddr:Nat_big_num.num= (Nat_big_num.modulus - ( Nat_big_num.sub_nat vaddr offset) max_page_size) - -(*val extract_natural_field : natural -> element -> natural -> natural*) -let extract_natural_field width element1 offset:Nat_big_num.num= -( - (* Read n bytes from the contents *)let maybe_bytes = (take0 width (drop0 offset element1.contents)) - in - let bytes = (Lem_list.map (fun mb -> (match mb with None -> Char.chr (Nat_big_num.to_int (Nat_big_num.of_int 0)) | Some mb -> mb )) maybe_bytes) - in - (* FIXME: do we want little- or big-endian? *) - List.fold_left (fun acc -> fun next_byte -> Nat_big_num.add (Nat_big_num.mul - acc(Nat_big_num.of_int 256)) (Nat_big_num.of_int (Char.code next_byte)) - ) (Nat_big_num.of_int 0 : Nat_big_num.num) bytes) - -(*val natural_to_le_byte_list : natural -> list byte*) -let rec natural_to_le_byte_list n:(char)list= - ((Char.chr (Nat_big_num.to_int ( Nat_big_num.modulus n(Nat_big_num.of_int 256)))) :: (let d =(Nat_big_num.div n(Nat_big_num.of_int 256)) in if Nat_big_num.equal d(Nat_big_num.of_int 0) then [] else natural_to_le_byte_list ( Nat_big_num.div n(Nat_big_num.of_int 256)))) - -(*val natural_to_le_byte_list_padded_to : natural -> natural -> list byte*) -let rec natural_to_le_byte_list_padded_to width n:(char)list= - (let bytes = (natural_to_le_byte_list n) - in - List.rev_append (List.rev bytes) (replicate0 ( Nat_big_num.sub_nat width (length bytes)) (Char.chr (Nat_big_num.to_int (Nat_big_num.of_int 0))))) - -(*val n2i : natural -> integer*) -let n2i:Nat_big_num.num ->Nat_big_num.num= (fun n-> n) - -(*val i2n: integer -> natural*) -let i2n:Nat_big_num.num ->Nat_big_num.num= Nat_big_num.abs - -(*val i2n_signed : nat -> integer -> natural*) -let i2n_signed width i:Nat_big_num.num= - (if Nat_big_num.greater_equal i(Nat_big_num.of_int 0) then - if Nat_big_num.greater_equal i (Nat_big_num.pow_int(Nat_big_num.of_int 2) (Nat_num.nat_monus width( 1))) then failwith "overflow" - else Nat_big_num.abs i - else - (* We manually encode the 2's complement of the negated value *) - let negated = (Nat_big_num.abs ( Nat_big_num.sub(Nat_big_num.of_int 0) i)) in - let (xormask : Nat_big_num.num) = ( Nat_big_num.sub_nat (Nat_big_num.pow_int(Nat_big_num.of_int 2) width)(Nat_big_num.of_int 1)) in - let compl = (Nat_big_num.add(Nat_big_num.of_int 1) (Nat_big_num.bitwise_xor negated xormask)) - in - (*let _ = errln ("Signed value " ^ (show i) ^ " is 2's-compl'd to 0x" ^ (hex_string_of_natural compl)) - in*) compl) - -(*val to_le_signed_bytes : natural -> integer -> list byte*) -let to_le_signed_bytes bytewidth i:(char)list= - (natural_to_le_byte_list_padded_to bytewidth (i2n_signed (Nat_big_num.to_int (Nat_big_num.mul(Nat_big_num.of_int 8)bytewidth)) i)) - -(*val to_le_unsigned_bytes : natural -> integer -> list byte*) -let to_le_unsigned_bytes bytewidth i:(char)list= - (natural_to_le_byte_list_padded_to bytewidth (Nat_big_num.abs i)) - -(*val write_natural_field : natural -> natural -> element -> natural -> element*) -let write_natural_field new_field_value width element1 offset:element= - (let pre_bytes = (take0 offset element1.contents) - in - let post_bytes = (drop0 ( Nat_big_num.add offset width) element1.contents) - in - (* FIXME: avoid hard-coding little-endian *) - let field_bytes = (natural_to_le_byte_list new_field_value) - in - if Nat_big_num.greater (length field_bytes) width then failwith "internal error: relocation output unrepresentable" - else - { - contents = (List.rev_append (List.rev (List.rev_append (List.rev (List.rev_append (List.rev pre_bytes) (let x2 = - ([]) in List.fold_right (fun b x2 -> if true then Some b :: x2 else x2) field_bytes - x2))) (replicate0 ( Nat_big_num.sub_nat width (length field_bytes)) (Some (Char.chr (Nat_big_num.to_int (Nat_big_num.of_int 0))))))) post_bytes) - ; startpos = (element1.startpos) - ; length1 = (element1.length1) - }) diff --git a/lib/ocaml_rts/linksem/memory_image_orderings.ml b/lib/ocaml_rts/linksem/memory_image_orderings.ml deleted file mode 100644 index ffde4184..00000000 --- a/lib/ocaml_rts/linksem/memory_image_orderings.ml +++ /dev/null @@ -1,329 +0,0 @@ -(*Generated by Lem from memory_image_orderings.lem.*) -open Lem_basic_classes -open Lem_function -open Lem_string -open Lem_tuple -open Lem_bool -open Lem_list -open Lem_sorting -open Lem_map -open Lem_set -open Multimap -open Lem_num -open Lem_maybe -open Lem_assert_extra -open Show - -open Byte_sequence -open Elf_file -open Elf_header -open Elf_interpreted_segment -open Elf_interpreted_section -open Elf_program_header_table -open Elf_section_header_table -open Elf_symbol_table -open Elf_types_native_uint -open Elf_relocation -open Memory_image -open Abi_classes -(* open import Abis *) - -open Missing_pervasives - -(*val elfFileFeatureCompare : elf_file_feature -> elf_file_feature -> Basic_classes.ordering*) -let elfFileFeatureCompare f1 f2:int= -( - (* order is: *)(match (f1, f2) with - (ElfHeader(x1), ElfHeader(x2)) -> (* equal tags, so ... *) elf64_header_compare x1 x2 - | (ElfHeader(x1), _) -> (-1) - | (ElfSectionHeaderTable(x1), ElfHeader(x2)) -> 1 - | (ElfSectionHeaderTable(x1), ElfSectionHeaderTable(x2)) -> ( (* equal tags, so ... *)lexicographic_compare compare_elf64_section_header_table_entry x1 x2) - | (ElfSectionHeaderTable(x1), _) -> (-1) - | (ElfProgramHeaderTable(x1), ElfHeader(x2)) -> 1 - | (ElfProgramHeaderTable(x1), ElfSectionHeaderTable(x2)) -> 1 - | (ElfProgramHeaderTable(x1), ElfProgramHeaderTable(x2)) -> (lexicographic_compare compare_elf64_program_header_table_entry x1 x2) - | (ElfProgramHeaderTable(x1), _) -> (-1) - | (ElfSection(x1), ElfHeader(x2)) -> 1 - | (ElfSection(x1), ElfSectionHeaderTable(x2)) -> 1 - | (ElfSection(x1), ElfProgramHeaderTable(x2)) -> 1 - | (ElfSection(x1), ElfSection(x2)) -> (pairCompare Nat_big_num.compare compare_elf64_interpreted_section x1 x2) - | (ElfSection(x1), _) -> (-1) - | (ElfSegment(x1), ElfHeader(x2)) -> 1 - | (ElfSegment(x1), ElfSectionHeaderTable(x2)) -> 1 - | (ElfSegment(x1), ElfProgramHeaderTable(x2)) -> 1 - | (ElfSegment(x1), ElfSection(x2)) -> 1 - | (ElfSegment(x1), ElfSegment(x2)) -> (pairCompare Nat_big_num.compare compare_elf64_interpreted_segment x1 x2) - | (ElfSegment(x1), _) -> (-1) - )) - -(*val elfFileFeatureTagEquiv : elf_file_feature -> elf_file_feature -> bool*) -let elfFileFeatureTagEquiv f1 f2:bool= -( - (* order is: *)(match (f1, f2) with - (ElfHeader(x1), ElfHeader(x2)) -> (* equal tags, so ... *) true - | (ElfSectionHeaderTable(x1), ElfSectionHeaderTable(x2)) -> true - | (ElfProgramHeaderTable(x1), ElfProgramHeaderTable(x2)) -> true - | (ElfSection(x1), ElfSection(x2)) -> true - | (ElfSegment(x1), ElfSegment(x2)) -> true - | (_, _) -> false - )) - -let instance_Basic_classes_Ord_Memory_image_elf_file_feature_dict:(elf_file_feature)ord_class= ({ - - compare_method = elfFileFeatureCompare; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(elfFileFeatureCompare f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> Pset.mem (elfFileFeatureCompare f1 f2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(elfFileFeatureCompare f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> Pset.mem (elfFileFeatureCompare f1 f2)(Pset.from_list compare [1; 0])))}) - -(*val tagCompare : forall 'abifeature. Ord 'abifeature => - range_tag 'abifeature -> range_tag 'abifeature -> Basic_classes.ordering*) -let tagCompare dict_Basic_classes_Ord_abifeature k1 k2:int= - ((match (k1, k2) with - (ImageBase, ImageBase) -> 0 - | (ImageBase, _) -> (-1) - | (EntryPoint, ImageBase) -> 1 - | (EntryPoint, EntryPoint) -> 0 - | (EntryPoint, _) -> (-1) - | (SymbolDef(_), ImageBase) -> 1 - | (SymbolDef(_), EntryPoint) -> 1 - | (SymbolDef(x1), SymbolDef(x2)) -> symDefCompare x1 x2 - | (SymbolDef(_), _) -> (-1) - | (SymbolRef(_), ImageBase) -> 1 - | (SymbolRef(_), EntryPoint) -> 1 - | (SymbolRef(_), SymbolDef(_)) -> 1 - | (SymbolRef(x1), SymbolRef(x2)) -> symRefAndRelocSiteCompare x1 x2 - | (SymbolRef(_), _) -> (-1) - | (FileFeature(_), ImageBase) -> 1 - | (FileFeature(_), EntryPoint) -> 1 - | (FileFeature(_), SymbolDef(_)) -> 1 - | (FileFeature(_), SymbolRef(_)) -> 1 - | (FileFeature(x1), FileFeature(x2)) -> elfFileFeatureCompare x1 x2 - | (FileFeature(_), _) -> (-1) - | (AbiFeature(_), ImageBase) -> 1 - | (AbiFeature(_), EntryPoint) -> 1 - | (AbiFeature(_), SymbolDef(_)) -> 1 - | (AbiFeature(_), SymbolRef(_)) -> 1 - | (AbiFeature(_), FileFeature(_)) -> 1 - | (AbiFeature(x1), AbiFeature(x2)) -> - dict_Basic_classes_Ord_abifeature.compare_method x1 x2 - | (AbiFeature(_), _) -> (-1) - )) - -let instance_Basic_classes_Ord_Memory_image_range_tag_dict dict_Basic_classes_Ord_abifeature:('abifeature range_tag)ord_class= ({ - - compare_method = - (tagCompare dict_Basic_classes_Ord_abifeature); - - isLess_method = (fun tag1 -> (fun tag2 -> ( Lem.orderingEqual(tagCompare - dict_Basic_classes_Ord_abifeature tag1 tag2) (-1)))); - - isLessEqual_method = (fun tag1 -> (fun tag2 -> Pset.mem (tagCompare - dict_Basic_classes_Ord_abifeature tag1 tag2)(Pset.from_list compare [(-1); 0]))); - - isGreater_method = (fun tag1 -> (fun tag2 -> ( Lem.orderingEqual(tagCompare - dict_Basic_classes_Ord_abifeature tag1 tag2) 1))); - - isGreaterEqual_method = (fun tag1 -> (fun tag2 -> Pset.mem (tagCompare - dict_Basic_classes_Ord_abifeature tag1 tag2)(Pset.from_list compare [1; 0])))}) - -(*val tagEquiv : forall 'abifeature. AbiFeatureTagEquiv 'abifeature => range_tag 'abifeature -> range_tag 'abifeature -> bool*) -let tagEquiv dict_Abi_classes_AbiFeatureTagEquiv_abifeature k1 k2:bool= - ((match (k1, k2) with - (ImageBase, ImageBase) -> true - | (EntryPoint, EntryPoint) -> true - | (SymbolDef(x1), SymbolDef(x2)) -> true - | (SymbolRef(_), SymbolRef(_)) -> true - | (FileFeature(x1), FileFeature(x2)) -> elfFileFeatureTagEquiv x1 x2 - | (AbiFeature(x1), AbiFeature(x2)) -> - dict_Abi_classes_AbiFeatureTagEquiv_abifeature.abiFeatureTagEquiv_method x1 x2 - | (_, _) -> false - )) - -(* ------- end of Ord / compare / ConstructorToNaturalList functions *) - - -(*val unique_tag_matching : forall 'abifeature. Ord 'abifeature, AbiFeatureTagEquiv 'abifeature => range_tag 'abifeature -> annotated_memory_image 'abifeature -> range_tag 'abifeature*) -let unique_tag_matching dict_Basic_classes_Ord_abifeature dict_Abi_classes_AbiFeatureTagEquiv_abifeature tag img2:'abifeature range_tag= - ((match Multimap.lookupBy0 - (instance_Basic_classes_Ord_Memory_image_range_tag_dict - dict_Basic_classes_Ord_abifeature) (instance_Basic_classes_Ord_Maybe_maybe_dict - (instance_Basic_classes_Ord_tup2_dict - Lem_string_extra.instance_Basic_classes_Ord_string_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_Num_natural_dict - instance_Basic_classes_Ord_Num_natural_dict))) instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) (tagEquiv dict_Abi_classes_AbiFeatureTagEquiv_abifeature) tag img2.by_tag with - [] -> failwith "no tag match found" - | [(t, r)] -> t - | x -> failwith ("more than one tag match") (* (ranges: " ^ - (show (List.map (fun (t, r) -> r) x)) - ^ ") when asserted unique")" *) - )) - -(*val tagged_ranges_matching_tag : forall 'abifeature. Ord 'abifeature, AbiFeatureTagEquiv 'abifeature => range_tag 'abifeature -> annotated_memory_image 'abifeature -> list (range_tag 'abifeature * maybe element_range)*) -let tagged_ranges_matching_tag dict_Basic_classes_Ord_abifeature dict_Abi_classes_AbiFeatureTagEquiv_abifeature tag img2:('abifeature range_tag*(element_range)option)list= - (Multimap.lookupBy0 - (instance_Basic_classes_Ord_Memory_image_range_tag_dict - dict_Basic_classes_Ord_abifeature) (instance_Basic_classes_Ord_Maybe_maybe_dict - (instance_Basic_classes_Ord_tup2_dict - Lem_string_extra.instance_Basic_classes_Ord_string_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_Num_natural_dict - instance_Basic_classes_Ord_Num_natural_dict))) instance_Basic_classes_SetType_var_dict (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) (tagEquiv dict_Abi_classes_AbiFeatureTagEquiv_abifeature) tag img2.by_tag) - -(*val element_range_compare : element_range -> element_range -> Basic_classes.ordering*) -let element_range_compare:string*(Nat_big_num.num*Nat_big_num.num) ->string*(Nat_big_num.num*Nat_big_num.num) ->int= (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare)) - -(*val unique_tag_matching_at_range_exact : forall 'abifeature. Ord 'abifeature, AbiFeatureTagEquiv 'abifeature => - maybe element_range - -> range_tag 'abifeature - -> annotated_memory_image 'abifeature - -> range_tag 'abifeature*) -let unique_tag_matching_at_range_exact dict_Basic_classes_Ord_abifeature dict_Abi_classes_AbiFeatureTagEquiv_abifeature r tag img2:'abifeature range_tag= -( - (* 1. find tags a unique range labelled as ELF section header table. *)let (_, (allRangeMatches : ( 'abifeature range_tag) list)) = (List.split (Multimap.lookupBy0 - (instance_Basic_classes_Ord_Maybe_maybe_dict - (instance_Basic_classes_Ord_tup2_dict - Lem_string_extra.instance_Basic_classes_Ord_string_dict - (instance_Basic_classes_Ord_tup2_dict - instance_Basic_classes_Ord_Num_natural_dict - instance_Basic_classes_Ord_Num_natural_dict))) (instance_Basic_classes_Ord_Memory_image_range_tag_dict - dict_Basic_classes_Ord_abifeature) (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) instance_Basic_classes_SetType_var_dict (Lem.option_equal (Lem.pair_equal (=) (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal))) r img2.by_range)) - in - let (tagAlsoMatches : ( 'abifeature range_tag) list) = (List.filter (fun x -> tagEquiv - dict_Abi_classes_AbiFeatureTagEquiv_abifeature x tag) allRangeMatches) - in - (match tagAlsoMatches with - [] -> failwith "no range/tag match when asserted to exist" - | [x] -> x - | _ -> failwith "multiple range/tag match when asserted unique" - )) - -(*val symbol_def_ranges : forall 'abifeature. Ord 'abifeature, AbiFeatureTagEquiv 'abifeature => annotated_memory_image 'abifeature -> (list (range_tag 'abifeature) * list (maybe element_range))*) -let symbol_def_ranges dict_Basic_classes_Ord_abifeature dict_Abi_classes_AbiFeatureTagEquiv_abifeature img2:('abifeature range_tag)list*((element_range)option)list= -( - (* find all element ranges labelled as ELF symbols *)let (tags, maybe_ranges) = (List.split ( - tagged_ranges_matching_tag - dict_Basic_classes_Ord_abifeature dict_Abi_classes_AbiFeatureTagEquiv_abifeature (SymbolDef(null_symbol_definition)) img2 - )) - in - (* some symbols, specifically ABS symbols, needn't label a range. *) - (tags, maybe_ranges)) - -(*val name_of_symbol_def : symbol_definition -> string*) -let name_of_symbol_def sym:string= (sym.def_symname) - -(*val defined_symbols_and_ranges : forall 'abifeature. Ord 'abifeature, AbiFeatureTagEquiv 'abifeature => annotated_memory_image 'abifeature -> list ((maybe element_range) * symbol_definition)*) -let defined_symbols_and_ranges dict_Basic_classes_Ord_abifeature dict_Abi_classes_AbiFeatureTagEquiv_abifeature img2:((element_range)option*symbol_definition)list= - (Lem_list.mapMaybe (fun (tag, maybeRange) -> - (match tag with - SymbolDef(ent) -> Some (maybeRange, ent) - | _ -> failwith "impossible: non-symbol def in list of symbol defs" - )) (tagged_ranges_matching_tag - dict_Basic_classes_Ord_abifeature dict_Abi_classes_AbiFeatureTagEquiv_abifeature (SymbolDef(null_symbol_definition)) img2)) - -(*val make_ranges_definite : list (maybe element_range) -> list element_range*) -let make_ranges_definite rs:(string*range)list= - (Lem_list.map (fun (maybeR : element_range option) -> (match maybeR with - Some r -> r - | None -> failwith "impossible: range not definite, but asserted to be" - )) rs) - -(*val find_defs_matching : forall 'abifeature. Ord 'abifeature, AbiFeatureTagEquiv 'abifeature => symbol_definition -> annotated_memory_image 'abifeature -> list ((maybe element_range) * symbol_definition)*) -let find_defs_matching dict_Basic_classes_Ord_abifeature dict_Abi_classes_AbiFeatureTagEquiv_abifeature bound_def img2:((element_range)option*symbol_definition)list= - (let (ranges_and_defs : ( element_range option * symbol_definition) list) = (defined_symbols_and_ranges - dict_Basic_classes_Ord_abifeature dict_Abi_classes_AbiFeatureTagEquiv_abifeature img2) - in - (*let _ = errln ("Searching (among " ^ (show (length ranges_and_defs)) ^ ") for the bound-to symbol `" ^ bound_def.def_symname - ^ "', which came from linkable idx " ^ - (show bound_def.def_linkable_idx) ^ ", section " ^ - (show bound_def.def_syment.elf64_st_shndx) ^ - ", symtab shndx " ^ (show bound_def.def_sym_scn) ^ - ", symind " ^ (show bound_def.def_sym_idx)) - in*) - Lem_list.mapMaybe (fun (maybe_some_range, some_def) -> - (* let _ = errln ("Considering one: `" ^ some_def.def_symname ^ "'") in *) - (* match maybe_some_range with - Nothing -> failwith "symbol definition not over a definite range" - | Just some_range -> *) - (* if some_def.def_symname = bound_def.def_symname - && some_def.def_linkable_idx = bound_def.def_linkable_idx then - if some_def = bound_def - then Just(maybe_some_range, some_def) else Nothing*) - (*let _ = errln ("Found one in the same linkable: syment is " ^ - (show some_def.def_syment)) - in*) - (*else*) if some_def = bound_def - then ( - (*let _ = errln ("Found one: syment is " ^ (show some_def.def_syment)) - in*) - Some(maybe_some_range, some_def) - ) - else if some_def.def_symname = bound_def.def_symname then - (*let _ = errln ("Warning: passing over name-matching def with section " ^ - (show some_def.def_syment.elf64_st_shndx) ^ - ", symtab shndx " ^ (show some_def.def_sym_scn) ^ - ", symind " ^ (show some_def.def_sym_idx) ^ - ", linkable idx " ^ (show some_def.def_linkable_idx)) - in*) None - else None - (* end *) - ) ranges_and_defs) - - -(*val defined_symbols : forall 'abifeature. Ord 'abifeature, AbiFeatureTagEquiv 'abifeature => annotated_memory_image 'abifeature -> list symbol_definition*) -let defined_symbols dict_Basic_classes_Ord_abifeature dict_Abi_classes_AbiFeatureTagEquiv_abifeature img2:(symbol_definition)list= - (let (all_symbol_tags, all_symbol_ranges) = (symbol_def_ranges - dict_Basic_classes_Ord_abifeature dict_Abi_classes_AbiFeatureTagEquiv_abifeature img2) in - Lem_list.mapMaybe (fun tag -> - (match tag with - SymbolDef(ent) -> Some ent - | _ -> failwith "impossible: non-symbol def in list of symbol defs" - )) all_symbol_tags) - - -let default_get_reloc_symaddr dict_Basic_classes_Ord_a dict_Abi_classes_AbiFeatureTagEquiv_a bound_def_in_input output_img maybe_reloc1:Nat_big_num.num= - ((match find_defs_matching - dict_Basic_classes_Ord_a dict_Abi_classes_AbiFeatureTagEquiv_a bound_def_in_input output_img with - [] -> failwith ("internal error: bound-to symbol (name `" ^ (bound_def_in_input.def_symname ^ "') not defined")) - | (maybe_range, d) :: more -> - let v = - ((match maybe_range with - Some(el_name, (start, len)) -> - (match element_and_offset_to_address (el_name, start) output_img with - Some a -> a - | None -> failwith "internal error: could not get address for symbol" - ) - | None -> - (* okay, it'd better be an ABS symbol. *) - if Nat_big_num.equal (Nat_big_num.of_string (Uint32.to_string d.def_syment.elf64_st_shndx)) shn_abs - then Ml_bindings.nat_big_num_of_uint64 d.def_syment.elf64_st_value - else failwith "no range for non-ABS symbol" - )) - in - (match more with - [] -> v - | _ -> (*let _ = errln ("FIXME: internal error: more than one def matching bound def `" ^ - bound_def_in_input.def_symname ^ "'") - in *) v - ) - )) diff --git a/lib/ocaml_rts/linksem/missing_pervasives.ml b/lib/ocaml_rts/linksem/missing_pervasives.ml deleted file mode 100644 index 5e81cbe7..00000000 --- a/lib/ocaml_rts/linksem/missing_pervasives.ml +++ /dev/null @@ -1,590 +0,0 @@ -(*Generated by Lem from missing_pervasives.lem.*) -open Lem_basic_classes -open Lem_bool -open Lem_list -open Lem_maybe -open Lem_num -open Lem_string -open Lem_assert_extra -open Show -open Lem_sorting - -(*val naturalZero : natural*) -(*let naturalZero:natural= 0*) - -(*val id : forall 'a. 'a -> 'a*) -let id0 x:'a= x - -(*type byte*) -(*val natural_of_byte : byte -> natural*) - -let compare_byte b1 b2:int= (Nat_big_num.compare (Nat_big_num.of_int (Char.code b1)) (Nat_big_num.of_int (Char.code b2))) - -let instance_Basic_classes_Ord_Missing_pervasives_byte_dict:(char)ord_class= ({ - - compare_method = compare_byte; - - isLess_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(compare_byte f1 f2) (-1)))); - - isLessEqual_method = (fun f1 -> (fun f2 -> let result = (compare_byte f1 f2) in Lem.orderingEqual result (-1) || Lem.orderingEqual result 0)); - - isGreater_method = (fun f1 -> (fun f2 -> ( Lem.orderingEqual(compare_byte f1 f2) 1))); - - isGreaterEqual_method = (fun f1 -> (fun f2 -> let result = (compare_byte f1 f2) in Lem.orderingEqual result 1 || Lem.orderingEqual result 0))}) - -(*val char_of_byte : byte -> char*) - -(*val byte_of_char : char -> byte*) - -(* Define how to print a byte in hex *) -(*val hex_char_of_nibble : natural -> char*) -let hex_char_of_nibble n:char= - (if Nat_big_num.equal n(Nat_big_num.of_int 0) then - '0' - else if Nat_big_num.equal n(Nat_big_num.of_int 1) then - '1' - else if Nat_big_num.equal n(Nat_big_num.of_int 2) then - '2' - else if Nat_big_num.equal n(Nat_big_num.of_int 3) then - '3' - else if Nat_big_num.equal n(Nat_big_num.of_int 4) then - '4' - else if Nat_big_num.equal n(Nat_big_num.of_int 5) then - '5' - else if Nat_big_num.equal n(Nat_big_num.of_int 6) then - '6' - else if Nat_big_num.equal n(Nat_big_num.of_int 7) then - '7' - else if Nat_big_num.equal n(Nat_big_num.of_int 8) then - '8' - else if Nat_big_num.equal n(Nat_big_num.of_int 9) then - '9' - else if Nat_big_num.equal n(Nat_big_num.of_int 10) then - 'a' - else if Nat_big_num.equal n(Nat_big_num.of_int 11) then - 'b' - else if Nat_big_num.equal n(Nat_big_num.of_int 12) then - 'c' - else if Nat_big_num.equal n(Nat_big_num.of_int 13) then - 'd' - else if Nat_big_num.equal n(Nat_big_num.of_int 14) then - 'e' - else if Nat_big_num.equal n(Nat_big_num.of_int 15) then - 'f' - else -(assert false)) - -let hex_string_of_byte b:string= - (Xstring.implode [ hex_char_of_nibble ( Nat_big_num.div(Nat_big_num.of_int (Char.code b))(Nat_big_num.of_int 16)) - ; hex_char_of_nibble ( Nat_big_num.modulus(Nat_big_num.of_int (Char.code b))(Nat_big_num.of_int 16))]) - -let instance_Show_Show_Missing_pervasives_byte_dict:(char)show_class= ({ - - show_method = hex_string_of_byte}) - -(*val natural_of_decimal_digit : char -> maybe natural*) -let natural_of_decimal_digit c:(Nat_big_num.num)option= - (if c = '0' then - Some(Nat_big_num.of_int 0) - else if c = '1' then - Some(Nat_big_num.of_int 1) - else if c = '2' then - Some(Nat_big_num.of_int 2) - else if c = '3' then - Some(Nat_big_num.of_int 3) - else if c = '4' then - Some(Nat_big_num.of_int 4) - else if c = '5' then - Some(Nat_big_num.of_int 5) - else if c = '6' then - Some(Nat_big_num.of_int 6) - else if c = '7' then - Some(Nat_big_num.of_int 7) - else if c = '8' then - Some(Nat_big_num.of_int 8) - else if c = '9' then - Some(Nat_big_num.of_int 9) - else - None) - -(*val natural_of_decimal_string_helper : natural -> list char -> natural*) -let rec natural_of_decimal_string_helper acc chars:Nat_big_num.num= - ((match chars with - [] -> acc - | c :: cs -> (match natural_of_decimal_digit c with - Some dig -> natural_of_decimal_string_helper ( Nat_big_num.add( Nat_big_num.mul(Nat_big_num.of_int 10) acc) dig) cs - | None -> acc - ) - )) - -(*val natural_of_decimal_string : string -> natural*) -let natural_of_decimal_string s:Nat_big_num.num= - (natural_of_decimal_string_helper(Nat_big_num.of_int 0) (Xstring.explode s)) - -(*val hex_string_of_natural : natural -> string*) -let rec hex_string_of_natural n:string= - (if Nat_big_num.less n(Nat_big_num.of_int 16) then Xstring.implode [hex_char_of_nibble n] - else (hex_string_of_natural ( Nat_big_num.div n(Nat_big_num.of_int 16))) ^ (Xstring.implode [hex_char_of_nibble ( Nat_big_num.modulus n(Nat_big_num.of_int 16))])) - -(*val natural_of_bool : bool -> natural*) -let natural_of_bool b:Nat_big_num.num= - ((match b with - | true ->Nat_big_num.of_int 1 - | false ->Nat_big_num.of_int 0 - )) - -(*val unsafe_nat_of_natural : natural -> nat*) - -(*val unsafe_int_of_natural : natural -> int*) - -(*val byte_of_natural : natural -> byte*) - -(*val natural_ordering : natural -> natural -> ordering*) -(*let natural_ordering left right:ordering= - if (Instance_Basic_classes_Eq_Num_natural.=) left right then - EQ - else if (Instance_Basic_classes_Ord_Num_natural.<) left right then - LT - else - GT*) - -(*val merge_by : forall 'a. ('a -> 'a -> ordering) -> list 'a -> list 'a -> list 'a*) -let rec merge_by comp xs ys:'a list= - ((match (xs, ys) with - | ([], ys) -> ys - | (xs, []) -> xs - | (x::xs, y::ys) -> - if Lem.orderingEqual (comp x y) (-1) then - x::(merge_by comp xs (y::ys)) - else - y::(merge_by comp (x::xs) ys) - )) - -(*val sort_by : forall 'a. ('a -> 'a -> ordering) -> list 'a -> list 'a*) -(*let rec sort_by comp xs:list 'a= - match xs with - | [] -> [] - | [x] -> [x] - | xs -> - let ls = List.take (Instance_Num_NumIntegerDivision_nat.div List.length xs 2) xs in - let rs = List.drop (Instance_Num_NumIntegerDivision_nat.div List.length xs 2) xs in - merge_by comp (sort_by comp ls) (sort_by comp rs) - 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. (natural -> 'a -> maybe 'b) -> natural -> list 'a -> list 'b*) -let rec mapMaybei' f idx1 xs:'b list= - ((match xs with - | [] -> [] - | x::xs -> - (match f idx1 x with - | None -> mapMaybei' f ( Nat_big_num.add(Nat_big_num.of_int 1) idx1) xs - | Some e -> e :: mapMaybei' f ( Nat_big_num.add(Nat_big_num.of_int 1) idx1) xs - ) - )) - -(*val mapMaybei : forall 'a 'b. (natural -> 'a -> maybe 'b) -> list 'a -> list 'b*) - -let mapMaybei f xs:'b list= - (mapMaybei' f(Nat_big_num.of_int 0) xs) - -(** [partitionii is xs] returns a pair of lists: firstly those elements in [xs] that are - at indices in [is], and secondly the remaining elements. - It preserves the order of elements in xs. *) -(*val partitionii' : forall 'a. natural -> list natural -> list 'a - -> list (natural * 'a) (* accumulates the 'in' partition *) - -> list (natural * 'a) (* accumulates the 'out' partition *) - -> (list (natural * 'a) * list (natural * 'a))*) -let rec partitionii' (offset : Nat_big_num.num) sorted_is xs reverse_accum reverse_accum_compl:(Nat_big_num.num*'a)list*(Nat_big_num.num*'a)list= -( - (* offset o means "xs begins at index o, as reckoned by the indices in sorted_is" *)(match sorted_is with - [] -> (List.rev reverse_accum, List.rev reverse_accum_compl) - | i :: more_is -> - let (length_to_split_off : int) = (Nat_big_num.to_int ( Nat_big_num.sub_nat i offset)) - in - let (left, right) = (Lem_list.split_at length_to_split_off xs) in - let left_indices : Nat_big_num.num list = (Lem_list.genlist - (fun j -> Nat_big_num.add (Nat_big_num.of_int j) offset) - (List.length left)) - in - let left_with_indices = (list_combine left_indices left) in - (* left begins at offset, right begins at offset + i *) - (match right with - [] -> (* We got to the end of the list before the target index. *) - (List.rev reverse_accum, - List.rev_append reverse_accum_compl left_with_indices) - | x :: more_xs -> - (* x is at index i by definition, so more_xs starts with index i + 1 *) - partitionii' (Nat_big_num.add i(Nat_big_num.of_int 1)) more_is more_xs ((i, x) :: reverse_accum) - (List.rev_append left_with_indices reverse_accum_compl) - ) - )) - -(*val filteri : forall 'a. list natural -> list 'a -> list 'a*) -let filteri is xs:'a list= - (let sorted_is = (List.sort Nat_big_num.compare is) in - let (accum, accum_compl) = (partitionii'(Nat_big_num.of_int 0) sorted_is xs [] []) - in - let (just_indices, just_items) = (List.split accum) - in - just_items) - -(*val filterii : forall 'a. list natural -> list 'a -> list (natural * 'a)*) -let filterii is xs:(Nat_big_num.num*'a)list= - (let sorted_is = (List.sort Nat_big_num.compare is) in - let (accum, accum_compl) = (partitionii'(Nat_big_num.of_int 0) sorted_is xs [] []) - in - accum) - -(*val partitioni : forall 'a. list natural -> list 'a -> (list 'a * list 'a)*) -let partitioni is xs:'a list*'a list= - (let sorted_is = (List.sort Nat_big_num.compare is) in - let (accum, accum_compl) = (partitionii'(Nat_big_num.of_int 0) sorted_is xs [] []) - in - let (just_indices, just_items) = (List.split accum) - in - let (just_indices_compl, just_items_compl) = (List.split accum_compl) - in - (just_items, just_items_compl)) - -(*val partitionii : forall 'a. list natural -> list 'a -> (list (natural * 'a) * list (natural * 'a))*) -let partitionii is xs:(Nat_big_num.num*'a)list*(Nat_big_num.num*'a)list= - (let sorted_is = (List.sort Nat_big_num.compare is) in - partitionii'(Nat_big_num.of_int 0) sorted_is xs [] []) - -(** [unzip3 ls] takes a list of triples and returns a triple of lists. *) -(*val unzip3: forall 'a 'b 'c. list ('a * 'b * 'c) -> (list 'a * list 'b * list 'c)*) -let rec unzip3 l:'a list*'b list*'c list= ((match l with - | [] -> ([], [], []) - | (x, y, z) :: xyzs -> let (xs, ys, zs) = (unzip3 xyzs) in ((x :: xs), (y :: ys), (z :: zs)) -)) - -(** [zip3 ls] takes a triple of lists and returns a list of triples. *) -(*val zip3: forall 'a 'b 'c. list 'a -> list 'b -> list 'c -> list ('a * 'b * 'c)*) -let rec zip3 alist blist clist:('a*'b*'c)list= ((match (alist, blist, clist) with - | ([], [], []) -> [] - | (x :: morex, y :: morey, z :: morez) -> let more_xyz = (zip3 morex morey morez) in (x, y, z) :: more_xyz -)) - -(** [null_byte] is the null character a a byte. *) -(*val null_byte : byte*) - -(** [null_char] is the null character. *) -(*val null_char : char*) -let null_char:char= ( '\000') - -(** [println s] prints [s] to stdout, adding a trailing newline. *) -(* val println : string -> unit *) -(* declare ocaml target_rep function println = `print_endline` *) - -(** [prints s] prints [s] to stdout, without adding a trailing newline. *) -(* val prints : string -> unit *) -(* declare ocaml target_rep function prints = `print_string` *) - -(** [errln s] prints [s] to stderr, adding a trailing newline. *) -(*val errln : string -> unit*) - -(** [errs s] prints [s] to stderr, without adding a trailing newline. *) -(*val errs : string -> unit*) - -(** [outln s] prints [s] to stdout, adding a trailing newline. *) -(*val outln : string -> unit*) - -(** [outs s] prints [s] to stdout, without adding a trailing newline. *) -(*val outs : string -> unit*) - -(** [intercalate sep xs] places [sep] between all elements of [xs]. - * Made tail recursive and unrolled slightly to improve performance on large - * lists.*) -(*val intercalate' : forall 'a. 'a -> list 'a -> list 'a -> list 'a*) -let rec intercalate' sep xs accum:'a list= - ((match xs with - | [] -> List.rev accum - | [x] -> List.rev_append (List.rev (List.rev accum)) [x] - | [x; y] -> List.rev_append (List.rev (List.rev accum)) [x; sep; y] - | x::y::xs -> intercalate' sep xs (sep::(y::(sep::(x::accum)))) - )) - -(*val intercalate : forall 'a. 'a -> list 'a -> list 'a*) -let intercalate sep xs:'a list= (intercalate' sep xs []) - -(** [unlines xs] concatenates a list of strings [xs], placing each entry - * on a new line. - *) -(*val unlines : list string -> string*) -let unlines xs:string= - (List.fold_left (^) "" (intercalate "\n" xs)) - -(** [bracket xs] concatenates a list of strings [xs], separating each entry with a - * space, and bracketing the resulting string. - *) -(*val bracket : list string -> string*) -let bracket xs:string= - ("(" ^ (List.fold_left (^) "" (intercalate " " xs) ^ ")")) - -(** [string_of_list l] produces a string representation of list [l]. - *) -(*val string_of_list : forall 'a. Show 'a => list 'a -> string*) -let string_of_list dict_Show_Show_a l:string= - (let result = (intercalate "," (Lem_list.map - dict_Show_Show_a.show_method l)) in - let folded = (List.fold_left (^) "" result) in - "[" ^ (folded ^ "]")) - -let instance_Show_Show_list_dict dict_Show_Show_a:('a list)show_class= ({ - - show_method = - (string_of_list dict_Show_Show_a)}) - -(** [split_string_on_char s c] splits a string [s] into a list of substrings - * on character [c], otherwise returning the singleton list containing [s] - * if [c] is not found in [s]. - * - * NOTE: quirkily, this doesn't discard separators (e.g. because NUL characters - * are significant when indexing into string tables). FIXME: given this, is this - * function really reusable? I suspect not. - *) -(*val split_string_on_char : string -> char -> list string*) - -(* [find_substring sub s] returns the index at which *) -(*val find_substring : string -> string -> maybe natural*) - -(** [string_of_nat m] produces a string representation of natural number [m]. *) -(*val string_of_nat : nat -> string*) - -(** [string_suffix i s] returns all but the first [i] characters of [s]. - * Fails if the index is negative, or beyond the end of the string. - *) -(*val string_suffix : natural -> string -> maybe string*) - -(*val nat_length : forall 'a. list 'a -> nat*) - -(*val length : forall 'a. list 'a -> natural*) -let length xs:Nat_big_num.num= (Nat_big_num.of_int (List.length xs)) - -(*val takeRevAcc : forall 'a. natural -> list 'a -> list 'a -> list 'a*) -let rec takeRevAcc m xs rev_acc:'a list= - ((match xs with - | [] -> List.rev rev_acc - | x::xs -> - if Nat_big_num.equal m(Nat_big_num.of_int 0) then - List.rev rev_acc - else - takeRevAcc ( Nat_big_num.sub_nat m(Nat_big_num.of_int 1)) xs (x::rev_acc) - )) - -(** [take cnt xs] takes the first [cnt] elements of list [xs]. Returns a truncation - * if [cnt] is greater than the length of [xs]. - *) -(*val take : forall 'a. natural -> list 'a -> list 'a*) -let rec take0 m xs:'a list= - (takeRevAcc m xs []) - -(** [drop cnt xs] returns all but the first [cnt] elements of list [xs]. Returns an empty list - * if [cnt] is greater than the length of [xs]. - *) -(*val drop : forall 'a. natural -> list 'a -> list 'a*) -let rec drop0 m xs:'a list= - ((match xs with - | [] -> [] - | x::xs -> - if Nat_big_num.equal m(Nat_big_num.of_int 0) then - x::xs - else - drop0 ( Nat_big_num.sub_nat m(Nat_big_num.of_int 1)) xs - )) - -(** [string_prefix i s] returns the first [i] characters of [s]. - * Fails if the index is negative, or beyond the end of the string. - *) -(*val string_prefix : natural -> string -> maybe string*) -(*let string_prefix m s:maybe(string)= - let cs = String.toCharList s in - if (Instance_Basic_classes_Ord_Num_natural.>) m (length cs) then - Nothing - else - Just (String.toString (take m cs))*) -(* FIXME: isabelle *) - -(** [string_index_of c s] returns [Just(i)] where [i] is the index of the first - * occurrence if [c] in [s], if it exists, otherwise returns [Nothing]. *) -(*val string_index_of' : char -> list char -> natural -> maybe natural*) -let rec string_index_of' e ss idx1:(Nat_big_num.num)option= - ((match ss with - | [] -> None - | s::ss -> - if s = e then - Some idx1 - else - string_index_of' e ss ( Nat_big_num.add(Nat_big_num.of_int 1) idx1) - )) - -(*val string_index_of : char -> string -> maybe natural*) -(*let string_index_of e s:maybe(natural)= string_index_of' e (String.toCharList s) 0*) - -(*val index : forall 'a. natural -> list 'a -> maybe 'a*) -(*let rec index m xs:maybe 'a= - match xs with - | [] -> Nothing - | x::xs -> - if (Instance_Basic_classes_Eq_Num_natural.=) m 0 then - Just x - else - index ((Instance_Num_NumMinus_Num_natural.-) m 1) xs - end*) - -(*val find_index_helper : forall 'a. natural -> ('a -> bool) -> list 'a -> maybe natural*) -let rec find_index_helper count p xs:(Nat_big_num.num)option= - ((match xs with - | [] -> None - | y::ys -> - if p y then - Some count - else - find_index_helper ( Nat_big_num.add count(Nat_big_num.of_int 1)) p ys - )) - -(*val find_index : forall 'a. ('a -> bool) -> list 'a -> maybe natural*) -let find_index0 p xs:(Nat_big_num.num)option= (find_index_helper(Nat_big_num.of_int 0) p xs) - -(*val argv : list string*) - -(*val replicate_revacc : forall 'a. list 'a -> natural -> 'a -> list 'a*) -let rec replicate_revacc revacc len e:'a list= - ( - if(Nat_big_num.equal len (Nat_big_num.of_int 0)) then (List.rev revacc) - else - (replicate_revacc (e :: revacc) - ( Nat_big_num.sub_nat len (Nat_big_num.of_int 1)) e)) - -(*val replicate : forall 'a. natural -> 'a -> list 'a*) -let rec replicate0 len e:'a list= - (replicate_revacc [] len e) - -(* We want a tail-recursive append. reverse_append l1 l2 appends l2 to the - * reverse of l1. So we get [l1-backwards] [l2]. So just reverse l1. *) -(*val list_append : forall 'a. list 'a -> list 'a -> list 'a*) -let list_append l1 l2:'a list= - (List.rev_append (List.rev l1) l2) - -(*val list_concat : forall 'a. list (list 'a) -> list 'a*) -let list_concat ll:'a list= (List.fold_left list_append [] ll) - -(*val list_concat_map : forall 'a 'b. ('a -> list 'b) -> list 'a -> list 'b*) -let list_concat_map f l:'b list= - (list_concat (Lem_list.map f l)) - -(*val list_reverse_concat_map_helper : forall 'a 'b. ('a -> list 'b) -> list 'b -> list 'a -> list 'b*) -let rec list_reverse_concat_map_helper f acc ll:'b list= - (let lcons = (fun l -> (fun i -> i :: l)) - in - (match ll with - | [] -> acc - | item :: items -> - (* item is a thing that maps to a list. it needn't be a list yet *) - let mapped_list = (f item) - in - (* let _ = Missing_pervasives.errln ("Map function gave us a list of " ^ (show (List.length mapped_list)) ^ " items") in *) - list_reverse_concat_map_helper f (List.fold_left lcons acc (f item)) items - )) - -(*val list_reverse_concat_map : forall 'a 'b. ('a -> list 'b) -> list 'a -> list 'b*) -let list_reverse_concat_map f ll:'b list= (list_reverse_concat_map_helper f [] ll) - -(*val list_take_with_accum : forall 'a. nat -> list 'a -> list 'a -> list 'a*) -let rec list_take_with_accum n reverse_acc l:'a list= -( - (* let _ = Missing_pervasives.errs ("Taking a byte; have accumulated " ^ (show (List.length acc) ^ " so far\n")) - in *)(match n with - 0 -> List.rev reverse_acc - | _ -> (match l with - [] -> failwith "list_take_with_accum: not enough elements" - | x :: xs -> list_take_with_accum (Nat_num.nat_monus n( 1)) (x :: reverse_acc) xs - ) - )) - -(*val unsafe_string_take : natural -> string -> string*) -let unsafe_string_take m str:string= - (let m = (Nat_big_num.to_int m) in - Xstring.implode (Lem_list.take m (Xstring.explode str))) - -(** [padding_and_maybe_newline c w s] creates enough of char [c] to pad string [s] to [w] characters, - * unless [s] is of length [w - 1] or greater, in which case it generates [w] copies preceded by a newline. - * This style of formatting is used by the GNU linker in its link map output, so we - * reproduce it using this function. Note that string [s] does not appear in the - * output. *) -(*val padding_and_maybe_newline : char -> natural -> string -> string*) -let padding_and_maybe_newline c width str:string= - (let padlen = (Nat_big_num.sub_nat width (Nat_big_num.of_int (String.length str))) in - (if Nat_big_num.less_equal padlen(Nat_big_num.of_int 1) then "\n" else "") - ^ (Xstring.implode (replicate0 (if Nat_big_num.less_equal padlen(Nat_big_num.of_int 1) then width else padlen) c))) - -(** [space_padding_and_maybe_newline w s] creates enoughspaces to pad string [s] to [w] characters, - * unless [s] is of length [w - 1] or greater, in which case it generates [w] copies preceded by a newline. - * This style of formatting is used by the GNU linker in its link map output, so we - * reproduce it using this function. Note that string [s] does not appear in the - * output. *) -(*val space_padding_and_maybe_newline : natural -> string -> string*) -let space_padding_and_maybe_newline width str:string= - (padding_and_maybe_newline ' ' width str) - -(** [padded_and_maybe_newline w s] pads string [s] to [w] characters, using char [c] - * unless [s] is of length [w - 1] or greater, in which case the padding consists of - * [w] copies of [c] preceded by a newline. - * This style of formatting is used by the GNU linker in its link map output, so we - * reproduce it using this function. *) -(*val padded_and_maybe_newline : char -> natural -> string -> string*) -let padded_and_maybe_newline c width str:string= - (str ^ (padding_and_maybe_newline c width str)) - -(** [padding_to c w s] creates enough copies of [c] to pad string [s] to [w] characters, - * or 0 characters if [s] is of length [w] or greater. Note that string [s] does not appear in the - * output. *) -(*val padding_to : char -> natural -> string -> string*) -let padding_to c width str:string= - (let padlen = (Nat_big_num.sub_nat width (Nat_big_num.of_int (String.length str))) in - if Nat_big_num.less_equal padlen(Nat_big_num.of_int 0) then "" else (Xstring.implode (replicate0 padlen c))) - -(** [left_padded_to c w s] left-pads string [s] to [w] characters using [c], - * returning it unchanged if [s] is of length [w] or greater. *) -(*val left_padded_to : char -> natural -> string -> string*) -let left_padded_to c width str:string= - ((padding_to c width str) ^ str) - -(** [right_padded_to c w s] right-pads string [s] to [w] characters using [c], - * returning it unchanged if [s] is of length [w] or greater. *) -(*val right_padded_to : char -> natural -> string -> string*) -let right_padded_to c width str:string= - (str ^ (padding_to c width str)) - -(** [space_padded_and_maybe_newline w s] pads string [s] to [w] characters, using spaces, - * unless [s] is of length [w - 1] or greater, in which case the padding consists of - * [w] spaces preceded by a newline. - * This style of formatting is used by the GNU linker in its link map output, so we - * reproduce it using this function. *) -(*val space_padded_and_maybe_newline : natural -> string -> string*) -let space_padded_and_maybe_newline width str:string= - (str ^ (padding_and_maybe_newline ' ' width str)) - -(** [left_space_padded_to w s] left-pads string [s] to [w] characters using spaces, - * returning it unchanged if [s] is of length [w] or greater. *) -(*val left_space_padded_to : natural -> string -> string*) -let left_space_padded_to width str:string= - ((padding_to ' ' width str) ^ str) - -(** [right_space_padded_to w s] right-pads string [s] to [w] characters using spaces, - * returning it unchanged if [s] is of length [w] or greater. *) -(*val right_space_padded_to : natural -> string -> string*) -let right_space_padded_to width str:string= - (str ^ (padding_to ' ' width str)) - -(** [left_zero_padded_to w s] left-pads string [s] to [w] characters using zeroes, - * returning it unchanged if [s] is of length [w] or greater. *) -(*val left_zero_padded_to : natural -> string -> string*) -let left_zero_padded_to width str:string= - ((padding_to '0' width str) ^ str) - diff --git a/lib/ocaml_rts/linksem/missing_pervasivesAuxiliary.ml b/lib/ocaml_rts/linksem/missing_pervasivesAuxiliary.ml deleted file mode 100644 index 5bcc2165..00000000 --- a/lib/ocaml_rts/linksem/missing_pervasivesAuxiliary.ml +++ /dev/null @@ -1,42 +0,0 @@ -(*Generated by Lem from missing_pervasives.lem.*) -open Lem_num - -open Lem_list - -open Lem_basic_classes - -open Lem_bool - -open Lem_maybe - -open Lem_string - -open Lem_assert_extra - -open Show - -open Lem_sorting - -open Missing_pervasives - -let run_test n loc b = - if b then (Format.printf "%s: ok\n" n) else ((Format.printf "%s: FAILED\n %s\n\n" n loc); exit 1);; - - -(****************************************************) -(* *) -(* Assertions *) -(* *) -(****************************************************) - -let _ = run_test "split_string_null" "File \"missing_pervasives.lem\", line 418, character 1 to line 422, character 32\n" ( - (let afterSplit = (Ml_bindings.split_string_on_char (Xstring.implode ([null_char; 's'; null_char; 't']: char list)) null_char) - in - let _ = (prerr_endline ("split string is " ^ (string_of_list - instance_Show_Show_string_dict afterSplit))) - in (listEqualBy (=) - afterSplit [""; "s"; "t"])) -) - - - diff --git a/lib/ocaml_rts/linksem/ml_bindings.ml b/lib/ocaml_rts/linksem/ml_bindings.ml deleted file mode 100644 index ed7c05fe..00000000 --- a/lib/ocaml_rts/linksem/ml_bindings.ml +++ /dev/null @@ -1,156 +0,0 @@ -open Endianness -open Error - -open Printf -open Unix - -let string_of_unix_time (tm : Nat_big_num.num) = - let num = Nat_big_num.to_int64 tm in - let tm = Unix.gmtime (Int64.to_float num) in - let day = tm.tm_mday in - let mon = 1 + tm.tm_mon in - let year = 1900 + tm.tm_year in - let hour = tm.tm_hour in - let min = tm.tm_min in - let sec = tm.tm_sec in - Printf.sprintf "%i-%i-%iT%02i:%02i:%02i" year mon day hour min sec - -let hex_string_of_nat_pad2 i : string = - Printf.sprintf "%02i" i -;; - -let hex_string_of_big_int_pad6 i : string = - let i0 = Nat_big_num.to_int64 i in - Printf.sprintf "%06Lx" i0 -;; - -let hex_string_of_big_int_pad7 i : string = - let i0 = Nat_big_num.to_int64 i in - Printf.sprintf "%07Lx" i0 -;; - -let hex_string_of_big_int_pad2 i : string = - let i0 = Nat_big_num.to_int64 i in - Printf.sprintf "%02Lx" i0 -;; - -let hex_string_of_big_int_pad4 i : string = - let i0 = Nat_big_num.to_int64 i in - Printf.sprintf "%04Lx" i0 -;; - -let hex_string_of_big_int_pad5 i : string = - let i0 = Nat_big_num.to_int64 i in - Printf.sprintf "%05Lx" i0 -;; - -let hex_string_of_big_int_pad8 i : string = - let i0 = Nat_big_num.to_int64 i in - Printf.sprintf "%08Lx" i0 -;; - -let hex_string_of_big_int_pad16 i : string = - let i0 = Nat_big_num.to_int64 i in - Printf.sprintf "%016Lx" i0 -;; - -let hex_string_of_big_int_no_padding i : string = - let i0 = Nat_big_num.to_int64 i in - if Int64.compare i0 Int64.zero < 0 then - let i0 = Int64.neg i0 in - Printf.sprintf "-%Lx" i0 - else - Printf.sprintf "%Lx" i0 -;; - -let bytes_of_int32 (i : Int32.t) = assert false -;; - -let bytes_of_int64 (i : Int64.t) = assert false -;; - -let int32_of_quad c1 c2 c3 c4 = - let b1 = Int32.of_int (Char.code c1) in - let b2 = Int32.shift_left (Int32.of_int (Char.code c2)) 8 in - let b3 = Int32.shift_left (Int32.of_int (Char.code c3)) 16 in - let b4 = Int32.shift_left (Int32.of_int (Char.code c4)) 24 in - Int32.add b1 (Int32.add b2 (Int32.add b3 b4)) -;; - -let int64_of_oct c1 c2 c3 c4 c5 c6 c7 c8 = - let b1 = Int64.of_int (Char.code c1) in - let b2 = Int64.shift_left (Int64.of_int (Char.code c2)) 8 in - let b3 = Int64.shift_left (Int64.of_int (Char.code c3)) 16 in - let b4 = Int64.shift_left (Int64.of_int (Char.code c4)) 24 in - let b5 = Int64.shift_left (Int64.of_int (Char.code c5)) 32 in - let b6 = Int64.shift_left (Int64.of_int (Char.code c6)) 40 in - let b7 = Int64.shift_left (Int64.of_int (Char.code c7)) 48 in - let b8 = Int64.shift_left (Int64.of_int (Char.code c8)) 56 in - Int64.add b1 (Int64.add b2 (Int64.add b3 (Int64.add b4 - (Int64.add b5 (Int64.add b6 (Int64.add b7 b8)))))) -;; - -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 string_suffix index str = - if (* index < 0 *) Nat_big_num.less index (Nat_big_num.of_int 0) || - (* index > length str *) (Nat_big_num.greater index (Nat_big_num.of_int (String.length str))) then - None - else - let idx = Nat_big_num.to_int index in - Some (String.sub str idx (String.length str - idx)) -;; - -let string_prefix index str = - if (* index < 0 *) Nat_big_num.less index (Nat_big_num.of_int 0) || - (* index > length str *) (Nat_big_num.greater index (Nat_big_num.of_int (String.length str))) then - None - else - let idx = Nat_big_num.to_int index in - Some (String.sub str 0 idx) -;; - -let string_index_of (c: char) (s : string) = try Some(Nat_big_num.of_int (String.index s c)) - with Not_found -> None -;; - -let find_substring (sub: string) (s : string) = - try Some(Nat_big_num.of_int (Str.search_forward (Str.regexp_string sub) s 0)) - with Not_found -> None -;; - -let rec list_index_big_int index xs = - match xs with - | [] -> None - | x::xs -> - if Nat_big_num.equal index (Nat_big_num.of_int 0) then - Some x - else - list_index_big_int (Nat_big_num.sub index (Nat_big_num.of_int 1)) xs -;; - -let argv_list = Array.to_list Sys.argv -;; - -let nat_big_num_of_uint64 x = - (* Nat_big_num can only be made from signed integers at present. - * Workaround: make an int64, and if negative, add the high bit - * in the big-num domain. *) - let via_int64 = Uint64.to_int64 x - in - if Int64.compare via_int64 Int64.zero >= 0 then Nat_big_num.of_int64 via_int64 - else - let two_to_63 = Uint64.shift_left (Uint64.of_int 1) 63 in - let lower_by_2_to_63 = Uint64.sub x two_to_63 in - (Nat_big_num.add - (Nat_big_num.of_int64 (Uint64.to_int64 lower_by_2_to_63)) - (Nat_big_num.shift_left (Nat_big_num.of_int 1) 63) - ) diff --git a/lib/ocaml_rts/linksem/multimap.ml b/lib/ocaml_rts/linksem/multimap.ml deleted file mode 100644 index 5ba51824..00000000 --- a/lib/ocaml_rts/linksem/multimap.ml +++ /dev/null @@ -1,215 +0,0 @@ -(*Generated by Lem from multimap.lem.*) -open Lem_bool -open Lem_basic_classes -open Lem_maybe -open Lem_function -open Lem_num -open Lem_list -open Lem_set -open Lem_set_extra -open Lem_assert_extra -open Missing_pervasives -open Lem_string -open Show - -(* HMM. Is the right thing instead to implement multiset first? Probably. *) - -(* This is a set of pairs - * augmented with operations implementing a particular kind of - * map. - * - * This map differs from the Lem map in the following ways. - * - * 0. The basic idea: it's a multimap, so a single key, supplied as a "query", - * can map to many (key, value) results. - * But PROBLEM: how do we store them in a tree? We're using OCaml's - * Set implementation underneath, and that doesn't allow duplicates. - * - * 1. ANSWER: require keys still be unique, but that the user supplies an - * equivalence relation on them, which - * is coarser-grained than the ordering relation - * used to order the set. It must be consistent with it, though: - * equivalent keys should appear as a contiguous range in the - * ordering. - * - * 2. This allows many "non-equal" keys, hence present independently - * in the set of pairs, to be "equivalent" for the purposes of a - * query. - * - * 3. The coarse-grained equivalence relation can be supplied on a - * per-query basis, meaning that different queries on the same - * set can query by finer or coarser criteria (while respecting - * the requirement to be consistent with the ordering). - * - * Although this seems more complicated than writing a map from - * k to list (k, v), which would allow us to ditch the finer ordering, - * it scales better (no lists) and allows certain range queries which - * would be harder to implement under that approach. It also has the - * nice property that the inverse multimap is represented as the same - * set but with the pairs reversed. - *) - -type( 'k, 'v) multimap = ('k * 'v) Pset.set - -(* In order for bisection search within a set to work, - * we need the equivalence class to tell us whether we're less than or - * greater than the members of the key's class. - * It effectively identifies a set of ranges. *) -type 'k key_equiv = 'k -> 'k -> bool - -(* -val hasMapping : forall 'k 'v. key_equiv 'k -> multimap 'k 'v -> bool -let inline hasMapping equiv m = -*) - -(* -val mappingCount : forall 'k 'v. key_equiv 'k -> multimap 'k 'v -> natural -val any : forall 'k 'v. ('k -> 'v -> bool) -> multimap 'k 'v -> bool -val all : forall 'k 'v. ('k -> 'v -> bool) -> multimap 'k 'v -> bool -*) -(*val findLowestKVWithKEquivTo : forall 'k 'v. - Ord 'k, Ord 'v, SetType 'k, SetType 'v => - 'k - -> key_equiv 'k - -> multimap 'k 'v - -> maybe ('k * 'v) - -> maybe ('k * 'v)*) -let rec findLowestKVWithKEquivTo dict_Basic_classes_Ord_k dict_Basic_classes_Ord_v dict_Basic_classes_SetType_k dict_Basic_classes_SetType_v k equiv subSet maybeBest:('k*'v)option= - ((match Pset.choose_and_split subSet with - None -> (* empty subset *) maybeBest - | Some(lower, ((chosenK: 'k), (chosenV : 'v)), higher) -> - (* is k equiv to chosen? *) - if equiv k chosenK - then - (* is chosen less than our current best? *) - let (bestK, bestV) = ((match maybeBest with - None -> (chosenK, chosenV) - | Some(currentBestK, currentBestV) -> - if pairLess - dict_Basic_classes_Ord_v dict_Basic_classes_Ord_k (chosenK, chosenV) (currentBestK, currentBestV) - then (chosenK, chosenV) - else (currentBestK, currentBestV) - )) - in - (* recurse down lower subSet; best is whichever is lower *) - findLowestKVWithKEquivTo - dict_Basic_classes_Ord_k dict_Basic_classes_Ord_v dict_Basic_classes_SetType_k dict_Basic_classes_SetType_v k equiv lower (Some(bestK, bestV)) - else - (* k is not equiv to chosen; do we need to look lower or higher? *) - if dict_Basic_classes_Ord_k.isLess_method k chosenK - then - (* k is lower, so look lower for equivs-to-k *) - findLowestKVWithKEquivTo - dict_Basic_classes_Ord_k dict_Basic_classes_Ord_v dict_Basic_classes_SetType_k dict_Basic_classes_SetType_v k equiv lower maybeBest - else - (* k is higher *) - findLowestKVWithKEquivTo - dict_Basic_classes_Ord_k dict_Basic_classes_Ord_v dict_Basic_classes_SetType_k dict_Basic_classes_SetType_v k equiv higher maybeBest - )) - -(*val testEquiv : natural -> natural -> bool*) -let testEquiv x y:bool= (if ( Nat_big_num.greater_equal x(Nat_big_num.of_int 3) && (Nat_big_num.less x(Nat_big_num.of_int 5) && (Nat_big_num.greater_equal y(Nat_big_num.of_int 3) && Nat_big_num.less_equal y(Nat_big_num.of_int 5)))) then true - else if ( Nat_big_num.less x(Nat_big_num.of_int 3) && Nat_big_num.less y(Nat_big_num.of_int 3)) then true - else if ( Nat_big_num.greater x(Nat_big_num.of_int 5) && Nat_big_num.greater y(Nat_big_num.of_int 5)) then true - else false) - -(* Note we can't just use findLowestEquiv with inverted relations, because - * chooseAndSplit returns us (lower, chosen, higher) and we need to swap - * around how we consume that. *) -(*val findHighestKVWithKEquivTo : forall 'k 'v. - Ord 'k, Ord 'v, SetType 'k, SetType 'v => - 'k - -> key_equiv 'k - -> multimap 'k 'v - -> maybe ('k * 'v) - -> maybe ('k * 'v)*) -let rec findHighestKVWithKEquivTo dict_Basic_classes_Ord_k dict_Basic_classes_Ord_v dict_Basic_classes_SetType_k dict_Basic_classes_SetType_v k equiv subSet maybeBest:('k*'v)option= - ((match Pset.choose_and_split subSet with - None -> (* empty subset *) maybeBest - | Some(lower, ((chosenK: 'k), (chosenV : 'v)), higher) -> - (* is k equiv to chosen? *) - if equiv k chosenK - then - (* is chosen greater than our current best? *) - let (bestK, bestV) = ((match maybeBest with - None -> (chosenK, chosenV) - | Some(currentBestK, currentBestV) -> - if pairGreater - dict_Basic_classes_Ord_k dict_Basic_classes_Ord_v (chosenK, chosenV) (currentBestK, currentBestV) - then (chosenK, chosenV) - else (currentBestK, currentBestV) - )) - in - (* recurse down higher-than-chosen subSet; best is whichever is higher *) - findHighestKVWithKEquivTo - dict_Basic_classes_Ord_k dict_Basic_classes_Ord_v dict_Basic_classes_SetType_k dict_Basic_classes_SetType_v k equiv higher (Some(bestK, bestV)) - else - (* k is not equiv to chosen; do we need to look lower or higher? - * NOTE: the pairs in the set must be lexicographically ordered! *) - if dict_Basic_classes_Ord_k.isGreater_method k chosenK - then - (* k is higher than chosen, so look higher for equivs-to-k *) - findHighestKVWithKEquivTo - dict_Basic_classes_Ord_k dict_Basic_classes_Ord_v dict_Basic_classes_SetType_k dict_Basic_classes_SetType_v k equiv higher maybeBest - else - (* k is lower than chosen, so look lower *) - findHighestKVWithKEquivTo - dict_Basic_classes_Ord_k dict_Basic_classes_Ord_v dict_Basic_classes_SetType_k dict_Basic_classes_SetType_v k equiv lower maybeBest - )) - -(* get the list of all pairs with key equiv to k. *) -(*val lookupBy : forall 'k 'v. - Ord 'k, Ord 'v, SetType 'k, SetType 'v => - key_equiv 'k -> 'k -> multimap 'k 'v -> list ('k * 'v)*) -let lookupBy0 dict_Basic_classes_Ord_k dict_Basic_classes_Ord_v dict_Basic_classes_SetType_k dict_Basic_classes_SetType_v equiv k m:('k*'v)list= -( - (* Find the lowest and highest elements equiv to k. - * We do this using chooseAndSplit recursively. *)(match findLowestKVWithKEquivTo - dict_Basic_classes_Ord_k dict_Basic_classes_Ord_v dict_Basic_classes_SetType_k dict_Basic_classes_SetType_v k equiv m None with - None -> [] - | Some lowestEquiv -> - let (highestEquiv : ('k * 'v)) = -( - (* We can't just invert the relation on the set, because - * the whole set is ordered *)(match findHighestKVWithKEquivTo - dict_Basic_classes_Ord_k dict_Basic_classes_Ord_v dict_Basic_classes_SetType_k dict_Basic_classes_SetType_v k equiv m None with - None -> failwith "impossible: lowest equiv but no highest equiv" - | Some highestEquiv -> highestEquiv - )) - in - (* FIXME: split is currently needlessly inefficient on OCaml! *) - let (lowerThanLow, highEnough) = (Lem_set.split - (instance_Basic_classes_SetType_tup2_dict dict_Basic_classes_SetType_k - dict_Basic_classes_SetType_v) (instance_Basic_classes_Ord_tup2_dict dict_Basic_classes_Ord_k - dict_Basic_classes_Ord_v) lowestEquiv m) - in - let (wanted, tooHigh) = (Lem_set.split - (instance_Basic_classes_SetType_tup2_dict dict_Basic_classes_SetType_k - dict_Basic_classes_SetType_v) (instance_Basic_classes_Ord_tup2_dict dict_Basic_classes_Ord_k - dict_Basic_classes_Ord_v) highestEquiv highEnough) - in - (* NOTE that lowestEquiv is a single element; we want to include - * *all those equiv to it*, which may be non-equal. FIXME: use splitMember, - * although that needs fixing in Lem (plus an optimised OCaml version). *) - List.rev_append (List.rev (List.rev_append (List.rev (Pset.elements (let x2 =(Pset.from_list (pairCompare - dict_Basic_classes_SetType_k.setElemCompare_method dict_Basic_classes_SetType_v.setElemCompare_method) []) in Pset.fold - (fun s x2 -> - if Lem.orderingEqual 0 - (pairCompare dict_Basic_classes_Ord_k.compare_method - dict_Basic_classes_Ord_v.compare_method s lowestEquiv) then - Pset.add s x2 else x2) m x2))) (Pset.elements wanted))) ( - (* don't include the lowest and highest twice, if they're the same *) - if pairLess - dict_Basic_classes_Ord_v dict_Basic_classes_Ord_k lowestEquiv highestEquiv then (Pset.elements (let x2 =(Pset.from_list (pairCompare - dict_Basic_classes_SetType_k.setElemCompare_method dict_Basic_classes_SetType_v.setElemCompare_method) []) in Pset.fold - (fun s x2 -> - if Lem.orderingEqual 0 - (pairCompare dict_Basic_classes_Ord_k.compare_method - dict_Basic_classes_Ord_v.compare_method s highestEquiv) then - Pset.add s x2 else x2) m x2)) else [] - ) - )) - - -(* To delete all pairs with key equiv to k, can use deleteBy *) - diff --git a/lib/ocaml_rts/linksem/multimapAuxiliary.ml b/lib/ocaml_rts/linksem/multimapAuxiliary.ml deleted file mode 100644 index c5123769..00000000 --- a/lib/ocaml_rts/linksem/multimapAuxiliary.ml +++ /dev/null @@ -1,129 +0,0 @@ -(*Generated by Lem from multimap.lem.*) -open Lem_num - -open Lem_list - -open Lem_set - -open Lem_function - -open Lem_basic_classes - -open Lem_bool - -open Lem_maybe - -open Lem_string - -open Lem_assert_extra - -open Show - -open Lem_set_extra - -open Missing_pervasives - -open Multimap - -let run_test n loc b = - if b then (Format.printf "%s: ok\n" n) else ((Format.printf "%s: FAILED\n %s\n\n" n loc); exit 1);; - - -(****************************************************) -(* *) -(* Assertions *) -(* *) -(****************************************************) - -let _ = run_test "lowest_simple" "File \"multimap.lem\", line 111, character 1 to line 112, character 100\n" ( - (Lem.option_equal (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal) (findLowestKVWithKEquivTo - instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict(Nat_big_num.of_int 4) testEquiv -((Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) [ (Nat_big_num.of_int 1,Nat_big_num.of_int 0); (Nat_big_num.of_int 2,Nat_big_num.of_int 0); (Nat_big_num.of_int 3,Nat_big_num.of_int 0); (Nat_big_num.of_int 4,Nat_big_num.of_int 0); (Nat_big_num.of_int 5,Nat_big_num.of_int 0); (Nat_big_num.of_int 6,Nat_big_num.of_int 0) ]) : (Nat_big_num.num * Nat_big_num.num) Pset.set) None) (Some (Nat_big_num.of_int 3,Nat_big_num.of_int 0))) -) - -let _ = run_test "lowest_kv" "File \"multimap.lem\", line 113, character 1 to line 114, character 108\n" ( - (Lem.option_equal (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal) (findLowestKVWithKEquivTo - instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict(Nat_big_num.of_int 4) testEquiv -((Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) [ (Nat_big_num.of_int 1,Nat_big_num.of_int 0); (Nat_big_num.of_int 2,Nat_big_num.of_int 0); (Nat_big_num.of_int 3,Nat_big_num.of_int 0); (Nat_big_num.of_int 3,Nat_big_num.of_int 1); (Nat_big_num.of_int 4,Nat_big_num.of_int 0); (Nat_big_num.of_int 5,Nat_big_num.of_int 0); (Nat_big_num.of_int 6,Nat_big_num.of_int 0) ]) : (Nat_big_num.num * Nat_big_num.num) Pset.set) None) (Some (Nat_big_num.of_int 3,Nat_big_num.of_int 0))) -) - -let _ = run_test "lowest_empty" "File \"multimap.lem\", line 115, character 1 to line 116, character 48\n" ( - (Lem.option_equal (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal) (findLowestKVWithKEquivTo - instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict(Nat_big_num.of_int 4) testEquiv -((Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) []) : (Nat_big_num.num * Nat_big_num.num) Pset.set) None) None) -) - -let _ = run_test "lowest_onepast" "File \"multimap.lem\", line 117, character 1 to line 118, character 56\n" ( - (Lem.option_equal (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal) (findLowestKVWithKEquivTo - instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict(Nat_big_num.of_int 4) testEquiv -((Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) [ (Nat_big_num.of_int 6,Nat_big_num.of_int 0) ]) : (Nat_big_num.num * Nat_big_num.num) Pset.set) None) None) -) - -let _ = run_test "lowest_oneprev" "File \"multimap.lem\", line 119, character 1 to line 120, character 56\n" ( - (Lem.option_equal (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal) (findLowestKVWithKEquivTo - instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict(Nat_big_num.of_int 4) testEquiv -((Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) [ (Nat_big_num.of_int 2,Nat_big_num.of_int 0) ]) : (Nat_big_num.num * Nat_big_num.num) Pset.set) None) None) -) - -let _ = run_test "highest_simple" "File \"multimap.lem\", line 169, character 1 to line 170, character 100\n" ( - (Lem.option_equal (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal) (findHighestKVWithKEquivTo - instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict(Nat_big_num.of_int 4) testEquiv -((Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) [ (Nat_big_num.of_int 1,Nat_big_num.of_int 0); (Nat_big_num.of_int 2,Nat_big_num.of_int 0); (Nat_big_num.of_int 3,Nat_big_num.of_int 0); (Nat_big_num.of_int 4,Nat_big_num.of_int 0); (Nat_big_num.of_int 5,Nat_big_num.of_int 0); (Nat_big_num.of_int 6,Nat_big_num.of_int 0) ]) : (Nat_big_num.num * Nat_big_num.num) Pset.set) None) (Some (Nat_big_num.of_int 5,Nat_big_num.of_int 0))) -) - -let _ = run_test "highest_kv" "File \"multimap.lem\", line 171, character 1 to line 172, character 108\n" ( - (Lem.option_equal (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal) (findHighestKVWithKEquivTo - instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict(Nat_big_num.of_int 4) testEquiv -((Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) [ (Nat_big_num.of_int 1,Nat_big_num.of_int 0); (Nat_big_num.of_int 2,Nat_big_num.of_int 0); (Nat_big_num.of_int 3,Nat_big_num.of_int 0); (Nat_big_num.of_int 4,Nat_big_num.of_int 0); (Nat_big_num.of_int 5,Nat_big_num.of_int 0); (Nat_big_num.of_int 5,Nat_big_num.of_int 1); (Nat_big_num.of_int 6,Nat_big_num.of_int 0) ]) : (Nat_big_num.num * Nat_big_num.num) Pset.set) None) (Some (Nat_big_num.of_int 5,Nat_big_num.of_int 1))) -) - -let _ = run_test "highest_empty" "File \"multimap.lem\", line 173, character 1 to line 174, character 48\n" ( - (Lem.option_equal (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal) (findHighestKVWithKEquivTo - instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict(Nat_big_num.of_int 4) testEquiv -((Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) []) : (Nat_big_num.num * Nat_big_num.num) Pset.set) None) None) -) - -let _ = run_test "highest_onepast" "File \"multimap.lem\", line 175, character 1 to line 176, character 56\n" ( - (Lem.option_equal (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal) (findHighestKVWithKEquivTo - instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict(Nat_big_num.of_int 4) testEquiv -((Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) [ (Nat_big_num.of_int 6,Nat_big_num.of_int 0) ]) : (Nat_big_num.num * Nat_big_num.num) Pset.set) None) None) -) - -let _ = run_test "highest_oneprev" "File \"multimap.lem\", line 177, character 1 to line 178, character 56\n" ( - (Lem.option_equal (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal) (findHighestKVWithKEquivTo - instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict(Nat_big_num.of_int 4) testEquiv -((Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) [ (Nat_big_num.of_int 2,Nat_big_num.of_int 0) ]) : (Nat_big_num.num * Nat_big_num.num) Pset.set) None) None) -) - -let _ = run_test "lookup_simple" "File \"multimap.lem\", line 219, character 1 to line 221, character 55\n" ( - (listEqualBy (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal) (lookupBy0 - instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict testEquiv(Nat_big_num.of_int 4) ((Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) [ (Nat_big_num.of_int 1,Nat_big_num.of_int 0); (Nat_big_num.of_int 2,Nat_big_num.of_int 0); (Nat_big_num.of_int 3,Nat_big_num.of_int 0); (Nat_big_num.of_int 4,Nat_big_num.of_int 0); (Nat_big_num.of_int 5,Nat_big_num.of_int 0); (Nat_big_num.of_int 6,Nat_big_num.of_int 0) ]) : (Nat_big_num.num * Nat_big_num.num) Pset.set)) ([(Nat_big_num.of_int 3,Nat_big_num.of_int 0); (Nat_big_num.of_int 4,Nat_big_num.of_int 0); (Nat_big_num.of_int 5,Nat_big_num.of_int 0)] : (Nat_big_num.num * Nat_big_num.num) list)) -) - -let _ = run_test "lookup_kv" "File \"multimap.lem\", line 222, character 1 to line 224, character 63\n" ( - (listEqualBy (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal) (lookupBy0 - instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict testEquiv(Nat_big_num.of_int 4) ((Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) [ (Nat_big_num.of_int 1,Nat_big_num.of_int 0); (Nat_big_num.of_int 2,Nat_big_num.of_int 0); (Nat_big_num.of_int 3,Nat_big_num.of_int 0); (Nat_big_num.of_int 4,Nat_big_num.of_int 0); (Nat_big_num.of_int 4,Nat_big_num.of_int 1); (Nat_big_num.of_int 5,Nat_big_num.of_int 0); (Nat_big_num.of_int 6,Nat_big_num.of_int 0) ]) : (Nat_big_num.num * Nat_big_num.num) Pset.set)) ([(Nat_big_num.of_int 3,Nat_big_num.of_int 0); (Nat_big_num.of_int 4,Nat_big_num.of_int 0); (Nat_big_num.of_int 4,Nat_big_num.of_int 1); (Nat_big_num.of_int 5,Nat_big_num.of_int 0)] : (Nat_big_num.num * Nat_big_num.num) list)) -) - -let _ = run_test "lookup_empty" "File \"multimap.lem\", line 225, character 1 to line 226, character 65\n" ( - (listEqualBy (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal) (lookupBy0 - instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict testEquiv(Nat_big_num.of_int 4) ((Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) []) : (Nat_big_num.num * Nat_big_num.num) Pset.set)) ([]: (Nat_big_num.num * Nat_big_num.num) list)) -) - -let _ = run_test "lookup_singleton" "File \"multimap.lem\", line 227, character 1 to line 228, character 77\n" ( - (listEqualBy (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal) (lookupBy0 - instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict testEquiv(Nat_big_num.of_int 4) ((Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) [(Nat_big_num.of_int 5,Nat_big_num.of_int 0)]) : (Nat_big_num.num * Nat_big_num.num) Pset.set)) ([(Nat_big_num.of_int 5,Nat_big_num.of_int 0)]: (Nat_big_num.num * Nat_big_num.num) list)) -) - -let _ = run_test "lookup_onepast" "File \"multimap.lem\", line 229, character 1 to line 230, character 74\n" ( - (listEqualBy (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal) (lookupBy0 - instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict testEquiv(Nat_big_num.of_int 4) ((Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) [ (Nat_big_num.of_int 6,Nat_big_num.of_int 0) ]) : (Nat_big_num.num * Nat_big_num.num) Pset.set)) ([] : (Nat_big_num.num * Nat_big_num.num) list)) -) - -let _ = run_test "lookup_oneprev" "File \"multimap.lem\", line 231, character 1 to line 232, character 74\n" ( - (listEqualBy (Lem.pair_equal Nat_big_num.equal Nat_big_num.equal) (lookupBy0 - instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_Ord_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict instance_Basic_classes_SetType_Num_natural_dict testEquiv(Nat_big_num.of_int 4) ((Pset.from_list (pairCompare Nat_big_num.compare Nat_big_num.compare) [ (Nat_big_num.of_int 2,Nat_big_num.of_int 0) ]) : (Nat_big_num.num * Nat_big_num.num) Pset.set)) ([] : (Nat_big_num.num * Nat_big_num.num) list)) -) - - - diff --git a/lib/ocaml_rts/linksem/scratch.ml b/lib/ocaml_rts/linksem/scratch.ml deleted file mode 100644 index 4b57ba9d..00000000 --- a/lib/ocaml_rts/linksem/scratch.ml +++ /dev/null @@ -1,28 +0,0 @@ -(*Generated by Lem from scratch.lem.*) -open Byte_sequence -open Error -open Missing_pervasives - -open Endianness -open Show - -open Elf_file -open Elf_header -open Elf_note -open Elf_section_header_table - -open Gnu_ext_note - -let ( _:unit) = -(let res = -(Byte_sequence.acquire "/usr/bin/less" >>= (fun bs0 -> - Elf_file.read_elf32_file bs0 >>= (fun ef1 -> - let endian = (get_elf32_header_endianness ef1.elf32_file_header) in - Elf_file.get_elf32_file_section_header_string_table ef1 >>= (fun sect_hdr -> - return (gnu_ext_extract_elf32_earliest_compatible_kernel endian ef1.elf32_file_section_header_table sect_hdr bs0))))) - in - (match res with - | Fail err -> print_endline err - | Success s -> print_endline (string_of_error - instance_Show_Show_string_dict s) - )) diff --git a/lib/ocaml_rts/linksem/show.ml b/lib/ocaml_rts/linksem/show.ml deleted file mode 100644 index ef8dc4ff..00000000 --- a/lib/ocaml_rts/linksem/show.ml +++ /dev/null @@ -1,123 +0,0 @@ -(*Generated by Lem from show.lem.*) -(** [show.lem] exports the typeclass [Show] and associated functions for pretty - * printing arbitrary values. - *) - -open Lem_function -open Lem_list -open Lem_maybe -open Lem_num -open Lem_string -open Lem_string_extra - -type 'a show_class={ - show_method : 'a -> string -} - -(** [string_of_unit u] produces a string representation of unit [u]. - *) -(*val string_of_unit : unit -> string*) -let string_of_unit u:string= "()" - -let instance_Show_Show_unit_dict:(unit)show_class= ({ - - show_method = string_of_unit}) - -(** [string_of_bool b] produces a string representation of boolean [b]. - *) -(*val string_of_bool : bool -> string*) -let string_of_bool b:string= - ((match b with - | true -> "true" - | false -> "false" - )) - -let instance_Show_Show_bool_dict:(bool)show_class= ({ - - show_method = string_of_bool}) - -(** To give control over extraction as instances cannot be target specific, but - * the functions they are bound to can be... - *) -(*val string_of_string : string -> string*) -let string_of_string x:string= x - -let instance_Show_Show_string_dict:(string)show_class= ({ - - show_method = string_of_string}) - -(** [string_of_pair p] produces a string representation of pair [p]. - *) -(*val string_of_pair : forall 'a 'b. Show 'a, Show 'b => ('a * 'b) -> string*) -let string_of_pair dict_Show_Show_a dict_Show_Show_b (left, right):string= - ("(" ^ (dict_Show_Show_a.show_method left ^ (", " ^ (dict_Show_Show_b.show_method right ^ ")")))) - -let instance_Show_Show_tup2_dict dict_Show_Show_a dict_Show_Show_b:('a*'b)show_class= ({ - - show_method = - (string_of_pair dict_Show_Show_a dict_Show_Show_b)}) - -(** [string_of_triple p] produces a string representation of triple [p]. - *) -(*val string_of_triple : forall 'a 'b 'c. Show 'a, Show 'b, Show 'c => ('a * 'b * 'c) -> string*) -let string_of_triple dict_Show_Show_a dict_Show_Show_b dict_Show_Show_c (left, middle, right):string= - ("(" ^ (dict_Show_Show_a.show_method left ^ (", " ^ (dict_Show_Show_b.show_method middle ^ (", " ^ (dict_Show_Show_c.show_method right ^ ")")))))) - -let instance_Show_Show_tup3_dict dict_Show_Show_a dict_Show_Show_b dict_Show_Show_c:('a*'b*'c)show_class= ({ - - show_method = - (string_of_triple dict_Show_Show_a dict_Show_Show_b dict_Show_Show_c)}) - -(** [string_of_quad p] produces a string representation of quad [p]. - *) -(*val string_of_quad : forall 'a 'b 'c 'd. Show 'a, Show 'b, Show 'c, Show 'd => ('a * 'b * 'c * 'd) -> string*) -let string_of_quad dict_Show_Show_a dict_Show_Show_b dict_Show_Show_c dict_Show_Show_d (left, middle1, middle2, right):string= - ("(" ^ (dict_Show_Show_a.show_method left ^ (", " ^ (dict_Show_Show_b.show_method middle1 ^ (", " ^ (dict_Show_Show_c.show_method middle2 ^ (", " ^ (dict_Show_Show_d.show_method right ^ ")")))))))) - -let instance_Show_Show_tup4_dict dict_Show_Show_a dict_Show_Show_b dict_Show_Show_c dict_Show_Show_d:('a*'b*'c*'d)show_class= ({ - - show_method = - (string_of_quad dict_Show_Show_a dict_Show_Show_b dict_Show_Show_c - dict_Show_Show_d)}) - -(** [string_of_maybe m] produces a string representation of maybe value [m]. - *) -(*val string_of_maybe : forall 'a. Show 'a => maybe 'a -> string*) -let string_of_maybe dict_Show_Show_a m:string= - ((match m with - | None -> "Nothing" - | Some e -> "Just " ^ - dict_Show_Show_a.show_method e - )) - -let instance_Show_Show_Maybe_maybe_dict dict_Show_Show_a:('a option)show_class= ({ - - show_method = - (string_of_maybe dict_Show_Show_a)}) - -(** [show_else s m] produces a string representation of maybe [m], using [s] - * in the case [m] = Nothing. *) -(*val show_else : forall 'a. Show 'a => string -> maybe 'a -> string*) -let show_else dict_Show_Show_a subst m:string= - ((match m with - Some x -> dict_Show_Show_a.show_method x - | None -> subst - )) - -(** [string_of_nat m] produces a string representation of nat value [m]. - *) -(*val string_of_nat : nat -> string*) - -let instance_Show_Show_nat_dict:(int)show_class= ({ - - show_method = Pervasives.string_of_int}) - -let instance_Show_Show_Num_natural_dict:(Nat_big_num.num)show_class= ({ - - show_method = Nat_big_num.to_string}) - -(*val string_of_integer : integer -> string*) - -let instance_Show_Show_Num_integer_dict:(Nat_big_num.num)show_class= ({ - - show_method = Nat_big_num.to_string}) diff --git a/lib/ocaml_rts/linksem/src_lem_library/bit.ml b/lib/ocaml_rts/linksem/src_lem_library/bit.ml deleted file mode 100644 index bd972008..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/bit.ml +++ /dev/null @@ -1,19 +0,0 @@ -type bit = Zero | One - -let to_bool b = match b with | Zero -> false | _ -> true -let bn b = match b with | Zero -> One | One -> Zero -let bor b1 b2 = match (b1,b2) with - | Zero,Zero -> Zero - | _ -> One -let xor b1 b2 = match (b1,b2) with - | Zero,Zero -> Zero - | Zero,One | One,Zero -> One - | _ -> Zero -let band b1 b2 = match (b1,b2) with - | One,One -> One - | _ -> Zero - -let add b1 b2 = match (b1,b2) with - | Zero,Zero -> Zero, false - | Zero,One | One,Zero -> One, false - | One,One -> Zero, true diff --git a/lib/ocaml_rts/linksem/src_lem_library/bit.mli b/lib/ocaml_rts/linksem/src_lem_library/bit.mli deleted file mode 100644 index a39c1a09..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/bit.mli +++ /dev/null @@ -1,8 +0,0 @@ -type bit = Zero | One - -val to_bool : bit -> bool -val bn : bit -> bit -val bor : bit -> bit -> bit -val xor : bit -> bit -> bit -val band : bit -> bit -> bit -val add : bit -> bit -> bit * bool diff --git a/lib/ocaml_rts/linksem/src_lem_library/either.ml b/lib/ocaml_rts/linksem/src_lem_library/either.ml deleted file mode 100644 index ddf1b214..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/either.ml +++ /dev/null @@ -1,24 +0,0 @@ -type ('a, 'b) either = - | Left of 'a - | Right of 'b - -let either_case fa fb x = match x with - | (Left a) -> fa a - | (Right b) -> fb b - -let eitherEqualBy eql eqr (left: ('a, 'b) either) (right: ('a, 'b) either) = - match (left, right) with - | ((Left l), (Left l')) -> eql l l' - | ((Right r), (Right r')) -> eqr r r' - | _ -> false - -let rec either_partition l = ((match l with - | [] -> ([], []) - | x :: xs -> begin - let (ll, rl) = (either_partition xs) in - (match x with - | (Left l) -> ((l::ll), rl) - | (Right r) -> (ll, (r::rl)) - ) - end -)) diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem.ml b/lib/ocaml_rts/linksem/src_lem_library/lem.ml deleted file mode 100644 index 2ff0090f..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem.ml +++ /dev/null @@ -1,103 +0,0 @@ -(* ========================================================================== *) -(* Tuples *) -(* ========================================================================== *) - - -let pair_equal eq1 eq2 (a1, b1) (a2, b2) = - (eq1 a1 a2) && (eq2 b1 b2) - -let pair_swap (v1, v2) = (v2, v1) - -let curry f v1 v2 = f (v1, v2) - -let uncurry f (v1, v2) = f v1 v2 - -(* ========================================================================== *) -(* Orderings *) -(* ========================================================================== *) - -let orderingIsLess r = (r < 0) -let orderingIsGreater r = (r > 0) -let orderingIsEqual r = (r = 0) - -let ordering_cases (r : int) (lt : 'a) (eq : 'a) (gt : 'a) : 'a = - (if (r < 0) then lt else - if (r = 0) then eq else gt) - -let orderingEqual r1 r2 = - ordering_cases r1 (orderingIsLess r2) (orderingIsEqual r2) (orderingIsGreater r2) - - -(* ========================================================================== *) -(* Lists *) -(* ========================================================================== *) - - -let list_null = function - | [] -> true - | _ -> false - -let rec lexicographic_compare cmp l1 l2 : int = (match (l1,l2) with - | ([], []) -> 0 - | ([], _::_) -> -1 - | (_::_, []) -> 1 - | (x::xs, y::ys) -> begin - ordering_cases (cmp x y) (-1) (lexicographic_compare cmp xs ys) (1) - end -) - -let rec lexicographic_less less less_eq l1 l2 = ((match (l1,l2) with - | ([], []) -> false - | ([], _::_) -> true - | (_::_, []) -> false - | (x::xs, y::ys) -> ((less x y) || ((less_eq x y) && (lexicographic_less less less_eq xs ys))) -)) - -let rec lexicographic_less_eq less less_eq l1 l2 = ((match (l1,l2) with - | ([], []) -> true - | ([], _::_) -> true - | (_::_, []) -> false - | (x::xs, y::ys) -> (less x y || (less_eq x y && lexicographic_less_eq less less_eq xs ys)) -)) - -let rec list_index l n = (match l with - | [] -> None - | x :: xs -> if n = 0 then (Some x) else list_index xs (n - 1) -) - - -(* ========================================================================== *) -(* Options *) -(* ========================================================================== *) - -let is_none = function - | None -> true - | Some _ -> false - -let is_some = function - | None -> false - | Some _ -> true - -let option_case d f mb = (match mb with - | Some a -> f a - | None -> d -) - -let option_default d = function - | Some a -> a - | None -> d - -let option_map f = function - | Some a -> Some (f a) - | None -> None - -let option_bind m f = - match m with - | Some a -> f a - | None -> None - -let option_equal eq o1 o2 = match (o1, o2) with - | (None, None) -> true - | (None, Some _) -> false - | (Some _, None) -> false - | (Some x1, Some x2) -> eq x1 x2 diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_assert_extra.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_assert_extra.ml deleted file mode 100644 index 3b4a1548..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_assert_extra.ml +++ /dev/null @@ -1,28 +0,0 @@ -(*Generated by Lem from assert_extra.lem.*) - -open Xstring - -(* ------------------------------------ *) -(* failing with a proper error message *) -(* ------------------------------------ *) - -(*val failwith: forall 'a. string -> 'a*) - -(* ------------------------------------ *) -(* failing without an error message *) -(* ------------------------------------ *) - -(*val fail : forall 'a. 'a*) -(*let fail = failwith "fail"*) - -(* ------------------------------------- *) -(* assertions *) -(* ------------------------------------- *) - -(*val ensure : bool -> string -> unit*) -let ensure test msg = -(if test then - () - else - failwith msg) -;; diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_basic_classes.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_basic_classes.ml deleted file mode 100644 index 9f24e5fb..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_basic_classes.ml +++ /dev/null @@ -1,323 +0,0 @@ -(*Generated by Lem from basic_classes.lem.*) -(******************************************************************************) -(* Basic Type Classes *) -(******************************************************************************) - -open Lem_bool - -(* ========================================================================== *) -(* Equality *) -(* ========================================================================== *) - -(* Lem`s default equality (=) is defined by the following type-class Eq. - This typeclass should define equality on an abstract datatype 'a. It should - always coincide with the default equality of Coq, HOL and Isabelle. - For OCaml, it might be different, since abstract datatypes like sets - might have fancy equalities. *) - -type 'a eq_class= { - isEqual_method : 'a -> 'a -> bool; - isInequal_method : 'a -> 'a -> bool -} - - -(* (=) should for all instances be an equivalence relation - The isEquivalence predicate of relations could be used here. - However, this would lead to a cyclic dependency. *) - -(* TODO: add later, once lemmata can be assigned to classes -lemma eq_equiv: ((forall x. (x = x)) && - (forall x y. (x = y) <-> (y = x)) && - (forall x y z. ((x = y) && (y = z)) --> (x = z))) -*) - -(* Structural equality *) - -(* Sometimes, it is also handy to be able to use structural equality. - This equality is mapped to the build-in equality of backends. This equality - differs significantly for each backend. For example, OCaml can`t check equality - of function types, whereas HOL can. When using structural equality, one should - know what one is doing. The only guarentee is that is behaves like - the native backend equality. - - A lengthy name for structural equality is used to discourage its direct use. - It also ensures that users realise it is unsafe (e.g. OCaml can`t check two functions - for equality *) -(*val unsafe_structural_equality : forall 'a. 'a -> 'a -> bool*) - -(*val unsafe_structural_inequality : forall 'a. 'a -> 'a -> bool*) -let unsafe_structural_inequality x y = (not (x = y)) - -(* The default for equality is the unsafe structural one. It can - (and should) be overriden for concrete types later. *) - -let instance_Basic_classes_Eq_var_dict =({ - - isEqual_method = (=); - - isInequal_method = unsafe_structural_inequality}) - - -(* ========================================================================== *) -(* Orderings *) -(* ========================================================================== *) - -(* The type-class Ord represents total orders (also called linear orders) *) -(*type ordering = LT | EQ | GT*) - -(*let orderingIsLess r = (match r with LT -> true | _ -> false end)*) -(*let orderingIsGreater r = (match r with GT -> true | _ -> false end)*) -(*let orderingIsEqual r = (match r with EQ -> true | _ -> false end)*) - -(*let ordering_cases r lt eq gt = - if orderingIsLess r then lt else - if orderingIsEqual r then eq else gt*) - - -(*val orderingEqual : ordering -> ordering -> bool*) - -let instance_Basic_classes_Eq_Basic_classes_ordering_dict =({ - - isEqual_method = Lem.orderingEqual; - - isInequal_method = (fun x y->not (Lem.orderingEqual x y))}) - -type 'a ord_class= { - compare_method : 'a -> 'a -> int; - isLess_method : 'a -> 'a -> bool; - isLessEqual_method : 'a -> 'a -> bool; - isGreater_method : 'a -> 'a -> bool; - isGreaterEqual_method : 'a -> 'a -> bool -} - - -(* Ocaml provides default, polymorphic compare functions. Let's use them - as the default. However, because used perhaps in a typeclass they must be - defined for all targets. So, explicitly declare them as undefined for - all other targets. If explictly declare undefined, the type-checker won't complain and - an error will only be raised when trying to actually output the function for a certain - target. *) -(*val defaultCompare : forall 'a. 'a -> 'a -> ordering*) -(*val defaultLess : forall 'a. 'a -> 'a -> bool*) -(*val defaultLessEq : forall 'a. 'a -> 'a -> bool*) -(*val defaultGreater : forall 'a. 'a -> 'a -> bool*) -(*val defaultGreaterEq : forall 'a. 'a -> 'a -> bool*) -;; - -let genericCompare (less: 'a -> 'a -> bool) (equal: 'a -> 'a -> bool) (x : 'a) (y : 'a) = -(if less x y then - (-1) - else if equal x y then - 0 - else - 1) - - -(* -(* compare should really be a total order *) -lemma ord_OK_1: ( - (forall x y. (compare x y = EQ) <-> (compare y x = EQ)) && - (forall x y. (compare x y = LT) <-> (compare y x = GT))) - -lemma ord_OK_2: ( - (forall x y z. (x <= y) && (y <= z) --> (x <= z)) && - (forall x y. (x <= y) || (y <= x)) -) -*) - -(* let's derive a compare function from the Ord type-class *) -(*val ordCompare : forall 'a. Eq 'a, Ord 'a => 'a -> 'a -> ordering*) -let ordCompare dict_Basic_classes_Eq_a dict_Basic_classes_Ord_a x y = -(if ( dict_Basic_classes_Ord_a.isLess_method x y) then (-1) else - if ( dict_Basic_classes_Eq_a.isEqual_method x y) then 0 else 1) - -type 'a ordMaxMin_class= { - max_method : 'a -> 'a -> 'a; - min_method : 'a -> 'a -> 'a -} - -(*val minByLessEqual : forall 'a. ('a -> 'a -> bool) -> 'a -> 'a -> 'a*) -let minByLessEqual le x y = (if (le x y) then x else y) - -(*val maxByLessEqual : forall 'a. ('a -> 'a -> bool) -> 'a -> 'a -> 'a*) -let maxByLessEqual le x y = (if (le y x) then x else y) - -(*val defaultMax : forall 'a. Ord 'a => 'a -> 'a -> 'a*) - -(*val defaultMin : forall 'a. Ord 'a => 'a -> 'a -> 'a*) - -let instance_Basic_classes_OrdMaxMin_var_dict dict_Basic_classes_Ord_a =({ - - max_method = max; - - min_method = min}) - - -(* ========================================================================== *) -(* SetTypes *) -(* ========================================================================== *) - -(* Set implementations use often an order on the elements. This allows the OCaml implementation - to use trees for implementing them. At least, one needs to be able to check equality on sets. - One could use the Ord type-class for sets. However, defining a special typeclass is cleaner - and allows more flexibility. One can make e.g. sure, that this type-class is ignored for - backends like HOL or Isabelle, which don't need it. Moreover, one is not forced to also instantiate - the functions "<", "<=" ... *) - -type 'a setType_class= { - setElemCompare_method : 'a -> 'a -> int -} - -let instance_Basic_classes_SetType_var_dict =({ - - setElemCompare_method = compare}) - -(* ========================================================================== *) -(* Instantiations *) -(* ========================================================================== *) - -let instance_Basic_classes_Eq_bool_dict =({ - - isEqual_method = (=); - - isInequal_method = (fun x y->not ((=) x y))}) - -let boolCompare b1 b2 = ((match (b1, b2) with - | (true, true) -> 0 - | (true, false) -> 1 - | (false, true) -> (-1) - | (false, false) -> 0 -)) - -let instance_Basic_classes_SetType_bool_dict =({ - - setElemCompare_method = boolCompare}) - -(* strings *) - -(*val charEqual : char -> char -> bool*) - -let instance_Basic_classes_Eq_char_dict =({ - - isEqual_method = (=); - - isInequal_method = (fun left right->not (left = right))}) - -(*val stringEquality : string -> string -> bool*) - -let instance_Basic_classes_Eq_string_dict =({ - - isEqual_method = (=); - - isInequal_method = (fun l r->not (l = r))}) - -(* pairs *) - -(*val pairEqual : forall 'a 'b. Eq 'a, Eq 'b => ('a * 'b) -> ('a * 'b) -> bool*) -(*let pairEqual (a1, b1) (a2, b2) = ( - dict_Basic_classes_Eq_a.isEqual_method a1 a2) && ( dict_Basic_classes_Eq_b.isEqual_method b1 b2)*) - -(*val pairEqualBy : forall 'a 'b. ('a -> 'a -> bool) -> ('b -> 'b -> bool) -> ('a * 'b) -> ('a * 'b) -> bool*) - -let instance_Basic_classes_Eq_tup2_dict dict_Basic_classes_Eq_a dict_Basic_classes_Eq_b =({ - - isEqual_method = (Lem.pair_equal - dict_Basic_classes_Eq_a.isEqual_method dict_Basic_classes_Eq_b.isEqual_method); - - isInequal_method = (fun x y->not ((Lem.pair_equal - dict_Basic_classes_Eq_a.isEqual_method dict_Basic_classes_Eq_b.isEqual_method x y)))}) - -(*val pairCompare : forall 'a 'b. ('a -> 'a -> ordering) -> ('b -> 'b -> ordering) -> ('a * 'b) -> ('a * 'b) -> ordering*) -let pairCompare cmpa cmpb (a1, b1) (a2, b2) = - (Lem.ordering_cases (cmpa a1 a2) (-1) (cmpb b1 b2) 1) - -let pairLess dict_Basic_classes_Ord_a dict_Basic_classes_Ord_b (x1, x2) (y1, y2) = (( - dict_Basic_classes_Ord_b.isLess_method x1 y1) || (( dict_Basic_classes_Ord_b.isLessEqual_method x1 y1) && ( dict_Basic_classes_Ord_a.isLess_method x2 y2))) -let pairLessEq dict_Basic_classes_Ord_a dict_Basic_classes_Ord_b (x1, x2) (y1, y2) = (( - dict_Basic_classes_Ord_b.isLess_method x1 y1) || (( dict_Basic_classes_Ord_b.isLessEqual_method x1 y1) && ( dict_Basic_classes_Ord_a.isLessEqual_method x2 y2))) - -let pairGreater dict_Basic_classes_Ord_a dict_Basic_classes_Ord_b x12 y12 = (pairLess - dict_Basic_classes_Ord_b dict_Basic_classes_Ord_a y12 x12) -let pairGreaterEq dict_Basic_classes_Ord_a dict_Basic_classes_Ord_b x12 y12 = (pairLessEq - dict_Basic_classes_Ord_b dict_Basic_classes_Ord_a y12 x12) - -let instance_Basic_classes_Ord_tup2_dict dict_Basic_classes_Ord_a dict_Basic_classes_Ord_b =({ - - compare_method = (pairCompare - dict_Basic_classes_Ord_a.compare_method dict_Basic_classes_Ord_b.compare_method); - - isLess_method = - (pairLess dict_Basic_classes_Ord_b dict_Basic_classes_Ord_a); - - isLessEqual_method = - (pairLessEq dict_Basic_classes_Ord_b dict_Basic_classes_Ord_a); - - isGreater_method = - (pairGreater dict_Basic_classes_Ord_a dict_Basic_classes_Ord_b); - - isGreaterEqual_method = - (pairGreaterEq dict_Basic_classes_Ord_a dict_Basic_classes_Ord_b)}) - -let instance_Basic_classes_SetType_tup2_dict dict_Basic_classes_SetType_a dict_Basic_classes_SetType_b =({ - - setElemCompare_method = (pairCompare - dict_Basic_classes_SetType_a.setElemCompare_method dict_Basic_classes_SetType_b.setElemCompare_method)}) - - -(* triples *) - -(*val tripleEqual : forall 'a 'b 'c. Eq 'a, Eq 'b, Eq 'c => ('a * 'b * 'c) -> ('a * 'b * 'c) -> bool*) -let tripleEqual dict_Basic_classes_Eq_a dict_Basic_classes_Eq_b dict_Basic_classes_Eq_c (x1, x2, x3) (y1, y2, y3) = ( (Lem.pair_equal - dict_Basic_classes_Eq_a.isEqual_method (Lem.pair_equal dict_Basic_classes_Eq_b.isEqual_method dict_Basic_classes_Eq_c.isEqual_method)(x1, (x2, x3)) (y1, (y2, y3)))) - -let instance_Basic_classes_Eq_tup3_dict dict_Basic_classes_Eq_a dict_Basic_classes_Eq_b dict_Basic_classes_Eq_c =({ - - isEqual_method = - (tripleEqual dict_Basic_classes_Eq_a dict_Basic_classes_Eq_b - dict_Basic_classes_Eq_c); - - isInequal_method = (fun x y->not (tripleEqual - dict_Basic_classes_Eq_a dict_Basic_classes_Eq_b dict_Basic_classes_Eq_c x y))}) - -(*val tripleCompare : forall 'a 'b 'c. ('a -> 'a -> ordering) -> ('b -> 'b -> ordering) -> ('c -> 'c -> ordering) -> ('a * 'b * 'c) -> ('a * 'b * 'c) -> ordering*) -let tripleCompare cmpa cmpb cmpc (a1, b1, c1) (a2, b2, c2) = -(pairCompare cmpa (pairCompare cmpb cmpc) (a1, (b1, c1)) (a2, (b2, c2))) - -let tripleLess dict_Basic_classes_Ord_a dict_Basic_classes_Ord_b dict_Basic_classes_Ord_c (x1, x2, x3) (y1, y2, y3) = (pairLess - (instance_Basic_classes_Ord_tup2_dict dict_Basic_classes_Ord_b - dict_Basic_classes_Ord_c) dict_Basic_classes_Ord_a (x1, (x2, x3)) (y1, (y2, y3))) -let tripleLessEq dict_Basic_classes_Ord_a dict_Basic_classes_Ord_b dict_Basic_classes_Ord_c (x1, x2, x3) (y1, y2, y3) = (pairLessEq - (instance_Basic_classes_Ord_tup2_dict dict_Basic_classes_Ord_b - dict_Basic_classes_Ord_c) dict_Basic_classes_Ord_a (x1, (x2, x3)) (y1, (y2, y3))) - -let tripleGreater dict_Basic_classes_Ord_a dict_Basic_classes_Ord_b dict_Basic_classes_Ord_c x123 y123 = (tripleLess - dict_Basic_classes_Ord_c dict_Basic_classes_Ord_b dict_Basic_classes_Ord_a y123 x123) -let tripleGreaterEq dict_Basic_classes_Ord_a dict_Basic_classes_Ord_b dict_Basic_classes_Ord_c x123 y123 = (tripleLessEq - dict_Basic_classes_Ord_c dict_Basic_classes_Ord_b dict_Basic_classes_Ord_a y123 x123) - -let instance_Basic_classes_Ord_tup3_dict dict_Basic_classes_Ord_a dict_Basic_classes_Ord_b dict_Basic_classes_Ord_c =({ - - compare_method = (tripleCompare - dict_Basic_classes_Ord_a.compare_method dict_Basic_classes_Ord_b.compare_method dict_Basic_classes_Ord_c.compare_method); - - isLess_method = - (tripleLess dict_Basic_classes_Ord_a dict_Basic_classes_Ord_b - dict_Basic_classes_Ord_c); - - isLessEqual_method = - (tripleLessEq dict_Basic_classes_Ord_a dict_Basic_classes_Ord_b - dict_Basic_classes_Ord_c); - - isGreater_method = - (tripleGreater dict_Basic_classes_Ord_c dict_Basic_classes_Ord_b - dict_Basic_classes_Ord_a); - - isGreaterEqual_method = - (tripleGreaterEq dict_Basic_classes_Ord_c dict_Basic_classes_Ord_b - dict_Basic_classes_Ord_a)}) - -let instance_Basic_classes_SetType_tup3_dict dict_Basic_classes_SetType_a dict_Basic_classes_SetType_b dict_Basic_classes_SetType_c =({ - - setElemCompare_method = (tripleCompare - dict_Basic_classes_SetType_a.setElemCompare_method dict_Basic_classes_SetType_b.setElemCompare_method dict_Basic_classes_SetType_c.setElemCompare_method)}) - diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_bool.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_bool.ml deleted file mode 100644 index 9b6eb0f6..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_bool.ml +++ /dev/null @@ -1,66 +0,0 @@ -(*Generated by Lem from bool.lem.*) - - -(* The type bool is hard-coded, so are true and false *) - -(* ----------------------- *) -(* not *) -(* ----------------------- *) - -(*val not : bool -> bool*) -(*let not b = match b with - | true -> false - | false -> true -end*) - -(* ----------------------- *) -(* and *) -(* ----------------------- *) - -(*val && [and] : bool -> bool -> bool*) -(*let && b1 b2 = match (b1, b2) with - | (true, true) -> true - | _ -> false -end*) - - -(* ----------------------- *) -(* or *) -(* ----------------------- *) - -(*val || [or] : bool -> bool -> bool*) -(*let || b1 b2 = match (b1, b2) with - | (false, false) -> false - | _ -> true -end*) - - -(* ----------------------- *) -(* implication *) -(* ----------------------- *) - -(*val --> [imp] : bool -> bool -> bool*) -(*let --> b1 b2 = match (b1, b2) with - | (true, false) -> false - | _ -> true -end*) - - -(* ----------------------- *) -(* equivalence *) -(* ----------------------- *) - -(*val <-> [equiv] : bool -> bool -> bool*) -(*let <-> b1 b2 = match (b1, b2) with - | (true, true) -> true - | (false, false) -> true - | _ -> false -end*) - - -(* ----------------------- *) -(* xor *) -(* ----------------------- *) - -(*val xor : bool -> bool -> bool*) - diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_either.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_either.ml deleted file mode 100644 index 9f1b4ad8..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_either.ml +++ /dev/null @@ -1,87 +0,0 @@ -(*Generated by Lem from either.lem.*) - - -open Lem_bool -open Lem_basic_classes -open Lem_list -open Lem_tuple -open Either - -(*type either 'a 'b - = Left of 'a - | Right of 'b*) - - -(* -------------------------------------------------------------------------- *) -(* Equality. *) -(* -------------------------------------------------------------------------- *) - -(*val eitherEqual : forall 'a 'b. Eq 'a, Eq 'b => (either 'a 'b) -> (either 'a 'b) -> bool*) -(*val eitherEqualBy : forall 'a 'b. ('a -> 'a -> bool) -> ('b -> 'b -> bool) -> (either 'a 'b) -> (either 'a 'b) -> bool*) - -(*let eitherEqualBy eql eqr (left: either 'a 'b) (right: either 'a 'b) = - match (left, right) with - | (Left l, Left l') -> eql l l' - | (Right r, Right r') -> eqr r r' - | _ -> false - end*) -(*let eitherEqual = eitherEqualBy - dict_Basic_classes_Eq_a.isEqual_method dict_Basic_classes_Eq_b.isEqual_method*) - -let instance_Basic_classes_Eq_Either_either_dict dict_Basic_classes_Eq_a dict_Basic_classes_Eq_b =({ - - isEqual_method = (Either.eitherEqualBy - dict_Basic_classes_Eq_a.isEqual_method dict_Basic_classes_Eq_b.isEqual_method); - - isInequal_method = (fun x y->not ((Either.eitherEqualBy - dict_Basic_classes_Eq_a.isEqual_method dict_Basic_classes_Eq_b.isEqual_method x y)))}) - -let either_setElemCompare cmpa cmpb x y = -((match (x, y) with - | (Either.Left x', Either.Left y') -> cmpa x' y' - | (Either.Right x', Either.Right y') -> cmpb x' y' - | (Either.Left _, Either.Right _) -> (-1) - | (Either.Right _, Either.Left _) -> 1 - )) - -let instance_Basic_classes_SetType_Either_either_dict dict_Basic_classes_SetType_a dict_Basic_classes_SetType_b =({ - - setElemCompare_method = (fun x y->either_setElemCompare - dict_Basic_classes_SetType_a.setElemCompare_method dict_Basic_classes_SetType_b.setElemCompare_method x y)}) - - -(* -------------------------------------------------------------------------- *) -(* Utility functions. *) -(* -------------------------------------------------------------------------- *) - -(*val isLeft : forall 'a 'b. either 'a 'b -> bool*) - -(*val isRight : forall 'a 'b. either 'a 'b -> bool*) - - -(*val either : forall 'a 'b 'c. ('a -> 'c) -> ('b -> 'c) -> either 'a 'b -> 'c*) -(*let either fa fb x = match x with - | Left a -> fa a - | Right b -> fb b -end*) - - -(*val partitionEither : forall 'a 'b. list (either 'a 'b) -> (list 'a * list 'b)*) -(*let rec partitionEither l = match l with - | [] -> ([], []) - | x :: xs -> begin - let (ll, rl) = partitionEither xs in - match x with - | Left l -> (l::ll, rl) - | Right r -> (ll, r::rl) - end - end -end*) - - -(*val lefts : forall 'a 'b. list (either 'a 'b) -> list 'a*) - - -(*val rights : forall 'a 'b. list (either 'a 'b) -> list 'b*) - - diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_function.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_function.ml deleted file mode 100644 index 677adc4c..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_function.ml +++ /dev/null @@ -1,53 +0,0 @@ -(*Generated by Lem from function.lem.*) -(******************************************************************************) -(* A library for common operations on functions *) -(******************************************************************************) - -open Lem_bool -open Lem_basic_classes - -(* ----------------------- *) -(* identity function *) -(* ----------------------- *) - -(*val id : forall 'a. 'a -> 'a*) -let id x = x - - -(* ----------------------- *) -(* constant function *) -(* ----------------------- *) - -(*val const : forall 'a 'b. 'a -> 'b -> 'a*) - - -(* ----------------------- *) -(* function composition *) -(* ----------------------- *) - -(*val comb : forall 'a 'b 'c. ('b -> 'c) -> ('a -> 'b) -> ('a -> 'c)*) -let comb f g = (fun x -> f (g x)) - - -(* ----------------------- *) -(* function application *) -(* ----------------------- *) - -(*val $ [apply] : forall 'a 'b. ('a -> 'b) -> ('a -> 'b)*) -(*let $ f = (fun x -> f x)*) - -(* ----------------------- *) -(* flipping argument order *) -(* ----------------------- *) - -(*val flip : forall 'a 'b 'c. ('a -> 'b -> 'c) -> ('b -> 'a -> 'c)*) -let flip f = (fun x y -> f y x) - - -(* currying / uncurrying *) - -(*val curry : forall 'a 'b 'c. (('a * 'b) -> 'c) -> 'a -> 'b -> 'c*) -let curry f = (fun a b -> f (a, b)) - -(*val uncurry : forall 'a 'b 'c. ('a -> 'b -> 'c) -> ('a * 'b -> 'c)*) -let uncurry f (a,b) = (f a b) diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_function_extra.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_function_extra.ml deleted file mode 100644 index 3c9e7854..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_function_extra.ml +++ /dev/null @@ -1,15 +0,0 @@ -(*Generated by Lem from function_extra.lem.*) - - -open Lem_maybe -open Lem_bool -open Lem_basic_classes -open Lem_num -open Lem_function - -(* ----------------------- *) -(* getting a unique value *) -(* ----------------------- *) - -(*val THE : forall 'a. ('a -> bool) -> maybe 'a*) - diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_list.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_list.ml deleted file mode 100644 index be308d6e..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_list.ml +++ /dev/null @@ -1,722 +0,0 @@ -(*Generated by Lem from list.lem.*) - - -open Lem_bool -open Lem_maybe -open Lem_basic_classes -open Lem_tuple -open Lem_num - -(* ========================================================================== *) -(* Basic list functions *) -(* ========================================================================== *) - -(* The type of lists as well as list literals like [], [1;2], ... are hardcoded. - Thus, we can directly dive into derived definitions. *) - - -(* ----------------------- *) -(* cons *) -(* ----------------------- *) - -(*val :: : forall 'a. 'a -> list 'a -> list 'a*) - - -(* ----------------------- *) -(* Emptyness check *) -(* ----------------------- *) - -(*val null : forall 'a. list 'a -> bool*) -let list_null l = ((match l with [] -> true | _ -> false )) - -(* ----------------------- *) -(* Length *) -(* ----------------------- *) - -(*val length : forall 'a. list 'a -> nat*) -(*let rec length l = - match l with - | [] -> 0 - | x :: xs -> (Instance_Num_NumAdd_nat.+) (length xs) 1 - end*) - -(* ----------------------- *) -(* Equality *) -(* ----------------------- *) - -(*val listEqual : forall 'a. Eq 'a => list 'a -> list 'a -> bool*) -(*val listEqualBy : forall 'a. ('a -> 'a -> bool) -> list 'a -> list 'a -> bool*) - -let rec listEqualBy eq l1 l2 = ((match (l1,l2) with - | ([], []) -> true - | ([], (_::_)) -> false - | ((_::_), []) -> false - | (x::xs, y :: ys) -> (eq x y && listEqualBy eq xs ys) -)) - -let instance_Basic_classes_Eq_list_dict dict_Basic_classes_Eq_a =({ - - isEqual_method = (listEqualBy - dict_Basic_classes_Eq_a.isEqual_method); - - isInequal_method = (fun l1 l2->not ((listEqualBy - dict_Basic_classes_Eq_a.isEqual_method l1 l2)))}) - - -(* ----------------------- *) -(* compare *) -(* ----------------------- *) - -(*val lexicographicCompare : forall 'a. Ord 'a => list 'a -> list 'a -> ordering*) -(*val lexicographicCompareBy : forall 'a. ('a -> 'a -> ordering) -> list 'a -> list 'a -> ordering*) - -let rec lexicographic_compare cmp l1 l2 = ((match (l1,l2) with - | ([], []) -> 0 - | ([], _::_) -> (-1) - | (_::_, []) -> 1 - | (x::xs, y::ys) -> begin - Lem.ordering_cases (cmp x y) (-1) (lexicographic_compare cmp xs ys) 1 - end -)) - -(*val lexicographicLess : forall 'a. Ord 'a => list 'a -> list 'a -> bool*) -(*val lexicographicLessBy : forall 'a. ('a -> 'a -> bool) -> ('a -> 'a -> bool) -> list 'a -> list 'a -> bool*) -let rec lexicographic_less less less_eq l1 l2 = ((match (l1,l2) with - | ([], []) -> false - | ([], _::_) -> true - | (_::_, []) -> false - | (x::xs, y::ys) -> ((less x y) || ((less_eq x y) && (lexicographic_less less less_eq xs ys))) -)) - -(*val lexicographicLessEq : forall 'a. Ord 'a => list 'a -> list 'a -> bool*) -(*val lexicographicLessEqBy : forall 'a. ('a -> 'a -> bool) -> ('a -> 'a -> bool) -> list 'a -> list 'a -> bool*) -let rec lexicographic_less_eq less less_eq l1 l2 = ((match (l1,l2) with - | ([], []) -> true - | ([], _::_) -> true - | (_::_, []) -> false - | (x::xs, y::ys) -> (less x y || (less_eq x y && lexicographic_less_eq less less_eq xs ys)) -)) - - -let instance_Basic_classes_Ord_list_dict dict_Basic_classes_Ord_a =({ - - compare_method = (lexicographic_compare - dict_Basic_classes_Ord_a.compare_method); - - isLess_method = (lexicographic_less - dict_Basic_classes_Ord_a.isLess_method dict_Basic_classes_Ord_a.isLessEqual_method); - - isLessEqual_method = (lexicographic_less_eq - dict_Basic_classes_Ord_a.isLess_method dict_Basic_classes_Ord_a.isLessEqual_method); - - isGreater_method = (fun x y->(lexicographic_less - dict_Basic_classes_Ord_a.isLess_method dict_Basic_classes_Ord_a.isLessEqual_method y x)); - - isGreaterEqual_method = (fun x y->(lexicographic_less_eq - dict_Basic_classes_Ord_a.isLess_method dict_Basic_classes_Ord_a.isLessEqual_method y x))}) - - -(* ----------------------- *) -(* Append *) -(* ----------------------- *) - -(*val ++ : forall 'a. list 'a -> list 'a -> list 'a*) (* originally append *) -(*let rec ++ xs ys = match xs with - | [] -> ys - | x :: xs' -> x :: (xs' ++ ys) - end*) - -(* ----------------------- *) -(* snoc *) -(* ----------------------- *) - -(*val snoc : forall 'a. 'a -> list 'a -> list 'a*) -let snoc e l = (List.append l [e]) - - -(* ----------------------- *) -(* Map *) -(* ----------------------- *) - -(*val map : forall 'a 'b. ('a -> 'b) -> list 'a -> list 'b*) -(*let rec map f l = match l with - | [] -> [] - | x :: xs -> (f x) :: map f xs -end*) - -(* ----------------------- *) -(* Reverse *) -(* ----------------------- *) - -(* First lets define the function [reverse_append], which is - closely related to reverse. [reverse_append l1 l2] appends the list [l2] to the reverse of [l1]. - This can be implemented more efficienctly than appending and is - used to implement reverse. *) - -(*val reverseAppend : forall 'a. list 'a -> list 'a -> list 'a*) (* originally named rev_append *) -(*let rec reverseAppend l1 l2 = match l1 with - | [] -> l2 - | x :: xs -> reverseAppend xs (x :: l2) - end*) - -(* Reversing a list *) -(*val reverse : forall 'a. list 'a -> list 'a*) (* originally named rev *) -(*let reverse l = reverseAppend l []*) - - -(* ----------------------- *) -(* Reverse Map *) -(* ----------------------- *) - -(*val reverseMap : forall 'a 'b. ('a -> 'b) -> list 'a -> list 'b*) - - - -(* ========================================================================== *) -(* Folding *) -(* ========================================================================== *) - -(* ----------------------- *) -(* fold left *) -(* ----------------------- *) - -(*val foldl : forall 'a 'b. ('a -> 'b -> 'a) -> 'a -> list 'b -> 'a*) (* originally foldl *) - -(*let rec foldl f b l = match l with - | [] -> b - | x :: xs -> foldl f (f b x) xs -end*) - - -(* ----------------------- *) -(* fold right *) -(* ----------------------- *) - -(*val foldr : forall 'a 'b. ('a -> 'b -> 'b) -> 'b -> list 'a -> 'b*) (* originally foldr with different argument order *) -(*let rec foldr f b l = match l with - | [] -> b - | x :: xs -> f x (foldr f b xs) -end*) - - -(* ----------------------- *) -(* concatenating lists *) -(* ----------------------- *) - -(*val concat : forall 'a. list (list 'a) -> list 'a*) (* before also called "flatten" *) -(*let concat = foldr (++) []*) - - -(* -------------------------- *) -(* concatenating with mapping *) -(* -------------------------- *) - -(*val concatMap : forall 'a 'b. ('a -> list 'b) -> list 'a -> list 'b*) - - -(* ------------------------- *) -(* universal qualification *) -(* ------------------------- *) - -(*val all : forall 'a. ('a -> bool) -> list 'a -> bool*) (* originally for_all *) -(*let all P l = foldl (fun r e -> P e && r) true l*) - - - -(* ------------------------- *) -(* existential qualification *) -(* ------------------------- *) - -(*val any : forall 'a. ('a -> bool) -> list 'a -> bool*) (* originally exist *) -(*let any P l = foldl (fun r e -> P e || r) false l*) - - -(* ------------------------- *) -(* dest_init *) -(* ------------------------- *) - -(* get the initial part and the last element of the list in a safe way *) - -(*val dest_init : forall 'a. list 'a -> maybe (list 'a * 'a)*) - -let rec dest_init_aux rev_init last_elem_seen to_process = -((match to_process with - | [] -> (List.rev rev_init, last_elem_seen) - | x::xs -> dest_init_aux (last_elem_seen::rev_init) x xs - )) - -let dest_init l = ((match l with - | [] -> None - | x::xs -> Some (dest_init_aux [] x xs) -)) - - -(* ========================================================================== *) -(* Indexing lists *) -(* ========================================================================== *) - -(* ------------------------- *) -(* index / nth with maybe *) -(* ------------------------- *) - -(*val index : forall 'a. list 'a -> nat -> maybe 'a*) - -let rec list_index l n = ((match l with - | [] -> None - | x :: xs -> if n = 0 then Some x else list_index xs (Nat_num.nat_monus n( 1)) -)) - -(* ------------------------- *) -(* findIndices *) -(* ------------------------- *) - -(* [findIndices P l] returns the indices of all elements of list [l] that satisfy predicate [P]. - Counting starts with 0, the result list is sorted ascendingly *) -(*val findIndices : forall 'a. ('a -> bool) -> list 'a -> list nat*) - -let rec find_indices_aux (i:int) p0 l = -((match l with - | [] -> [] - | x :: xs -> if p0 x then i :: find_indices_aux (i + 1) p0 xs else find_indices_aux (i + 1) p0 xs - )) -let find_indices p0 l = (find_indices_aux( 0) p0 l) - - - -(* ------------------------- *) -(* findIndex *) -(* ------------------------- *) - -(* findIndex returns the first index of a list that satisfies a given predicate. *) -(*val findIndex : forall 'a. ('a -> bool) -> list 'a -> maybe nat*) -let find_index p0 l = ((match find_indices p0 l with - | [] -> None - | x :: _ -> Some x -)) - -(* ------------------------- *) -(* elemIndices *) -(* ------------------------- *) - -(*val elemIndices : forall 'a. Eq 'a => 'a -> list 'a -> list nat*) - -(* ------------------------- *) -(* elemIndex *) -(* ------------------------- *) - -(*val elemIndex : forall 'a. Eq 'a => 'a -> list 'a -> maybe nat*) - - -(* ========================================================================== *) -(* Creating lists *) -(* ========================================================================== *) - -(* ------------------------- *) -(* genlist *) -(* ------------------------- *) - -(* [genlist f n] generates the list [f 0; f 1; ... (f (n-1))] *) -(*val genlist : forall 'a. (nat -> 'a) -> nat -> list 'a*) - - -let rec genlist f n = - ( - if(n = 0) then ([]) else - (let n'0 =(Nat_num.nat_monus n ( 1)) in snoc (f n'0) (genlist f n'0))) - - -(* ------------------------- *) -(* replicate *) -(* ------------------------- *) - -(*val replicate : forall 'a. nat -> 'a -> list 'a*) -let rec replicate n x = - ( - if(n = 0) then ([]) else - (let n'0 =(Nat_num.nat_monus n ( 1)) in x :: replicate n'0 x)) - - -(* ========================================================================== *) -(* Sublists *) -(* ========================================================================== *) - -(* ------------------------- *) -(* splitAt *) -(* ------------------------- *) - -(* [splitAt n xs] returns a tuple (xs1, xs2), with "append xs1 xs2 = xs" and - "length xs1 = n". If there are not enough elements - in [xs], the original list and the empty one are returned. *) -(*val splitAt : forall 'a. nat -> list 'a -> (list 'a * list 'a)*) -let rec split_at n l = - ((match l with - | [] -> ([], []) - | x::xs -> - if n <= 0 then ([], l) else - begin - let (l1, l2) = (split_at (Nat_num.nat_monus n( 1)) xs) in - ((x::l1), l2) - end - )) - - -(* ------------------------- *) -(* take *) -(* ------------------------- *) - -(* take n xs returns the prefix of xs of length n, or xs itself if n > length xs *) -(*val take : forall 'a. nat -> list 'a -> list 'a*) -let take n l = (fst (split_at n l)) - - - -(* ------------------------- *) -(* drop *) -(* ------------------------- *) - -(* [drop n xs] drops the first [n] elements of [xs]. It returns the empty list, if [n] > [length xs]. *) -(*val drop : forall 'a. nat -> list 'a -> list 'a*) -let drop n l = (snd (split_at n l)) - -(* ------------------------- *) -(* dropWhile *) -(* ------------------------- *) - -(* [dropWhile p xs] drops the first elements of [xs] that satisfy [p]. *) -(*val dropWhile : forall 'a. ('a -> bool) -> list 'a -> list 'a*) -let rec dropWhile p l = ((match l with - | [] -> [] - | x::xs -> if p x then dropWhile p xs else l -)) - - -(* ------------------------- *) -(* takeWhile *) -(* ------------------------- *) - -(* [takeWhile p xs] takes the first elements of [xs] that satisfy [p]. *) -(*val takeWhile : forall 'a. ('a -> bool) -> list 'a -> list 'a*) -let rec takeWhile p l = ((match l with - | [] -> [] - | x::xs -> if p x then x::takeWhile p xs else [] -)) - - -(* ------------------------- *) -(* isPrefixOf *) -(* ------------------------- *) - -(*val isPrefixOf : forall 'a. Eq 'a => list 'a -> list 'a -> bool*) -let rec isPrefixOf dict_Basic_classes_Eq_a l1 l2 = ((match (l1, l2) with - | ([], _) -> true - | (_::_, []) -> false - | (x::xs, y::ys) -> ( - dict_Basic_classes_Eq_a.isEqual_method x y) && isPrefixOf dict_Basic_classes_Eq_a xs ys -)) - -(* ------------------------- *) -(* update *) -(* ------------------------- *) -(*val update : forall 'a. list 'a -> nat -> 'a -> list 'a*) -let rec list_update l n e = - ((match l with - | [] -> [] - | x :: xs -> if n = 0 then e :: xs else x :: (list_update xs ( Nat_num.nat_monus n( 1)) e) -)) - - - -(* ========================================================================== *) -(* Searching lists *) -(* ========================================================================== *) - -(* ------------------------- *) -(* Membership test *) -(* ------------------------- *) - -(* The membership test, one of the basic list functions, is actually tricky for - Lem, because it is tricky, which equality to use. From Lem`s point of - perspective, we want to use the equality provided by the equality type - class. - This allows for example to check whether a set is in a list of sets. - - However, in order to use the equality type class, elem essentially becomes - existential quantification over lists. For types, which implement semantic - equality (=) with syntactic equality, this is overly complicated. In - our theorem prover backend, we would end up with overly complicated, harder - to read definitions and some of the automation would be harder to apply. - Moreover, nearly all the old Lem generated code would change and require - (hopefully minor) adaptions of proofs. - - For now, we ignore this problem and just demand, that all instances of - the equality type class do the right thing for the theorem prover backends. -*) - -(*val elem : forall 'a. Eq 'a => 'a -> list 'a -> bool*) -(*val elemBy : forall 'a. ('a -> 'a -> bool) -> 'a -> list 'a -> bool*) - -let elemBy eq e l = (List.exists (eq e) l) -(*let elem = elemBy dict_Basic_classes_Eq_a.isEqual_method*) - -(* ------------------------- *) -(* Find *) -(* ------------------------- *) -(*val find : forall 'a. ('a -> bool) -> list 'a -> maybe 'a*) (* previously not of maybe type *) -let rec list_find_opt p0 l = ((match l with - | [] -> None - | x :: xs -> if p0 x then Some x else list_find_opt p0 xs -)) - - -(* ----------------------------- *) -(* Lookup in an associative list *) -(* ----------------------------- *) -(*val lookup : forall 'a 'b. Eq 'a => 'a -> list ('a * 'b) -> maybe 'b*) -(*val lookupBy : forall 'a 'b. ('a -> 'a -> bool) -> 'a -> list ('a * 'b) -> maybe 'b*) - -(* DPM: eta-expansion for Coq backend type-inference. *) -let lookupBy eq k m = (Lem.option_map (fun x -> snd x) (list_find_opt (fun (k', _) -> eq k k') m)) - -(* ------------------------- *) -(* filter *) -(* ------------------------- *) -(*val filter : forall 'a. ('a -> bool) -> list 'a -> list 'a*) -(*let rec filter P l = match l with - | [] -> [] - | x :: xs -> if (P x) then x :: (filter P xs) else filter P xs - end*) - - -(* ------------------------- *) -(* partition *) -(* ------------------------- *) -(*val partition : forall 'a. ('a -> bool) -> list 'a -> list 'a * list 'a*) -(*let partition P l = (filter P l, filter (fun x -> not (P x)) l)*) - -(*val reversePartition : forall 'a. ('a -> bool) -> list 'a -> list 'a * list 'a*) -let reversePartition p0 l = (List.partition p0 (List.rev l)) - - -(* ------------------------- *) -(* delete first element *) -(* with certain property *) -(* ------------------------- *) - -(*val deleteFirst : forall 'a. ('a -> bool) -> list 'a -> maybe (list 'a)*) -let rec list_delete_first p0 l = ((match l with - | [] -> None - | x :: xs -> if (p0 x) then Some xs else Lem.option_map (fun xs' -> x :: xs') (list_delete_first p0 xs) - )) - - -(*val delete : forall 'a. Eq 'a => 'a -> list 'a -> list 'a*) -(*val deleteBy : forall 'a. ('a -> 'a -> bool) -> 'a -> list 'a -> list 'a*) - -let list_delete eq x l = (Lem.option_default l (list_delete_first (eq x) l)) - - -(* ========================================================================== *) -(* Zipping and unzipping lists *) -(* ========================================================================== *) - -(* ------------------------- *) -(* zip *) -(* ------------------------- *) - -(* zip takes two lists and returns a list of corresponding pairs. If one input list is short, excess elements of the longer list are discarded. *) -(*val zip : forall 'a 'b. list 'a -> list 'b -> list ('a * 'b)*) (* before combine *) -let rec list_combine l1 l2 = ((match (l1, l2) with - | (x :: xs, y :: ys) -> (x, y) :: list_combine xs ys - | _ -> [] -)) - -(* ------------------------- *) -(* unzip *) -(* ------------------------- *) - -(*val unzip: forall 'a 'b. list ('a * 'b) -> (list 'a * list 'b)*) -(*let rec unzip l = match l with - | [] -> ([], []) - | (x, y) :: xys -> let (xs, ys) = unzip xys in (x :: xs, y :: ys) -end*) - - -let instance_Basic_classes_SetType_list_dict dict_Basic_classes_SetType_a =({ - - setElemCompare_method = (lexicographic_compare - dict_Basic_classes_SetType_a.setElemCompare_method)}) - -(* ------------------------- *) -(* distinct elements *) -(* ------------------------- *) - -(*val allDistinct : forall 'a. Eq 'a => list 'a -> bool*) -let rec allDistinct dict_Basic_classes_Eq_a l = - ((match l with - | [] -> true - | (x::l') -> not (List.mem x l') && allDistinct - dict_Basic_classes_Eq_a l' - )) - -(* some more useful functions *) -(*val mapMaybe : forall 'a 'b. ('a -> maybe 'b) -> list 'a -> list 'b*) -let rec mapMaybe f xs = -((match xs with - | [] -> [] - | x::xs -> - (match f x with - | None -> mapMaybe f xs - | Some y -> y :: (mapMaybe f xs) - ) - )) - -(*val mapi : forall 'a 'b. (nat -> 'a -> 'b) -> list 'a -> list 'b*) -let rec mapiAux f (n : int) l = ((match l with - | [] -> [] - | x :: xs -> (f n x) :: mapiAux f (n + 1) xs -)) -let mapi f l = (mapiAux f( 0) l) - -(* ========================================================================== *) -(* Comments (not clean yet, please ignore the rest of the file) *) -(* ========================================================================== *) - -(* ----------------------- *) -(* skipped from Haskell Lib*) -(* ----------------------- - -intersperse :: a -> [a] -> [a] -intercalate :: [a] -> [[a]] -> [a] -transpose :: [[a]] -> [[a]] -subsequences :: [a] -> [[a]] -permutations :: [a] -> [[a]] -foldl` :: (a -> b -> a) -> a -> [b] -> aSource -foldl1` :: (a -> a -> a) -> [a] -> aSource - -and -or -sum -product -maximum -minimum -scanl -scanr -scanl1 -scanr1 -Accumulating maps - -mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])Source -mapAccumR :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])Source - -iterate :: (a -> a) -> a -> [a] -repeat :: a -> [a] -cycle :: [a] -> [a] -unfoldr - - -takeWhile :: (a -> Bool) -> [a] -> [a]Source -dropWhile :: (a -> Bool) -> [a] -> [a]Source -dropWhileEnd :: (a -> Bool) -> [a] -> [a]Source -span :: (a -> Bool) -> [a] -> ([a], [a])Source -break :: (a -> Bool) -> [a] -> ([a], [a])Source -break p is equivalent to span (not . p). -stripPrefix :: Eq a => [a] -> [a] -> Maybe [a]Source -group :: Eq a => [a] -> [[a]]Source -inits :: [a] -> [[a]]Source -tails :: [a] -> [[a]]Source - - -isPrefixOf :: Eq a => [a] -> [a] -> BoolSource -isSuffixOf :: Eq a => [a] -> [a] -> BoolSource -isInfixOf :: Eq a => [a] -> [a] -> BoolSource - - - -notElem :: Eq a => a -> [a] -> BoolSource - -zip3 :: [a] -> [b] -> [c] -> [(a, b, c)]Source -zip4 :: [a] -> [b] -> [c] -> [d] -> [(a, b, c, d)]Source -zip5 :: [a] -> [b] -> [c] -> [d] -> [e] -> [(a, b, c, d, e)]Source -zip6 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [(a, b, c, d, e, f)]Source -zip7 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g] -> [(a, b, c, d, e, f, g)]Source - -zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]Source -zipWith3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]Source -zipWith4 :: (a -> b -> c -> d -> e) -> [a] -> [b] -> [c] -> [d] -> [e]Source -zipWith5 :: (a -> b -> c -> d -> e -> f) -> [a] -> [b] -> [c] -> [d] -> [e] -> [f]Source -zipWith6 :: (a -> b -> c -> d -> e -> f -> g) -> [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g]Source -zipWith7 :: (a -> b -> c -> d -> e -> f -> g -> h) -> [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g] -> [h]Source - - -unzip3 :: [(a, b, c)] -> ([a], [b], [c])Source -unzip4 :: [(a, b, c, d)] -> ([a], [b], [c], [d])Source -unzip5 :: [(a, b, c, d, e)] -> ([a], [b], [c], [d], [e])Source -unzip6 :: [(a, b, c, d, e, f)] -> ([a], [b], [c], [d], [e], [f])Source -unzip7 :: [(a, b, c, d, e, f, g)] -> ([a], [b], [c], [d], [e], [f], [g])Source - - -lines :: String -> [String]Source -words :: String -> [String]Source -unlines :: [String] -> StringSource -unwords :: [String] -> StringSource -nub :: Eq a => [a] -> [a]Source -delete :: Eq a => a -> [a] -> [a]Source - -(\\) :: Eq a => [a] -> [a] -> [a]Source -union :: Eq a => [a] -> [a] -> [a]Source -intersect :: Eq a => [a] -> [a] -> [a]Source -sort :: Ord a => [a] -> [a]Source -insert :: Ord a => a -> [a] -> [a]Source - - -nubBy :: (a -> a -> Bool) -> [a] -> [a]Source -deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]Source -deleteFirstsBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]Source -unionBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]Source -intersectBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]Source -groupBy :: (a -> a -> Bool) -> [a] -> [[a]]Source -sortBy :: (a -> a -> Ordering) -> [a] -> [a]Source -insertBy :: (a -> a -> Ordering) -> a -> [a] -> [a]Source -maximumBy :: (a -> a -> Ordering) -> [a] -> aSource -minimumBy :: (a -> a -> Ordering) -> [a] -> aSource -genericLength :: Num i => [b] -> iSource -genericTake :: Integral i => i -> [a] -> [a]Source -genericDrop :: Integral i => i -> [a] -> [a]Source -genericSplitAt :: Integral i => i -> [b] -> ([b], [b])Source -genericIndex :: Integral a => [b] -> a -> bSource -genericReplicate :: Integral i => i -> a -> [a]Source - - -*) - - -(* ----------------------- *) -(* skipped from Lem Lib *) -(* ----------------------- - - -val for_all2 : forall 'a 'b. ('a -> 'b -> bool) -> list 'a -> list 'b -> bool -val exists2 : forall 'a 'b. ('a -> 'b -> bool) -> list 'a -> list 'b -> bool -val map2 : forall 'a 'b 'c. ('a -> 'b -> 'c) -> list 'a -> list 'b -> list 'c -val rev_map2 : forall 'a 'b 'c. ('a -> 'b -> 'c) -> list 'a -> list 'b -> list 'c -val fold_left2 : forall 'a 'b 'c. ('a -> 'b -> 'c -> 'a) -> 'a -> list 'b -> list 'c -> 'a -val fold_right2 : forall 'a 'b 'c. ('a -> 'b -> 'c -> 'c) -> list 'a -> list 'b -> 'c -> 'c - - -(* now maybe result and called lookup *) -val assoc : forall 'a 'b. 'a -> list ('a * 'b) -> 'b -let inline {ocaml} assoc = Ocaml.List.assoc - - -val mem_assoc : forall 'a 'b. 'a -> list ('a * 'b) -> bool -val remove_assoc : forall 'a 'b. 'a -> list ('a * 'b) -> list ('a * 'b) - - - -val stable_sort : forall 'a. ('a -> 'a -> num) -> list 'a -> list 'a -val fast_sort : forall 'a. ('a -> 'a -> num) -> list 'a -> list 'a - -val merge : forall 'a. ('a -> 'a -> num) -> list 'a -> list 'a -> list 'a -val intersect : forall 'a. list 'a -> list 'a -> list 'a - - -*) diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_list_extra.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_list_extra.ml deleted file mode 100644 index 8769b232..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_list_extra.ml +++ /dev/null @@ -1,85 +0,0 @@ -(*Generated by Lem from list_extra.lem.*) - - -open Lem_bool -open Lem_maybe -open Lem_basic_classes -open Lem_tuple -open Lem_num -open Lem_list -open Lem_assert_extra - -(* ------------------------- *) -(* head of non-empty list *) -(* ------------------------- *) -(*val head : forall 'a. list 'a -> 'a*) -(*let head l = match l with | x::xs -> x | [] -> failwith "List_extra.head of empty list" end*) - - -(* ------------------------- *) -(* tail of non-empty list *) -(* ------------------------- *) -(*val tail : forall 'a. list 'a -> list 'a*) -(*let tail l = match l with | x::xs -> xs | [] -> failwith "List_extra.tail of empty list" end*) - - -(* ------------------------- *) -(* last *) -(* ------------------------- *) -(*val last : forall 'a. list 'a -> 'a*) -let rec last l = ((match l with | [x] -> x | x1::x2::xs -> last (x2 :: xs) | [] -> failwith "List_extra.last of empty list" )) - - -(* ------------------------- *) -(* init *) -(* ------------------------- *) - -(* All elements of a non-empty list except the last one. *) -(*val init : forall 'a. list 'a -> list 'a*) -let rec init l = ((match l with | [x] -> [] | x1::x2::xs -> x1::(init (x2::xs)) | [] -> failwith "List_extra.init of empty list" )) - - -(* ------------------------- *) -(* foldl1 / foldr1 *) -(* ------------------------- *) - -(* folding functions for non-empty lists, - which don`t take the base case *) -(*val foldl1 : forall 'a. ('a -> 'a -> 'a) -> list 'a -> 'a*) -let foldl1 f x_xs = ((match x_xs with | (x :: xs) -> List.fold_left f x xs | [] -> failwith "List_extra.foldl1 of empty list" )) - -(*val foldr1 : forall 'a. ('a -> 'a -> 'a) -> list 'a -> 'a*) -let foldr1 f x_xs = ((match x_xs with | (x :: xs) -> List.fold_right f xs x | [] -> failwith "List_extra.foldr1 of empty list" )) - - -(* ------------------------- *) -(* nth element *) -(* ------------------------- *) - -(* get the nth element of a list *) -(*val nth : forall 'a. list 'a -> nat -> 'a*) -(*let nth l n = match index l n with Just e -> e | Nothing -> failwith "List_extra.nth" end*) - - -(* ------------------------- *) -(* Find_non_pure *) -(* ------------------------- *) -(*val findNonPure : forall 'a. ('a -> bool) -> list 'a -> 'a*) -let findNonPure p0 l = ((match (list_find_opt p0 l) with - | Some e -> e - | None -> failwith "List_extra.findNonPure" -)) - - -(* ------------------------- *) -(* zip same length *) -(* ------------------------- *) - -(*val zipSameLength : forall 'a 'b. list 'a -> list 'b -> list ('a * 'b)*) -(*let rec zipSameLength l1 l2 = match (l1, l2) with - | (x :: xs, y :: ys) -> (x, y) :: zipSameLength xs ys - | ([], []) -> [] - | _ -> failwith "List_extra.zipSameLength of different length lists" - -end*) - diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_map.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_map.ml deleted file mode 100644 index a1aab076..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_map.ml +++ /dev/null @@ -1,154 +0,0 @@ -(*Generated by Lem from map.lem.*) - - -open Lem_bool -open Lem_basic_classes -open Lem_function -open Lem_maybe -open Lem_list -open Lem_tuple -open Lem_set -open Lem_num - -(*type map 'k 'v*) - - - -(* -------------------------------------------------------------------------- *) -(* Map equality. *) -(* -------------------------------------------------------------------------- *) - -(*val mapEqual : forall 'k 'v. Eq 'k, Eq 'v => map 'k 'v -> map 'k 'v -> bool*) -(*val mapEqualBy : forall 'k 'v. ('k -> 'k -> bool) -> ('v -> 'v -> bool) -> map 'k 'v -> map 'k 'v -> bool*) - -let instance_Basic_classes_Eq_Map_map_dict dict_Basic_classes_Eq_k dict_Basic_classes_Eq_v =({ - - isEqual_method = (Pmap.equal dict_Basic_classes_Eq_v.isEqual_method); - - isInequal_method = (fun m1 m2->not ((Pmap.equal dict_Basic_classes_Eq_v.isEqual_method m1 m2)))}) - - -(* -------------------------------------------------------------------------- *) -(* Map type class *) -(* -------------------------------------------------------------------------- *) - -type 'a mapKeyType_class= { - mapKeyCompare_method : 'a -> 'a -> int -} - -let instance_Map_MapKeyType_var_dict dict_Basic_classes_SetType_a =({ - - mapKeyCompare_method = dict_Basic_classes_SetType_a.setElemCompare_method}) - - -(* -------------------------------------------------------------------------- *) -(* Empty maps *) -(* -------------------------------------------------------------------------- *) - -(*val empty : forall 'k 'v. MapKeyType 'k => map 'k 'v*) -(*val emptyBy : forall 'k 'v. ('k -> 'k -> ordering) -> map 'k 'v*) - - -(* -------------------------------------------------------------------------- *) -(* Insertion *) -(* -------------------------------------------------------------------------- *) - -(*val insert : forall 'k 'v. MapKeyType 'k => 'k -> 'v -> map 'k 'v -> map 'k 'v*) - - -(* -------------------------------------------------------------------------- *) -(* Singleton *) -(* -------------------------------------------------------------------------- *) - -(*val singleton : forall 'k 'v. MapKeyType 'k => 'k -> 'v -> map 'k 'v*) - - - -(* -------------------------------------------------------------------------- *) -(* Emptyness check *) -(* -------------------------------------------------------------------------- *) - -(*val null : forall 'k 'v. MapKeyType 'k, Eq 'k, Eq 'v => map 'k 'v -> bool*) - - -(* -------------------------------------------------------------------------- *) -(* lookup *) -(* -------------------------------------------------------------------------- *) - -(*val lookupBy : forall 'k 'v. ('k -> 'k -> ordering) -> 'k -> map 'k 'v -> maybe 'v*) - -(*val lookup : forall 'k 'v. MapKeyType 'k => 'k -> map 'k 'v -> maybe 'v*) - -(* -------------------------------------------------------------------------- *) -(* findWithDefault *) -(* -------------------------------------------------------------------------- *) - -(*val findWithDefault : forall 'k 'v. MapKeyType 'k => 'k -> 'v -> map 'k 'v -> 'v*) - -(* -------------------------------------------------------------------------- *) -(* from lists *) -(* -------------------------------------------------------------------------- *) - -(*val fromList : forall 'k 'v. MapKeyType 'k => list ('k * 'v) -> map 'k 'v*) -let fromList dict_Map_MapKeyType_k l = (List.fold_left (fun m (k,v) -> Pmap.add k v m) (Pmap.empty - dict_Map_MapKeyType_k.mapKeyCompare_method) l) - - -(* -------------------------------------------------------------------------- *) -(* to sets / domain / range *) -(* -------------------------------------------------------------------------- *) - -(*val toSet : forall 'k 'v. MapKeyType 'k, SetType 'k, SetType 'v => map 'k 'v -> set ('k * 'v)*) -(*val toSetBy : forall 'k 'v. (('k * 'v) -> ('k * 'v) -> ordering) -> map 'k 'v -> set ('k * 'v)*) - - -(*val domainBy : forall 'k 'v. ('k -> 'k -> ordering) -> map 'k 'v -> set 'k*) -(*val domain : forall 'k 'v. MapKeyType 'k, SetType 'k => map 'k 'v -> set 'k*) - - -(*val range : forall 'k 'v. MapKeyType 'k, SetType 'v => map 'k 'v -> set 'v*) -(*val rangeBy : forall 'k 'v. ('v -> 'v -> ordering) -> map 'k 'v -> set 'v*) - - -(* -------------------------------------------------------------------------- *) -(* member *) -(* -------------------------------------------------------------------------- *) - -(*val member : forall 'k 'v. MapKeyType 'k, SetType 'k, Eq 'k => 'k -> map 'k 'v -> bool*) - -(*val notMember : forall 'k 'v. MapKeyType 'k, SetType 'k, Eq 'k => 'k -> map 'k 'v -> bool*) - -(* -------------------------------------------------------------------------- *) -(* Quantification *) -(* -------------------------------------------------------------------------- *) - -(*val any : forall 'k 'v. MapKeyType 'k, Eq 'v => ('k -> 'v -> bool) -> map 'k 'v -> bool*) -(*val all : forall 'k 'v. MapKeyType 'k, Eq 'v => ('k -> 'v -> bool) -> map 'k 'v -> bool*) - -(*let all P m = (forall k v. (P k v && ((Instance_Basic_classes_Eq_Maybe_maybe.=) (lookup k m) (Just v))))*) - - -(* -------------------------------------------------------------------------- *) -(* Set-like operations. *) -(* -------------------------------------------------------------------------- *) -(*val deleteBy : forall 'k 'v. ('k -> 'k -> ordering) -> 'k -> map 'k 'v -> map 'k 'v*) -(*val delete : forall 'k 'v. MapKeyType 'k => 'k -> map 'k 'v -> map 'k 'v*) -(*val deleteSwap : forall 'k 'v. MapKeyType 'k => map 'k 'v -> 'k -> map 'k 'v*) - -(*val union : forall 'k 'v. MapKeyType 'k => map 'k 'v -> map 'k 'v -> map 'k 'v*) - -(*val unions : forall 'k 'v. MapKeyType 'k => list (map 'k 'v) -> map 'k 'v*) - - -(* -------------------------------------------------------------------------- *) -(* Maps (in the functor sense). *) -(* -------------------------------------------------------------------------- *) - -(*val map : forall 'k 'v 'w. MapKeyType 'k => ('v -> 'w) -> map 'k 'v -> map 'k 'w*) - -(*val mapi : forall 'k 'v 'w. MapKeyType 'k => ('k -> 'v -> 'w) -> map 'k 'v -> map 'k 'w*) - -(* -------------------------------------------------------------------------- *) -(* Cardinality *) -(* -------------------------------------------------------------------------- *) -(*val size : forall 'k 'v. MapKeyType 'k, SetType 'k => map 'k 'v -> nat*) diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_map_extra.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_map_extra.ml deleted file mode 100644 index c27f6b73..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_map_extra.ml +++ /dev/null @@ -1,41 +0,0 @@ -(*Generated by Lem from map_extra.lem.*) - - -open Lem_bool -open Lem_basic_classes -open Lem_function -open Lem_assert_extra -open Lem_maybe -open Lem_list -open Lem_num -open Lem_set -open Lem_map - -(* -------------------------------------------------------------------------- *) -(* find *) -(* -------------------------------------------------------------------------- *) - -(*val find : forall 'k 'v. MapKeyType 'k => 'k -> map 'k 'v -> 'v*) -(*let find k m = match (lookup k m) with Just x -> x | Nothing -> failwith "Map_extra.find" end*) - - - -(* -------------------------------------------------------------------------- *) -(* from sets / domain / range *) -(* -------------------------------------------------------------------------- *) - - -(*val fromSet : forall 'k 'v. MapKeyType 'k => ('k -> 'v) -> set 'k -> map 'k 'v*) -(*let fromSet f s = Set_helpers.fold (fun k m -> Map.insert k (f k) m) s Map.empty*) - - -(* -------------------------------------------------------------------------- *) -(* fold *) -(* -------------------------------------------------------------------------- *) - -(*val fold : forall 'k 'v 'r. MapKeyType 'k, SetType 'k, SetType 'v => ('k -> 'v -> 'r -> 'r) -> map 'k 'v -> 'r -> 'r*) -(*let fold f m v = Set_helpers.fold (fun (k, v) r -> f k v r) (Map.toSet m) v*) - - -(*val toList: forall 'k 'v. MapKeyType 'k => map 'k 'v -> list ('k * 'v)*) - diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_maybe.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_maybe.ml deleted file mode 100644 index 8f35b88f..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_maybe.ml +++ /dev/null @@ -1,98 +0,0 @@ -(*Generated by Lem from maybe.lem.*) - - -open Lem_bool -open Lem_basic_classes -open Lem_function - -(* ========================================================================== *) -(* Basic stuff *) -(* ========================================================================== *) - -(*type maybe 'a = - | Nothing - | Just of 'a*) - - -(*val maybeEqual : forall 'a. Eq 'a => maybe 'a -> maybe 'a -> bool*) -(*val maybeEqualBy : forall 'a. ('a -> 'a -> bool) -> maybe 'a -> maybe 'a -> bool*) - -(*let maybeEqualBy eq x y = match (x,y) with - | (Nothing, Nothing) -> true - | (Nothing, Just _) -> false - | (Just _, Nothing) -> false - | (Just x', Just y') -> (eq x' y') -end*) - -let instance_Basic_classes_Eq_Maybe_maybe_dict dict_Basic_classes_Eq_a =({ - - isEqual_method = (Lem.option_equal - dict_Basic_classes_Eq_a.isEqual_method); - - isInequal_method = (fun x y->not ((Lem.option_equal - dict_Basic_classes_Eq_a.isEqual_method x y)))}) - - -let maybeCompare cmp x y = ((match (x,y) with - | (None, None) -> 0 - | (None, Some _) -> (-1) - | (Some _, None) -> 1 - | (Some x', Some y') -> cmp x' y' -)) - -let instance_Basic_classes_SetType_Maybe_maybe_dict dict_Basic_classes_SetType_a =({ - - setElemCompare_method = (maybeCompare - dict_Basic_classes_SetType_a.setElemCompare_method)}) - - -(* ----------------------- *) -(* maybe *) -(* ----------------------- *) - -(*val maybe : forall 'a 'b. 'b -> ('a -> 'b) -> maybe 'a -> 'b*) -(*let maybe d f mb = match mb with - | Just a -> f a - | Nothing -> d -end*) - -(* ----------------------- *) -(* isJust / isNothing *) -(* ----------------------- *) - -(*val isJust : forall 'a. maybe 'a -> bool*) -(*let isJust mb = match mb with - | Just _ -> true - | Nothing -> false -end*) - -(*val isNothing : forall 'a. maybe 'a -> bool*) -(*let isNothing mb = match mb with - | Just _ -> false - | Nothing -> true -end*) - -(* ----------------------- *) -(* fromMaybe *) -(* ----------------------- *) - -(*val fromMaybe : forall 'a. 'a -> maybe 'a -> 'a*) -(*let fromMaybe d mb = match mb with - | Just v -> v - | Nothing -> d -end*) - -(* ----------------------- *) -(* map *) -(* ----------------------- *) - -(*val map : forall 'a 'b. ('a -> 'b) -> maybe 'a -> maybe 'b*) -(*let map f = maybe Nothing (fun v -> Just (f v))*) - - -(* ----------------------- *) -(* bind *) -(* ----------------------- *) - -(*val bind : forall 'a 'b. maybe 'a -> ('a -> maybe 'b) -> maybe 'b*) -(*let bind mb f = maybe Nothing f mb*) diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_maybe_extra.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_maybe_extra.ml deleted file mode 100644 index 7260b642..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_maybe_extra.ml +++ /dev/null @@ -1,14 +0,0 @@ -(*Generated by Lem from maybe_extra.lem.*) - - -open Lem_basic_classes -open Lem_maybe -open Lem_assert_extra - -(* ----------------------- *) -(* fromJust *) -(* ----------------------- *) - -(*val fromJust : forall 'a. maybe 'a -> 'a*) -let fromJust op = ((match op with | Some v -> v | None -> failwith "fromJust of Nothing" )) - diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_num.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_num.ml deleted file mode 100644 index f2e10846..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_num.ml +++ /dev/null @@ -1,901 +0,0 @@ -(*Generated by Lem from num.lem.*) - - -open Lem_bool -open Lem_basic_classes - -(*class inline ( Numeral 'a ) - val fromNumeral : numeral -> 'a -end*) - -(* ========================================================================== *) -(* Syntactic type-classes for common operations *) -(* ========================================================================== *) - -(* Typeclasses can be used as a mean to overload constants like "+", "-", etc *) - -type 'a numNegate_class= { - numNegate_method : 'a -> 'a -} - -type 'a numAbs_class= { - abs_method : 'a -> 'a -} - -type 'a numAdd_class= { - numAdd_method : 'a -> 'a -> 'a -} - -type 'a numMinus_class= { - numMinus_method : 'a -> 'a -> 'a -} - -type 'a numMult_class= { - numMult_method : 'a -> 'a -> 'a -} - -type 'a numPow_class= { - numPow_method : 'a -> int -> 'a -} - -type 'a numDivision_class= { - numDivision_method : 'a -> 'a -> 'a -} - -type 'a numIntegerDivision_class= { - div_method : 'a -> 'a -> 'a -} - - -type 'a numRemainder_class= { - mod_method : 'a -> 'a -> 'a -} - -type 'a numSucc_class= { - succ_method : 'a -> 'a -} - -type 'a numPred_class= { - pred_method : 'a -> 'a -} - - -(* ----------------------- *) -(* natural *) -(* ----------------------- *) - -(* unbounded size natural numbers *) -(*type natural*) - - -(* ----------------------- *) -(* int *) -(* ----------------------- *) - -(* bounded size integers with uncertain length *) - -(*type int*) - - -(* ----------------------- *) -(* integer *) -(* ----------------------- *) - -(* unbounded size integers *) - -(*type integer*) - -(* ----------------------- *) -(* bint *) -(* ----------------------- *) - -(* TODO the bounded ints are only partially implemented, use with care. *) - -(* 32 bit integers *) -(*type int32*) - -(* 64 bit integers *) -(*type int64*) - - -(* ----------------------- *) -(* rational *) -(* ----------------------- *) - -(* unbounded size and precision rational numbers *) - -(*type rational*) (* ???: better type for this in HOL? *) - - -(* ----------------------- *) -(* double *) -(* ----------------------- *) - -(* double precision floating point (64 bits) *) - -(*type float64*) (* ???: better type for this in HOL? *) - -(*type float32*) (* ???: better type for this in HOL? *) - - -(* ========================================================================== *) -(* Binding the standard operations for the number types *) -(* ========================================================================== *) - - -(* ----------------------- *) -(* nat *) -(* ----------------------- *) - -(*val natFromNumeral : numeral -> nat*) - -(*val natEq : nat -> nat -> bool*) -let instance_Basic_classes_Eq_nat_dict =({ - - isEqual_method = (=); - - isInequal_method = (fun n1 n2->not (n1 = n2))}) - -(*val natLess : nat -> nat -> bool*) -(*val natLessEqual : nat -> nat -> bool*) -(*val natGreater : nat -> nat -> bool*) -(*val natGreaterEqual : nat -> nat -> bool*) - -(*val natCompare : nat -> nat -> ordering*) - -let instance_Basic_classes_Ord_nat_dict =({ - - compare_method = compare; - - isLess_method = (<); - - isLessEqual_method = (<=); - - isGreater_method = (>); - - isGreaterEqual_method = (>=)}) - -let instance_Basic_classes_SetType_nat_dict =({ - - setElemCompare_method = compare}) - -(*val natAdd : nat -> nat -> nat*) - -let instance_Num_NumAdd_nat_dict =({ - - numAdd_method = (+)}) - -(*val natMinus : nat -> nat -> nat*) - -let instance_Num_NumMinus_nat_dict =({ - - numMinus_method = Nat_num.nat_monus}) - -(*val natSucc : nat -> nat*) -(*let natSucc n = (Instance_Num_NumAdd_nat.+) n 1*) -let instance_Num_NumSucc_nat_dict =({ - - succ_method = succ}) - -(*val natPred : nat -> nat*) -let instance_Num_NumPred_nat_dict =({ - - pred_method = Nat_num.nat_pred}) - -(*val natMult : nat -> nat -> nat*) - -let instance_Num_NumMult_nat_dict =({ - - numMult_method = ( * )}) - -(*val natDiv : nat -> nat -> nat*) - -let instance_Num_NumIntegerDivision_nat_dict =({ - - div_method = (/)}) - -let instance_Num_NumDivision_nat_dict =({ - - numDivision_method = (/)}) - -(*val natMod : nat -> nat -> nat*) - -let instance_Num_NumRemainder_nat_dict =({ - - mod_method = (mod)}) - - -(*val gen_pow_aux : forall 'a. ('a -> 'a -> 'a) -> 'a -> 'a -> nat -> 'a*) -let rec gen_pow_aux (mul : 'a -> 'a -> 'a) (a : 'a) (b : 'a) (e : int) = - ( (* cannot happen, call discipline guarentees e >= 1 *) if(e = 0) then - a else - ( - if(e = 1) then (mul a b) else - (let e'' = (e / 2) in - let a' = (if (e mod 2) = 0 then a else mul a b) in - gen_pow_aux mul a' (mul b b) e''))) - -let gen_pow (one : 'a) (mul : 'a -> 'a -> 'a) (b : 'a) (e : int) : 'a = - (if e < 0 then one else - if (e = 0) then one else gen_pow_aux mul one b e) - -(*val natPow : nat -> nat -> nat*) -let natPow = (gen_pow( 1) ( * )) - -let instance_Num_NumPow_nat_dict =({ - - numPow_method = natPow}) - -(*val natMin : nat -> nat -> nat*) - -(*val natMax : nat -> nat -> nat*) - -let instance_Basic_classes_OrdMaxMin_nat_dict =({ - - max_method = max; - - min_method = min}) - - -(* ----------------------- *) -(* natural *) -(* ----------------------- *) - -(*val naturalFromNumeral : numeral -> natural*) - -(*val naturalEq : natural -> natural -> bool*) -let instance_Basic_classes_Eq_Num_natural_dict =({ - - isEqual_method = Big_int.eq_big_int; - - isInequal_method = (fun n1 n2->not (Big_int.eq_big_int n1 n2))}) - -(*val naturalLess : natural -> natural -> bool*) -(*val naturalLessEqual : natural -> natural -> bool*) -(*val naturalGreater : natural -> natural -> bool*) -(*val naturalGreaterEqual : natural -> natural -> bool*) - -(*val naturalCompare : natural -> natural -> ordering*) - -let instance_Basic_classes_Ord_Num_natural_dict =({ - - compare_method = Big_int.compare_big_int; - - isLess_method = Big_int.lt_big_int; - - isLessEqual_method = Big_int.le_big_int; - - isGreater_method = Big_int.gt_big_int; - - isGreaterEqual_method = Big_int.ge_big_int}) - -let instance_Basic_classes_SetType_Num_natural_dict =({ - - setElemCompare_method = Big_int.compare_big_int}) - -(*val naturalAdd : natural -> natural -> natural*) - -let instance_Num_NumAdd_Num_natural_dict =({ - - numAdd_method = Big_int.add_big_int}) - -(*val naturalMinus : natural -> natural -> natural*) - -let instance_Num_NumMinus_Num_natural_dict =({ - - numMinus_method = Nat_num.natural_monus}) - -(*val naturalSucc : natural -> natural*) -(*let naturalSucc n = (Instance_Num_NumAdd_Num_natural.+) n 1*) -let instance_Num_NumSucc_Num_natural_dict =({ - - succ_method = Big_int.succ_big_int}) - -(*val naturalPred : natural -> natural*) -let instance_Num_NumPred_Num_natural_dict =({ - - pred_method = Nat_num.natural_pred}) - -(*val naturalMult : natural -> natural -> natural*) - -let instance_Num_NumMult_Num_natural_dict =({ - - numMult_method = Big_int.mult_big_int}) - - -(*val naturalPow : natural -> nat -> natural*) - -let instance_Num_NumPow_Num_natural_dict =({ - - numPow_method = Big_int.power_big_int_positive_int}) - -(*val naturalDiv : natural -> natural -> natural*) - -let instance_Num_NumIntegerDivision_Num_natural_dict =({ - - div_method = Big_int.div_big_int}) - -let instance_Num_NumDivision_Num_natural_dict =({ - - numDivision_method = Big_int.div_big_int}) - -(*val naturalMod : natural -> natural -> natural*) - -let instance_Num_NumRemainder_Num_natural_dict =({ - - mod_method = Big_int.mod_big_int}) - -(*val naturalMin : natural -> natural -> natural*) - -(*val naturalMax : natural -> natural -> natural*) - -let instance_Basic_classes_OrdMaxMin_Num_natural_dict =({ - - max_method = Big_int.max_big_int; - - min_method = Big_int.min_big_int}) - - -(* ----------------------- *) -(* int *) -(* ----------------------- *) - -(*val intFromNumeral : numeral -> int*) - -(*val intEq : int -> int -> bool*) -let instance_Basic_classes_Eq_Num_int_dict =({ - - isEqual_method = (=); - - isInequal_method = (fun n1 n2->not (n1 = n2))}) - -(*val intLess : int -> int -> bool*) -(*val intLessEqual : int -> int -> bool*) -(*val intGreater : int -> int -> bool*) -(*val intGreaterEqual : int -> int -> bool*) - -(*val intCompare : int -> int -> ordering*) - -let instance_Basic_classes_Ord_Num_int_dict =({ - - compare_method = compare; - - isLess_method = (<); - - isLessEqual_method = (<=); - - isGreater_method = (>); - - isGreaterEqual_method = (>=)}) - -let instance_Basic_classes_SetType_Num_int_dict =({ - - setElemCompare_method = compare}) - -(*val intNegate : int -> int*) - -let instance_Num_NumNegate_Num_int_dict =({ - - numNegate_method = (fun i->(~- i))}) - -(*val intAbs : int -> int*) (* TODO: check *) - -let instance_Num_NumAbs_Num_int_dict =({ - - abs_method = abs}) - -(*val intAdd : int -> int -> int*) - -let instance_Num_NumAdd_Num_int_dict =({ - - numAdd_method = (+)}) - -(*val intMinus : int -> int -> int*) - -let instance_Num_NumMinus_Num_int_dict =({ - - numMinus_method = (-)}) - -(*val intSucc : int -> int*) -let instance_Num_NumSucc_Num_int_dict =({ - - succ_method = succ}) - -(*val intPred : int -> int*) -let instance_Num_NumPred_Num_int_dict =({ - - pred_method = pred}) - -(*val intMult : int -> int -> int*) - -let instance_Num_NumMult_Num_int_dict =({ - - numMult_method = ( * )}) - - -(*val intPow : int -> nat -> int*) -let intPow = (gen_pow( 1) ( * )) - -let instance_Num_NumPow_Num_int_dict =({ - - numPow_method = intPow}) - -(*val intDiv : int -> int -> int*) - -let instance_Num_NumIntegerDivision_Num_int_dict =({ - - div_method = Nat_num.int_div}) - -let instance_Num_NumDivision_Num_int_dict =({ - - numDivision_method = Nat_num.int_div}) - -(*val intMod : int -> int -> int*) - -let instance_Num_NumRemainder_Num_int_dict =({ - - mod_method = Nat_num.int_mod}) - -(*val intMin : int -> int -> int*) - -(*val intMax : int -> int -> int*) - -let instance_Basic_classes_OrdMaxMin_Num_int_dict =({ - - max_method = max; - - min_method = min}) - -(* ----------------------- *) -(* int32 *) -(* ----------------------- *) -(*val int32FromNumeral : numeral -> int32*) - -(*val int32Eq : int32 -> int32 -> bool*) - -let instance_Basic_classes_Eq_Num_int32_dict =({ - - isEqual_method = (=); - - isInequal_method = (fun n1 n2->not (n1 = n2))}) - -(*val int32Less : int32 -> int32 -> bool*) -(*val int32LessEqual : int32 -> int32 -> bool*) -(*val int32Greater : int32 -> int32 -> bool*) -(*val int32GreaterEqual : int32 -> int32 -> bool*) - -(*val int32Compare : int32 -> int32 -> ordering*) - -let instance_Basic_classes_Ord_Num_int32_dict =({ - - compare_method = Int32.compare; - - isLess_method = (<); - - isLessEqual_method = (<=); - - isGreater_method = (>); - - isGreaterEqual_method = (>=)}) - -let instance_Basic_classes_SetType_Num_int32_dict =({ - - setElemCompare_method = Int32.compare}) - -(*val int32Negate : int32 -> int32*) - -let instance_Num_NumNegate_Num_int32_dict =({ - - numNegate_method = Int32.neg}) - -(*val int32Abs : int32 -> int32*) -(*let int32Abs i = (if (Instance_Basic_classes_Ord_Num_int32.<=) 0 i then i else Instance_Num_NumNegate_Num_int32.~ i)*) - -let instance_Num_NumAbs_Num_int32_dict =({ - - abs_method = Int32.abs}) - - -(*val int32Add : int32 -> int32 -> int32*) - -let instance_Num_NumAdd_Num_int32_dict =({ - - numAdd_method = Int32.add}) - -(*val int32Minus : int32 -> int32 -> int32*) - -let instance_Num_NumMinus_Num_int32_dict =({ - - numMinus_method = Int32.sub}) - -(*val int32Succ : int32 -> int32*) - -let instance_Num_NumSucc_Num_int32_dict =({ - - succ_method = Int32.succ}) - -(*val int32Pred : int32 -> int32*) -let instance_Num_NumPred_Num_int32_dict =({ - - pred_method = Int32.pred}) - -(*val int32Mult : int32 -> int32 -> int32*) - -let instance_Num_NumMult_Num_int32_dict =({ - - numMult_method = Int32.mul}) - - -(*val int32Pow : int32 -> nat -> int32*) -let int32Pow = (gen_pow(Int32.of_int 1) Int32.mul) - -let instance_Num_NumPow_Num_int32_dict =({ - - numPow_method = int32Pow}) - -(*val int32Div : int32 -> int32 -> int32*) - -let instance_Num_NumIntegerDivision_Num_int32_dict =({ - - div_method = Nat_num.int32_div}) - -let instance_Num_NumDivision_Num_int32_dict =({ - - numDivision_method = Nat_num.int32_div}) - -(*val int32Mod : int32 -> int32 -> int32*) - -let instance_Num_NumRemainder_Num_int32_dict =({ - - mod_method = Nat_num.int32_mod}) - -(*val int32Min : int32 -> int32 -> int32*) - -(*val int32Max : int32 -> int32 -> int32*) - -let instance_Basic_classes_OrdMaxMin_Num_int32_dict =({ - - max_method = max; - - min_method = min}) - - - -(* ----------------------- *) -(* int64 *) -(* ----------------------- *) -(*val int64FromNumeral : numeral -> int64*) - -(*val int64Eq : int64 -> int64 -> bool*) - -let instance_Basic_classes_Eq_Num_int64_dict =({ - - isEqual_method = (=); - - isInequal_method = (fun n1 n2->not (n1 = n2))}) - -(*val int64Less : int64 -> int64 -> bool*) -(*val int64LessEqual : int64 -> int64 -> bool*) -(*val int64Greater : int64 -> int64 -> bool*) -(*val int64GreaterEqual : int64 -> int64 -> bool*) - -(*val int64Compare : int64 -> int64 -> ordering*) - -let instance_Basic_classes_Ord_Num_int64_dict =({ - - compare_method = Int64.compare; - - isLess_method = (<); - - isLessEqual_method = (<=); - - isGreater_method = (>); - - isGreaterEqual_method = (>=)}) - -let instance_Basic_classes_SetType_Num_int64_dict =({ - - setElemCompare_method = Int64.compare}) - -(*val int64Negate : int64 -> int64*) - -let instance_Num_NumNegate_Num_int64_dict =({ - - numNegate_method = Int64.neg}) - -(*val int64Abs : int64 -> int64*) -(*let int64Abs i = (if (Instance_Basic_classes_Ord_Num_int64.<=) 0 i then i else Instance_Num_NumNegate_Num_int64.~ i)*) - -let instance_Num_NumAbs_Num_int64_dict =({ - - abs_method = Int64.abs}) - - -(*val int64Add : int64 -> int64 -> int64*) - -let instance_Num_NumAdd_Num_int64_dict =({ - - numAdd_method = Int64.add}) - -(*val int64Minus : int64 -> int64 -> int64*) - -let instance_Num_NumMinus_Num_int64_dict =({ - - numMinus_method = Int64.sub}) - -(*val int64Succ : int64 -> int64*) - -let instance_Num_NumSucc_Num_int64_dict =({ - - succ_method = Int64.succ}) - -(*val int64Pred : int64 -> int64*) -let instance_Num_NumPred_Num_int64_dict =({ - - pred_method = Int64.pred}) - -(*val int64Mult : int64 -> int64 -> int64*) - -let instance_Num_NumMult_Num_int64_dict =({ - - numMult_method = Int64.mul}) - - -(*val int64Pow : int64 -> nat -> int64*) -let int64Pow = (gen_pow(Int64.of_int 1) Int64.mul) - -let instance_Num_NumPow_Num_int64_dict =({ - - numPow_method = int64Pow}) - -(*val int64Div : int64 -> int64 -> int64*) - -let instance_Num_NumIntegerDivision_Num_int64_dict =({ - - div_method = Nat_num.int64_div}) - -let instance_Num_NumDivision_Num_int64_dict =({ - - numDivision_method = Nat_num.int64_div}) - -(*val int64Mod : int64 -> int64 -> int64*) - -let instance_Num_NumRemainder_Num_int64_dict =({ - - mod_method = Nat_num.int64_mod}) - -(*val int64Min : int64 -> int64 -> int64*) - -(*val int64Max : int64 -> int64 -> int64*) - -let instance_Basic_classes_OrdMaxMin_Num_int64_dict =({ - - max_method = max; - - min_method = min}) - - -(* ----------------------- *) -(* integer *) -(* ----------------------- *) - -(*val integerFromNumeral : numeral -> integer*) - -(*val integerEq : integer -> integer -> bool*) -let instance_Basic_classes_Eq_Num_integer_dict =({ - - isEqual_method = Big_int.eq_big_int; - - isInequal_method = (fun n1 n2->not (Big_int.eq_big_int n1 n2))}) - -(*val integerLess : integer -> integer -> bool*) -(*val integerLessEqual : integer -> integer -> bool*) -(*val integerGreater : integer -> integer -> bool*) -(*val integerGreaterEqual : integer -> integer -> bool*) - -(*val integerCompare : integer -> integer -> ordering*) - -let instance_Basic_classes_Ord_Num_integer_dict =({ - - compare_method = Big_int.compare_big_int; - - isLess_method = Big_int.lt_big_int; - - isLessEqual_method = Big_int.le_big_int; - - isGreater_method = Big_int.gt_big_int; - - isGreaterEqual_method = Big_int.ge_big_int}) - -let instance_Basic_classes_SetType_Num_integer_dict =({ - - setElemCompare_method = Big_int.compare_big_int}) - -(*val integerNegate : integer -> integer*) - -let instance_Num_NumNegate_Num_integer_dict =({ - - numNegate_method = Big_int.minus_big_int}) - -(*val integerAbs : integer -> integer*) (* TODO: check *) - -let instance_Num_NumAbs_Num_integer_dict =({ - - abs_method = Big_int.abs_big_int}) - -(*val integerAdd : integer -> integer -> integer*) - -let instance_Num_NumAdd_Num_integer_dict =({ - - numAdd_method = Big_int.add_big_int}) - -(*val integerMinus : integer -> integer -> integer*) - -let instance_Num_NumMinus_Num_integer_dict =({ - - numMinus_method = Big_int.sub_big_int}) - -(*val integerSucc : integer -> integer*) -let instance_Num_NumSucc_Num_integer_dict =({ - - succ_method = Big_int.succ_big_int}) - -(*val integerPred : integer -> integer*) -let instance_Num_NumPred_Num_integer_dict =({ - - pred_method = Big_int.pred_big_int}) - -(*val integerMult : integer -> integer -> integer*) - -let instance_Num_NumMult_Num_integer_dict =({ - - numMult_method = Big_int.mult_big_int}) - - -(*val integerPow : integer -> nat -> integer*) - -let instance_Num_NumPow_Num_integer_dict =({ - - numPow_method = Big_int.power_big_int_positive_int}) - -(*val integerDiv : integer -> integer -> integer*) - -let instance_Num_NumIntegerDivision_Num_integer_dict =({ - - div_method = Big_int.div_big_int}) - -let instance_Num_NumDivision_Num_integer_dict =({ - - numDivision_method = Big_int.div_big_int}) - -(*val integerMod : integer -> integer -> integer*) - -let instance_Num_NumRemainder_Num_integer_dict =({ - - mod_method = Big_int.mod_big_int}) - -(*val integerMin : integer -> integer -> integer*) - -(*val integerMax : integer -> integer -> integer*) - -let instance_Basic_classes_OrdMaxMin_Num_integer_dict =({ - - max_method = Big_int.max_big_int; - - min_method = Big_int.min_big_int}) - - - -(* ========================================================================== *) -(* Translation between number types *) -(* ========================================================================== *) - -(******************) -(* integerFrom... *) -(******************) - -(*val integerFromInt : int -> integer*) - - -(*val integerFromNat : nat -> integer*) - -(*val integerFromNatural : natural -> integer*) - - -(*val integerFromInt32 : int32 -> integer*) - - -(*val integerFromInt64 : int64 -> integer*) - - -(******************) -(* naturalFrom... *) -(******************) - -(*val naturalFromNat : nat -> natural*) - -(*val naturalFromInteger : integer -> natural*) - - -(******************) -(* intFrom ... *) -(******************) - -(*val intFromInteger : integer -> int*) - -(*val intFromNat : nat -> int*) - - -(******************) -(* natFrom ... *) -(******************) - -(*val natFromNatural : natural -> nat*) - -(*val natFromInt : int -> nat*) - - -(******************) -(* int32From ... *) -(******************) - -(*val int32FromNat : nat -> int32*) - -(*val int32FromNatural : natural -> int32*) - -(*val int32FromInteger : integer -> int32*) -(*let int32FromInteger i = ( - let abs_int32 = int32FromNatural (naturalFromInteger i) in - if ((Instance_Basic_classes_Ord_Num_integer.<) i 0) then (Instance_Num_NumNegate_Num_int32.~ abs_int32) else abs_int32 -)*) - -(*val int32FromInt : int -> int32*) -(*let int32FromInt i = int32FromInteger (integerFromInt i)*) - - -(*val int32FromInt64 : int64 -> int32*) -(*let int32FromInt64 i = int32FromInteger (integerFromInt64 i)*) - - - - -(******************) -(* int64From ... *) -(******************) - -(*val int64FromNat : nat -> int64*) - -(*val int64FromNatural : natural -> int64*) - -(*val int64FromInteger : integer -> int64*) -(*let int64FromInteger i = ( - let abs_int64 = int64FromNatural (naturalFromInteger i) in - if ((Instance_Basic_classes_Ord_Num_integer.<) i 0) then (Instance_Num_NumNegate_Num_int64.~ abs_int64) else abs_int64 -)*) - -(*val int64FromInt : int -> int64*) -(*let int64FromInt i = int64FromInteger (integerFromInt i)*) - - -(*val int64FromInt32 : int32 -> int64*) -(*let int64FromInt32 i = int64FromInteger (integerFromInt32 i)*) - - -(******************) -(* what's missing *) -(******************) - -(*val naturalFromInt : int -> natural*) -(*val naturalFromInt32 : int32 -> natural*) -(*val naturalFromInt64 : int64 -> natural*) - - -(*val intFromNatural : natural -> int*) -(*val intFromInt32 : int32 -> int*) -(*val intFromInt64 : int64 -> int*) - -(*val natFromInteger : integer -> nat*) -(*val natFromInt32 : int32 -> nat*) -(*val natFromInt64 : int64 -> nat*) - -(*val string_of_natural : natural -> string*) diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_pervasives.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_pervasives.ml deleted file mode 100644 index 729d9b79..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_pervasives.ml +++ /dev/null @@ -1,18 +0,0 @@ -(*Generated by Lem from pervasives.lem.*) - - -include Lem_basic_classes -include Lem_bool -include Lem_tuple -include Lem_maybe -include Lem_either -include Lem_function -include Lem_num -include Lem_map -include Lem_set -include Lem_list -include Lem_string -include Lem_word - -(*import Sorting Relation*) - diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_pervasives_extra.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_pervasives_extra.ml deleted file mode 100644 index 121429c6..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_pervasives_extra.ml +++ /dev/null @@ -1,12 +0,0 @@ -(*Generated by Lem from pervasives_extra.lem.*) - - -include Lem_pervasives -include Lem_function_extra -include Lem_maybe_extra -include Lem_map_extra -include Lem_set_extra -include Lem_set_helpers -include Lem_list_extra -include Lem_string_extra -include Lem_assert_extra diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_relation.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_relation.ml deleted file mode 100644 index f2e8114b..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_relation.ml +++ /dev/null @@ -1,424 +0,0 @@ -(*Generated by Lem from relation.lem.*) - - -open Lem_bool -open Lem_basic_classes -open Lem_tuple -open Lem_set -open Lem_num - -(* ========================================================================== *) -(* The type of relations *) -(* ========================================================================== *) - -type( 'a, 'b) rel_pred = 'a -> 'b -> bool -type( 'a, 'b) rel_set = ('a * 'b) Pset.set - -(* Binary relations are usually represented as either - sets of pairs (rel_set) or as curried functions (rel_pred). - - The choice depends on taste and the backend. Lem should not take a - decision, but supports both representations. There is an abstract type - pred, which can be converted to both representations. The representation - of pred itself then depends on the backend. However, for the time beeing, - let's implement relations as sets to get them working more quickly. *) - -type( 'a, 'b) rel = ('a, 'b) rel_set - -(*val relToSet : forall 'a 'b. SetType 'a, SetType 'b => rel 'a 'b -> rel_set 'a 'b*) -(*val relFromSet : forall 'a 'b. SetType 'a, SetType 'b => rel_set 'a 'b -> rel 'a 'b*) - -(*val relEq : forall 'a 'b. SetType 'a, SetType 'b => rel 'a 'b -> rel 'a 'b -> bool*) -let relEq dict_Basic_classes_SetType_a dict_Basic_classes_SetType_b r1 r2 = ( Pset.equal r1 r2) - -(*val relToPred : forall 'a 'b. SetType 'a, SetType 'b, Eq 'a, Eq 'b => rel 'a 'b -> rel_pred 'a 'b*) -(*val relFromPred : forall 'a 'b. SetType 'a, SetType 'b, Eq 'a, Eq 'b => set 'a -> set 'b -> rel_pred 'a 'b -> rel 'a 'b*) - -let relToPred dict_Basic_classes_SetType_a dict_Basic_classes_SetType_b dict_Basic_classes_Eq_a dict_Basic_classes_Eq_b r = (fun x y -> Pset.mem(x, y) r) -let relFromPred dict_Basic_classes_SetType_a dict_Basic_classes_SetType_b dict_Basic_classes_Eq_a dict_Basic_classes_Eq_b xs ys p = (Pset.filter (fun (x,y) -> p x y) ((Pset.cross (pairCompare - dict_Basic_classes_SetType_a.setElemCompare_method dict_Basic_classes_SetType_b.setElemCompare_method) xs ys))) - - -(* ========================================================================== *) -(* Basic Operations *) -(* ========================================================================== *) - -(* ----------------------- *) -(* membership test *) -(* ----------------------- *) - -(*val inRel : forall 'a 'b. SetType 'a, SetType 'b, Eq 'a, Eq 'b => 'a -> 'b -> rel 'a 'b -> bool*) - - -(* ----------------------- *) -(* empty relation *) -(* ----------------------- *) - -(*val relEmpty : forall 'a 'b. SetType 'a, SetType 'b => rel 'a 'b*) - -(* ----------------------- *) -(* Insertion *) -(* ----------------------- *) - -(*val relAdd : forall 'a 'b. SetType 'a, SetType 'b => 'a -> 'b -> rel 'a 'b -> rel 'a 'b*) - - -(* ----------------------- *) -(* Identity relation *) -(* ----------------------- *) - -(*val relIdOn : forall 'a. SetType 'a, Eq 'a => set 'a -> rel 'a 'a*) -let relIdOn dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a s = (relFromPred - dict_Basic_classes_SetType_a dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a dict_Basic_classes_Eq_a s s dict_Basic_classes_Eq_a.isEqual_method) - -(*val relId : forall 'a. SetType 'a, Eq 'a => rel 'a 'a*) - -(* ----------------------- *) -(* relation union *) -(* ----------------------- *) - -(*val relUnion : forall 'a 'b. SetType 'a, SetType 'b => rel 'a 'b -> rel 'a 'b -> rel 'a 'b*) - -(* ----------------------- *) -(* relation intersection *) -(* ----------------------- *) - -(*val relIntersection : forall 'a 'b. SetType 'a, SetType 'b, Eq 'a, Eq 'b => rel 'a 'b -> rel 'a 'b -> rel 'a 'b*) - -(* ----------------------- *) -(* Relation Composition *) -(* ----------------------- *) - -(*val relComp : forall 'a 'b 'c. SetType 'a, SetType 'b, SetType 'c, Eq 'a, Eq 'b => rel 'a 'b -> rel 'b 'c -> rel 'a 'c*) -let relComp dict_Basic_classes_SetType_a dict_Basic_classes_SetType_b dict_Basic_classes_SetType_c dict_Basic_classes_Eq_a dict_Basic_classes_Eq_b r1 r2 = (let x2 =(Pset.from_list (pairCompare - dict_Basic_classes_SetType_a.setElemCompare_method dict_Basic_classes_SetType_c.setElemCompare_method) []) in Pset.fold - (fun(e1,e2) x2 -> Pset.fold - (fun(e2',e3) x2 -> - if dict_Basic_classes_Eq_b.isEqual_method e2 e2' then - Pset.add (e1, e3) x2 else x2) (r2) x2) (r1) - x2) - -(* ----------------------- *) -(* restrict *) -(* ----------------------- *) - -(*val relRestrict : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> set 'a -> rel 'a 'a*) -let relRestrict dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s = (let x2 =(Pset.from_list (pairCompare - dict_Basic_classes_SetType_a.setElemCompare_method dict_Basic_classes_SetType_a.setElemCompare_method) []) in Pset.fold - (fun a x2 -> Pset.fold - (fun b x2 -> - if Pset.mem (a, b) r then Pset.add (a, b) x2 else x2) - s x2) s x2) - - -(* ----------------------- *) -(* Converse *) -(* ----------------------- *) - -(*val relConverse : forall 'a 'b. SetType 'a, SetType 'b => rel 'a 'b -> rel 'b 'a*) -let relConverse dict_Basic_classes_SetType_a dict_Basic_classes_SetType_b r = ((Pset.map (pairCompare - dict_Basic_classes_SetType_b.setElemCompare_method dict_Basic_classes_SetType_a.setElemCompare_method) Lem.pair_swap (r))) - - -(* ----------------------- *) -(* domain *) -(* ----------------------- *) - -(*val relDomain : forall 'a 'b. SetType 'a, SetType 'b => rel 'a 'b -> set 'a*) -let relDomain dict_Basic_classes_SetType_a dict_Basic_classes_SetType_b r = (Pset.map - dict_Basic_classes_SetType_a.setElemCompare_method (fun x -> fst x) (r)) - -(* ----------------------- *) -(* range *) -(* ----------------------- *) - -(*val relRange : forall 'a 'b. SetType 'a, SetType 'b => rel 'a 'b -> set 'b*) -let relRange dict_Basic_classes_SetType_a dict_Basic_classes_SetType_b r = (Pset.map - dict_Basic_classes_SetType_b.setElemCompare_method (fun x -> snd x) (r)) - - -(* ----------------------- *) -(* field / definedOn *) -(* *) -(* avoid the keyword field *) -(* ----------------------- *) - -(*val relDefinedOn : forall 'a. SetType 'a => rel 'a 'a -> set 'a*) - -(* ----------------------- *) -(* relOver *) -(* *) -(* avoid the keyword field *) -(* ----------------------- *) - -(*val relOver : forall 'a. SetType 'a => rel 'a 'a -> set 'a -> bool*) -let relOver dict_Basic_classes_SetType_a r s = ( Pset.subset(( Pset.(union)(relDomain - dict_Basic_classes_SetType_a dict_Basic_classes_SetType_a r) (relRange dict_Basic_classes_SetType_a dict_Basic_classes_SetType_a r))) s) - - -(* ----------------------- *) -(* apply a relation *) -(* ----------------------- *) - -(* Given a relation r and a set s, relApply r s applies s to r, i.e. - it returns the set of all value reachable via r from a value in s. - This operation can be seen as a generalisation of function application. *) - -(*val relApply : forall 'a 'b. SetType 'a, SetType 'b, Eq 'a => rel 'a 'b -> set 'a -> set 'b*) -let relApply dict_Basic_classes_SetType_a dict_Basic_classes_SetType_b dict_Basic_classes_Eq_a r s = (let x2 =(Pset.from_list - dict_Basic_classes_SetType_b.setElemCompare_method []) in Pset.fold (fun(x, y) x2 -> if Pset.mem x s then Pset.add y x2 else x2) - (r) x2) - - -(* ========================================================================== *) -(* Properties *) -(* ========================================================================== *) - -(* ----------------------- *) -(* subrel *) -(* ----------------------- *) - -(*val isSubrel : forall 'a 'b. SetType 'a, SetType 'b, Eq 'a, Eq 'b => rel 'a 'b -> rel 'a 'b -> bool*) - -(* ----------------------- *) -(* reflexivity *) -(* ----------------------- *) - -(*val isReflexiveOn : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> set 'a -> bool*) -let isReflexiveOn dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s = (Pset.for_all - (fun e -> Pset.mem (e, e) r) s) - -(*val isReflexive : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> bool*) - - -(* ----------------------- *) -(* irreflexivity *) -(* ----------------------- *) - -(*val isIrreflexiveOn : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> set 'a -> bool*) -let isIrreflexiveOn dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s = (Pset.for_all - (fun e -> not ( Pset.mem (e, e) r)) s) - -(*val isIrreflexive : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> bool*) -let isIrreflexive dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r = (Pset.for_all - (fun (e1, e2) -> not ( dict_Basic_classes_Eq_a.isEqual_method e1 e2)) (r)) - - -(* ----------------------- *) -(* symmetry *) -(* ----------------------- *) - -(*val isSymmetricOn : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> set 'a -> bool*) -let isSymmetricOn dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s = (Pset.for_all - (fun e1 -> Pset.for_all - (fun e2 -> ((not ( Pset.mem (e1, e2) r)) || - ( Pset.mem (e2, e1) r))) s) s) - -(*val isSymmetric : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> bool*) -let isSymmetric dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r = (Pset.for_all - (fun (e1, e2) -> Pset.mem (e2, e1) r) r) - - -(* ----------------------- *) -(* antisymmetry *) -(* ----------------------- *) - -(*val isAntisymmetricOn : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> set 'a -> bool*) -let isAntisymmetricOn dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s = (Pset.for_all - (fun e1 -> Pset.for_all - (fun e2 -> ((not ( Pset.mem (e1, e2) r)) || - ((not ( Pset.mem (e2, e1) r)) || - ( dict_Basic_classes_Eq_a.isEqual_method - e1 e2)))) s) s) - -(*val isAntisymmetric : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> bool*) -let isAntisymmetric dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r = (Pset.for_all - (fun (e1, e2) -> ((not ( Pset.mem (e2, e1) r)) || - ( dict_Basic_classes_Eq_a.isEqual_method e1 e2))) r) - - -(* ----------------------- *) -(* transitivity *) -(* ----------------------- *) - -(*val isTransitiveOn : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> set 'a -> bool*) -let isTransitiveOn dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s = (Pset.for_all - (fun e1 -> Pset.for_all - (fun e2 -> Pset.for_all - (fun e3 -> ((not ( Pset.mem (e1, e2) r)) || - ((not ( Pset.mem (e2, e3) r)) || - ( Pset.mem (e1, e3) r)))) - s) s) s) - -(*val isTransitive : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> bool*) -let isTransitive dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r = (Pset.for_all - (fun (e1, e2) -> Pset.for_all (fun e3 -> Pset.mem (e1, e3) r) - (relApply dict_Basic_classes_SetType_a - dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a - r - (Pset.from_list - dict_Basic_classes_SetType_a.setElemCompare_method - [e2]))) r) - -(* ----------------------- *) -(* total *) -(* ----------------------- *) - -(*val isTotalOn : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> set 'a -> bool*) -let isTotalOn dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s = (Pset.for_all - (fun e1 -> Pset.for_all - (fun e2 -> ( Pset.mem (e1, e2) r) || ( Pset.mem (e2, e1) r)) - s) s) - - -(*val isTotal : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> bool*) - - -(*val isTrichotomousOn : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> set 'a -> bool*) -let isTrichotomousOn dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s = (Pset.for_all - (fun e1 -> Pset.for_all - (fun e2 -> ( Pset.mem (e1, e2) r) || - (( dict_Basic_classes_Eq_a.isEqual_method e1 e2) - || ( Pset.mem (e2, e1) r))) s) s) - -(*val isTrichotomous : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> bool*) - - -(* ----------------------- *) -(* is_single_valued *) -(* ----------------------- *) - -(*val isSingleValued : forall 'a 'b. SetType 'a, SetType 'b, Eq 'a, Eq 'b => rel 'a 'b -> bool*) -let isSingleValued dict_Basic_classes_SetType_a dict_Basic_classes_SetType_b dict_Basic_classes_Eq_a dict_Basic_classes_Eq_b r = (Pset.for_all - (fun (e1, e2a) -> Pset.for_all - (fun e2b -> dict_Basic_classes_Eq_b.isEqual_method - e2a e2b) - (relApply dict_Basic_classes_SetType_a - dict_Basic_classes_SetType_b dict_Basic_classes_Eq_a - r - (Pset.from_list - dict_Basic_classes_SetType_a.setElemCompare_method - [e1]))) r) - - -(* ----------------------- *) -(* equivalence relation *) -(* ----------------------- *) - -(*val isEquivalenceOn : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> set 'a -> bool*) -let isEquivalenceOn dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s = (isReflexiveOn - dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s && (isSymmetricOn - dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s && isTransitiveOn - dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s)) - - -(*val isEquivalence : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> bool*) - - -(* ----------------------- *) -(* well founded *) -(* ----------------------- *) - -(*val isWellFounded : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> bool*) - - -(* ========================================================================== *) -(* Orders *) -(* ========================================================================== *) - - -(* ----------------------- *) -(* pre- or quasiorders *) -(* ----------------------- *) - -(*val isPreorderOn : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> set 'a -> bool*) -let isPreorderOn dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s = (isReflexiveOn - dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s && isTransitiveOn - dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s) - -(*val isPreorder : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> bool*) - - -(* ----------------------- *) -(* partial orders *) -(* ----------------------- *) - -(*val isPartialOrderOn : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> set 'a -> bool*) -let isPartialOrderOn dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s = (isReflexiveOn - dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s && (isTransitiveOn - dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s && isAntisymmetricOn - dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s)) - - -(*val isStrictPartialOrderOn : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> set 'a -> bool*) -let isStrictPartialOrderOn dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s = (isIrreflexiveOn - dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s && isTransitiveOn - dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s) - - -(*val isStrictPartialOrder : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> bool*) -let isStrictPartialOrder dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r = (isIrreflexive - dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r && isTransitive dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r) - -(*val isPartialOrder : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> bool*) - -(* ----------------------- *) -(* total / linear orders *) -(* ----------------------- *) - -(*val isTotalOrderOn : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> set 'a -> bool*) -let isTotalOrderOn dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s = (isPartialOrderOn - dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s && isTotalOn dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s) - -(*val isStrictTotalOrderOn : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> set 'a -> bool*) -let isStrictTotalOrderOn dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s = (isStrictPartialOrderOn - dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s && isTrichotomousOn - dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s) - -(*val isTotalOrder : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> bool*) - -(*val isStrictTotalOrder : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> bool*) - - - -(* ========================================================================== *) -(* closures *) -(* ========================================================================== *) - -(* ----------------------- *) -(* transitive closure *) -(* ----------------------- *) - -(*val transitiveClosure : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> rel 'a 'a*) -(*val transitiveClosureByEq : forall 'a. ('a -> 'a -> bool) -> rel 'a 'a -> rel 'a 'a*) -(*val transitiveClosureByCmp : forall 'a. ('a * 'a -> 'a * 'a -> ordering) -> rel 'a 'a -> rel 'a 'a*) - - -(* ----------------------- *) -(* transitive closure step *) -(* ----------------------- *) - -(*val transitiveClosureAdd : forall 'a. SetType 'a, Eq 'a => 'a -> 'a -> rel 'a 'a -> rel 'a 'a*) - -let transitiveClosureAdd dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a x y r = - (( Pset.(union)(((Pset.add (x,y) (r)))) ((( Pset.(union)((let x2 =(Pset.from_list (pairCompare - dict_Basic_classes_SetType_a.setElemCompare_method dict_Basic_classes_SetType_a.setElemCompare_method) []) in Pset.fold (fun z x2 -> if Pset.mem (y, z) r then Pset.add (x, z) x2 else x2) - (relRange dict_Basic_classes_SetType_a dict_Basic_classes_SetType_a r) - x2)) ((let x2 =(Pset.from_list (pairCompare - dict_Basic_classes_SetType_a.setElemCompare_method dict_Basic_classes_SetType_a.setElemCompare_method) []) in Pset.fold (fun z x2 -> if Pset.mem (z, x) r then Pset.add (z, y) x2 else x2) - (relDomain dict_Basic_classes_SetType_a dict_Basic_classes_SetType_a r) - x2))))))) - - -(* ========================================================================== *) -(* reflexiv closures *) -(* ========================================================================== *) - -(*val reflexivTransitiveClosureOn : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> set 'a -> rel 'a 'a*) -let reflexivTransitiveClosureOn dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a r s = (Pset.tc (pairCompare - dict_Basic_classes_SetType_a.setElemCompare_method dict_Basic_classes_SetType_a.setElemCompare_method) (( Pset.(union)(r) ((relIdOn - dict_Basic_classes_SetType_a dict_Basic_classes_Eq_a s))))) - - -(*val reflexivTransitiveClosure : forall 'a. SetType 'a, Eq 'a => rel 'a 'a -> rel 'a 'a*) - diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_set.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_set.ml deleted file mode 100644 index 1cd7c3fa..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_set.ml +++ /dev/null @@ -1,290 +0,0 @@ -(*Generated by Lem from set.lem.*) -(******************************************************************************) -(* A library for sets *) -(* *) -(* It mainly follows the Haskell Set-library *) -(******************************************************************************) - -(* Sets in Lem are a bit tricky. On the one hand, we want efficiently executable sets. - OCaml and Haskell both represent sets by some kind of balancing trees. This means - that sets are finite and an order on the element type is required. - Such sets are constructed by simple, executable operations like inserting or - deleting elements, union, intersection, filtering etc. - - On the other hand, we want to use sets for specifications. This leads often - infinite sets, which are specificied in complicated, perhaps even undecidable - ways. - - The set library in this file, chooses the first approach. It describes - *finite* sets with an underlying order. Infinite sets should in the medium - run be represented by a separate type. Since this would require some significant - changes to Lem, for the moment also infinite sets are represented using this - class. However, a run-time exception might occour when using these sets. - This problem needs adressing in the future. *) - - -(* ========================================================================== *) -(* Header *) -(* ========================================================================== *) - -open Lem_bool -open Lem_basic_classes -open Lem_maybe -open Lem_function -open Lem_num -open Lem_list -open Lem_set_helpers - -(* ----------------------- *) -(* Equality check *) -(* ----------------------- *) - -(*val setEqualBy : forall 'a. ('a -> 'a -> ordering) -> set 'a -> set 'a -> bool*) - -(*val setEqual : forall 'a. SetType 'a => set 'a -> set 'a -> bool*) - -let instance_Basic_classes_Eq_set_dict dict_Basic_classes_SetType_a =({ - - isEqual_method = Pset.equal; - - isInequal_method = (fun s1 s2->not (Pset.equal s1 s2))}) - - - -(* ----------------------- *) -(* compare *) -(* ----------------------- *) - -(*val setCompareBy: forall 'a. ('a -> 'a -> ordering) -> set 'a -> set 'a -> ordering*) - -(*val setCompare : forall 'a. SetType 'a => set 'a -> set 'a -> ordering*) - -let instance_Basic_classes_SetType_set_dict dict_Basic_classes_SetType_a =({ - - setElemCompare_method = Pset.compare}) - - -(* ----------------------- *) -(* Empty set *) -(* ----------------------- *) - -(*val empty : forall 'a. SetType 'a => set 'a*) -(*val emptyBy : forall 'a. ('a -> 'a -> ordering) -> set 'a*) - -(* ----------------------- *) -(* any / all *) -(* ----------------------- *) - -(*val any : forall 'a. SetType 'a => ('a -> bool) -> set 'a -> bool*) - -(*val all : forall 'a. SetType 'a => ('a -> bool) -> set 'a -> bool*) - - -(* ----------------------- *) -(* (IN) *) -(* ----------------------- *) - -(*val IN [member] : forall 'a. SetType 'a => 'a -> set 'a -> bool*) -(*val memberBy : forall 'a. ('a -> 'a -> ordering) -> 'a -> set 'a -> bool*) - -(* ----------------------- *) -(* not (IN) *) -(* ----------------------- *) - -(*val NIN [notMember] : forall 'a. SetType 'a => 'a -> set 'a -> bool*) - - - -(* ----------------------- *) -(* Emptyness check *) -(* ----------------------- *) - -(*val null : forall 'a. SetType 'a => set 'a -> bool*) - - -(* ------------------------ *) -(* singleton *) -(* ------------------------ *) - -(*val singleton : forall 'a. SetType 'a => 'a -> set 'a*) - - -(* ----------------------- *) -(* size *) -(* ----------------------- *) - -(*val size : forall 'a. SetType 'a => set 'a -> nat*) - - -(* ----------------------------*) -(* setting up pattern matching *) -(* --------------------------- *) - -(*val set_case : forall 'a 'b. SetType 'a => set 'a -> 'b -> ('a -> 'b) -> 'b -> 'b*) - - -(* ------------------------ *) -(* union *) -(* ------------------------ *) - -(*val unionBy : forall 'a. ('a -> 'a -> ordering) -> set 'a -> set 'a -> set 'a*) -(*val union : forall 'a. SetType 'a => set 'a -> set 'a -> set 'a*) - -(* ----------------------- *) -(* insert *) -(* ----------------------- *) - -(*val insert : forall 'a. SetType 'a => 'a -> set 'a -> set 'a*) - -(* ----------------------- *) -(* filter *) -(* ----------------------- *) - -(*val filter : forall 'a. SetType 'a => ('a -> bool) -> set 'a -> set 'a*) -(*let filter P s = {e | forall (e IN s) | P e}*) - - -(* ----------------------- *) -(* partition *) -(* ----------------------- *) - -(*val partition : forall 'a. SetType 'a => ('a -> bool) -> set 'a -> set 'a * set 'a*) -let partition dict_Basic_classes_SetType_a p0 s = (Pset.filter p0 s, Pset.filter (fun e -> not (p0 e)) s) - - -(* ----------------------- *) -(* split *) -(* ----------------------- *) - -(*val split : forall 'a. SetType 'a, Ord 'a => 'a -> set 'a -> set 'a * set 'a*) -let split dict_Basic_classes_SetType_a dict_Basic_classes_Ord_a p s = (Pset.filter ( - dict_Basic_classes_Ord_a.isLess_method p) s, Pset.filter (dict_Basic_classes_Ord_a.isGreater_method p) s) - -(*val splitMember : forall 'a. SetType 'a, Ord 'a => 'a -> set 'a -> set 'a * bool * set 'a*) -let splitMember dict_Basic_classes_SetType_a dict_Basic_classes_Ord_a p s = (Pset.filter ( - dict_Basic_classes_Ord_a.isLess_method p) s, Pset.mem p s, Pset.filter ( - dict_Basic_classes_Ord_a.isGreater_method p) s) - - -(* ------------------------ *) -(* subset and proper subset *) -(* ------------------------ *) - -(*val isSubsetOfBy : forall 'a. ('a -> 'a -> ordering) -> set 'a -> set 'a -> bool*) -(*val isProperSubsetOfBy : forall 'a. ('a -> 'a -> ordering) -> set 'a -> set 'a -> bool*) - -(*val isSubsetOf : forall 'a. SetType 'a => set 'a -> set 'a -> bool*) -(*val isProperSubsetOf : forall 'a. SetType 'a => set 'a -> set 'a -> bool*) - - -(* ------------------------ *) -(* delete *) -(* ------------------------ *) - -(*val delete : forall 'a. SetType 'a, Eq 'a => 'a -> set 'a -> set 'a*) -(*val deleteBy : forall 'a. SetType 'a => ('a -> 'a -> bool) -> 'a -> set 'a -> set 'a*) - - -(* ------------------------ *) -(* bigunion *) -(* ------------------------ *) - -(*val bigunion : forall 'a. SetType 'a => set (set 'a) -> set 'a*) -(*val bigunionBy : forall 'a. ('a -> 'a -> ordering) -> set (set 'a) -> set 'a*) - -(*let bigunion bs = {x | forall (s IN bs) (x IN s) | true}*) - - -(* ------------------------ *) -(* difference *) -(* ------------------------ *) - -(*val differenceBy : forall 'a. ('a -> 'a -> ordering) -> set 'a -> set 'a -> set 'a*) -(*val difference : forall 'a. SetType 'a => set 'a -> set 'a -> set 'a*) - -(* ------------------------ *) -(* intersection *) -(* ------------------------ *) - -(*val intersection : forall 'a. SetType 'a => set 'a -> set 'a -> set 'a*) -(*val intersectionBy : forall 'a. ('a -> 'a -> ordering) -> set 'a -> set 'a -> set 'a*) - - -(* ------------------------ *) -(* map *) -(* ------------------------ *) - -(*val map : forall 'a 'b. SetType 'a, SetType 'b => ('a -> 'b) -> set 'a -> set 'b*) (* before image *) -(*let map f s = { f e | forall (e IN s) | true }*) - -(*val mapBy : forall 'a 'b. ('b -> 'b -> ordering) -> ('a -> 'b) -> set 'a -> set 'b*) - - -(* ------------------------ *) -(* bigunionMap *) -(* ------------------------ *) - -(* In order to avoid providing an comparison function for sets of sets, - it might be better to combine bigunion and map sometimes into a single operation. *) - -(*val bigunionMap : forall 'a 'b. SetType 'a, SetType 'b => ('a -> set 'b) -> set 'a -> set 'b*) -(*val bigunionMapBy : forall 'a 'b. ('b -> 'b -> ordering) -> ('a -> set 'b) -> set 'a -> set 'b*) - -(* ------------------------ *) -(* min and max *) -(* ------------------------ *) - -(*val findMin : forall 'a. SetType 'a, Eq 'a => set 'a -> maybe 'a*) -(*val findMax : forall 'a. SetType 'a, Eq 'a => set 'a -> maybe 'a*) - - - -(* ------------------------ *) -(* fromList *) -(* ------------------------ *) - -(*val fromList : forall 'a. SetType 'a => list 'a -> set 'a*) (* before from_list *) -(*val fromListBy : forall 'a. ('a -> 'a -> ordering) -> list 'a -> set 'a*) - - -(* ------------------------ *) -(* Sigma *) -(* ------------------------ *) - -(*val sigma : forall 'a 'b. SetType 'a, SetType 'b => set 'a -> ('a -> set 'b) -> set ('a * 'b)*) -(*val sigmaBy : forall 'a 'b. (('a * 'b) -> ('a * 'b) -> ordering) -> set 'a -> ('a -> set 'b) -> set ('a * 'b)*) - -(*let sigma sa sb = { (a, b) | forall (a IN sa) (b IN sb a) | true }*) - - -(* ------------------------ *) -(* cross product *) -(* ------------------------ *) - -(*val cross : forall 'a 'b. SetType 'a, SetType 'b => set 'a -> set 'b -> set ('a * 'b)*) -(*val crossBy : forall 'a 'b. (('a * 'b) -> ('a * 'b) -> ordering) -> set 'a -> set 'b -> set ('a * 'b)*) - -(*let cross s1 s2 = { (e1, e2) | forall (e1 IN s1) (e2 IN s2) | true }*) - - -(* ------------------------ *) -(* finite *) -(* ------------------------ *) - -(*val finite : forall 'a. SetType 'a => set 'a -> bool*) - - -(* ----------------------------*) -(* fixed point *) -(* --------------------------- *) - -(*val leastFixedPoint : forall 'a. SetType 'a - => nat -> (set 'a -> set 'a) -> set 'a -> set 'a*) -let rec leastFixedPoint dict_Basic_classes_SetType_a bound f x = - ( - if(bound = 0) then x else - (let bound'0 =(Nat_num.nat_monus bound ( 1)) in - let fx = (f x) in - if Pset.subset fx x then x else - leastFixedPoint dict_Basic_classes_SetType_a bound'0 f - ( Pset.(union) fx x))) diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_set_extra.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_set_extra.ml deleted file mode 100644 index 505f2d3e..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_set_extra.ml +++ /dev/null @@ -1,66 +0,0 @@ -(*Generated by Lem from set_extra.lem.*) -(******************************************************************************) -(* A library for sets *) -(* *) -(* It mainly follows the Haskell Set-library *) -(******************************************************************************) - -(* ========================================================================== *) -(* Header *) -(* ========================================================================== *) - -open Lem_bool -open Lem_basic_classes -open Lem_maybe -open Lem_function -open Lem_num -open Lem_list -open Lem_sorting -open Lem_set - - -(* ----------------------------*) -(* set choose (be careful !) *) -(* --------------------------- *) - -(*val choose : forall 'a. SetType 'a => set 'a -> 'a*) - - -(* ----------------------------*) -(* universal set *) -(* --------------------------- *) - -(*val universal : forall 'a. SetType 'a => set 'a*) - - -(* ----------------------------*) -(* toList *) -(* --------------------------- *) - -(*val toList : forall 'a. SetType 'a => set 'a -> list 'a*) - - -(* ----------------------------*) -(* toOrderedList *) -(* --------------------------- *) - -(* "toOrderedList" returns a sorted list. Therefore the result is (given a suitable order) deterministic. - Therefore, it is much preferred to "toList". However, it still is only defined for finite sets. So, please - use carefully and consider using set-operations instead of translating sets to lists, performing list manipulations - and then transforming back to sets. *) - -(*val toOrderedListBy : forall 'a. ('a -> 'a -> bool) -> set 'a -> list 'a*) - -(*val toOrderedList : forall 'a. SetType 'a, Ord 'a => set 'a -> list 'a*) - -(* ----------------------------*) -(* unbounded fixed point *) -(* --------------------------- *) - -(* Is NOT supported by the coq backend! *) -(*val leastFixedPointUnbounded : forall 'a. SetType 'a => (set 'a -> set 'a) -> set 'a -> set 'a*) -let rec leastFixedPointUnbounded dict_Basic_classes_SetType_a f x = -(let fx = (f x) in - if Pset.subset fx x then x - else leastFixedPointUnbounded - dict_Basic_classes_SetType_a f ( Pset.(union) fx x)) diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_set_helpers.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_set_helpers.ml deleted file mode 100644 index 25aa739f..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_set_helpers.ml +++ /dev/null @@ -1,38 +0,0 @@ -(*Generated by Lem from set_helpers.lem.*) -(******************************************************************************) -(* Helper functions for sets *) -(******************************************************************************) - -(* Usually there is a something.lem file containing the main definitions and a - something_extra.lem one containing functions that might cause problems for - some backends or are just seldomly used. - - For sets the situation is different. folding is not well defined, since it - is only sensibly defined for finite sets and it the traversel - order is underspecified. *) - -(* ========================================================================== *) -(* Header *) -(* ========================================================================== *) - -open Lem_bool -open Lem_basic_classes -open Lem_maybe -open Lem_function -open Lem_num - -(* ------------------------ *) -(* fold *) -(* ------------------------ *) - -(* fold is suspicious, because if given a function, for which - the order, in which the arguments are given, matters, it's - results are undefined. On the other hand, it is very handy to - define other - non suspicious functions. - - Moreover, fold is central for OCaml, size it is used to - compile set comprehensions *) - -(*val fold : forall 'a 'b. ('a -> 'b -> 'b) -> set 'a -> 'b -> 'b*) - - diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_sorting.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_sorting.ml deleted file mode 100644 index fa16f70c..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_sorting.ml +++ /dev/null @@ -1,83 +0,0 @@ -(*Generated by Lem from sorting.lem.*) - - -open Lem_bool -open Lem_basic_classes -open Lem_maybe -open Lem_list -open Lem_num - -(* ------------------------- *) -(* permutations *) -(* ------------------------- *) - -(*val isPermutation : forall 'a. Eq 'a => list 'a -> list 'a -> bool*) -(*val isPermutationBy : forall 'a. ('a -> 'a -> bool) -> list 'a -> list 'a -> bool*) - -let rec isPermutationBy eq l1 l2 = ((match l1 with - | [] -> list_null l2 - | (x :: xs) -> begin - (match list_delete_first (eq x) l2 with - | None -> false - | Some ys -> isPermutationBy eq xs ys - ) - end -)) - - - -(* ------------------------- *) -(* isSorted *) -(* ------------------------- *) - -(* isSortedBy R l - checks, whether the list l is sorted by ordering R. - R should represent an order, i.e. it should be transitive. - Different backends defined "isSorted" slightly differently. However, - the definitions coincide for transitive R. Therefore there is the - following restriction: - - WARNING: Use isSorted and isSortedBy only with transitive relations! -*) - -(*val isSorted : forall 'a. Ord 'a => list 'a -> bool*) -(*val isSortedBy : forall 'a. ('a -> 'a -> bool) -> list 'a -> bool*) - -(* DPM: rejigged the definition with a nested match to get past Coq's termination checker. *) -let rec isSortedBy cmp l = ((match l with - | [] -> true - | x1 :: xs -> - (match xs with - | [] -> true - | x2 :: _ -> (cmp x1 x2 && isSortedBy cmp xs) - ) -)) - - -(* ----------------------- *) -(* insertion sort *) -(* ----------------------- *) - -(*val insert : forall 'a. Ord 'a => 'a -> list 'a -> list 'a*) -(*val insertBy : forall 'a. ('a -> 'a -> bool) -> 'a -> list 'a -> list 'a*) - -(*val insertSort: forall 'a. Ord 'a => list 'a -> list 'a*) -(*val insertSortBy: forall 'a. ('a -> 'a -> bool) -> list 'a -> list 'a*) - -let rec insertBy cmp e l = ((match l with - | [] -> [e] - | x :: xs -> if cmp x e then x :: (insertBy cmp e xs) else (e :: (x :: xs)) -)) - -let insertSortBy cmp l = (List.fold_left (fun l e -> insertBy cmp e l) [] l) - - -(* ----------------------- *) -(* general sorting *) -(* ----------------------- *) - -(*val sort: forall 'a. Ord 'a => list 'a -> list 'a*) -(*val sortBy: forall 'a. ('a -> 'a -> bool) -> list 'a -> list 'a*) -(*val sortByOrd: forall 'a. ('a -> 'a -> ordering) -> list 'a -> list 'a*) - - diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_string.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_string.ml deleted file mode 100644 index f193f7dd..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_string.ml +++ /dev/null @@ -1,53 +0,0 @@ -(*Generated by Lem from string.lem.*) - - -open Lem_bool -open Lem_basic_classes -open Lem_list -open Xstring - -(* ------------------------------------------- *) -(* translations between strings and char lists *) -(* ------------------------------------------- *) - -(*val toCharList : string -> list char*) - -(*val toString : list char -> string*) - - -(* ----------------------- *) -(* generating strings *) -(* ----------------------- *) - -(*val makeString : nat -> char -> string*) -(*let makeString len c = toString (replicate len c)*) - -(* ----------------------- *) -(* length *) -(* ----------------------- *) - -(*val stringLength : string -> nat*) - -(* ----------------------- *) -(* string concatenation *) -(* ----------------------- *) - -(*val ^ [stringAppend] : string -> string -> string*) - - -(* ----------------------------*) -(* setting up pattern matching *) -(* --------------------------- *) - -(*val string_case : forall 'a. string -> 'a -> (char -> string -> 'a) -> 'a*) - -(*let string_case s c_empty c_cons = - match (toCharList s) with - | [] -> c_empty - | c :: cs -> c_cons c (toString cs) - end*) - -(*val empty_string : string*) - -(*val cons_string : char -> string -> string*) - diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_string_extra.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_string_extra.ml deleted file mode 100644 index a3c8fe7b..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_string_extra.ml +++ /dev/null @@ -1,91 +0,0 @@ -(*Generated by Lem from string_extra.lem.*) -(******************************************************************************) -(* String functions *) -(******************************************************************************) - -open Lem_basic_classes -open Lem_num -open Lem_list -open Lem_string -open Lem_list_extra - - -(******************************************************************************) -(* Character's to numbers *) -(******************************************************************************) - -(*val ord : char -> nat*) - -(*val chr : nat -> char*) - -(******************************************************************************) -(* Converting to strings *) -(******************************************************************************) - -type 'a show_class={ - show_method : 'a -> string -} - -(*val natToStringHelper : nat -> list char -> list char*) -let rec natToStringHelper n acc = -(if n = 0 then - acc - else - natToStringHelper (n / 10) (Char.chr ((n mod 10) + 48) :: acc)) - -(*val natToString : nat -> string*) -let natToString n = (Xstring.implode (natToStringHelper n [])) - -let instance_String_extra_Show_nat_dict =({ - - show_method = natToString}) - -(*val naturalToStringHelper : natural -> list char -> list char*) -let rec naturalToStringHelper n acc = -(if Big_int.eq_big_int n(Big_int.big_int_of_int 0) then - acc - else - naturalToStringHelper ( Big_int.div_big_int n(Big_int.big_int_of_int 10)) (Char.chr (Big_int.int_of_big_int ( Big_int.add_big_int (Big_int.mod_big_int n(Big_int.big_int_of_int 10))(Big_int.big_int_of_int 48))) :: acc)) - -(*val naturalToString : natural -> string*) -let naturalToString n = (Xstring.implode (naturalToStringHelper n [])) - -let instance_String_extra_Show_Num_natural_dict =({ - - show_method = naturalToString}) - - -(******************************************************************************) -(* List-like operations *) -(******************************************************************************) - -(*val nth : string -> nat -> char*) -(*let nth s n = List_extra.nth (toCharList s) n*) - -(*val stringConcat : list string -> string*) -(*let stringConcat s = - List.foldr (^) "" s*) - -(******************************************************************************) -(* String comparison *) -(******************************************************************************) - -(*val stringCompare : string -> string -> ordering*) - -let stringLess x y = (Lem.orderingIsLess (compare x y)) -let stringLessEq x y = (not (Lem.orderingIsGreater (compare x y))) -let stringGreater x y = (stringLess y x) -let stringGreaterEq x y = (stringLessEq y x) - -let instance_Basic_classes_Ord_string_dict =({ - - compare_method = compare; - - isLess_method = stringLess; - - isLessEqual_method = stringLessEq; - - isGreater_method = stringGreater; - - isGreaterEqual_method = stringGreaterEq}) - diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_tuple.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_tuple.ml deleted file mode 100644 index 8b7aec27..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_tuple.ml +++ /dev/null @@ -1,41 +0,0 @@ -(*Generated by Lem from tuple.lem.*) - - -open Lem_bool -open Lem_basic_classes - -(* ----------------------- *) -(* fst *) -(* ----------------------- *) - -(*val fst : forall 'a 'b. 'a * 'b -> 'a*) -(*let fst (v1, v2) = v1*) - -(* ----------------------- *) -(* snd *) -(* ----------------------- *) - -(*val snd : forall 'a 'b. 'a * 'b -> 'b*) -(*let snd (v1, v2) = v2*) - - -(* ----------------------- *) -(* curry *) -(* ----------------------- *) - -(*val curry : forall 'a 'b 'c. ('a * 'b -> 'c) -> ('a -> 'b -> 'c)*) - -(* ----------------------- *) -(* uncurry *) -(* ----------------------- *) - -(*val uncurry : forall 'a 'b 'c. ('a -> 'b -> 'c) -> ('a * 'b -> 'c)*) - - -(* ----------------------- *) -(* swap *) -(* ----------------------- *) - -(*val swap : forall 'a 'b. ('a * 'b) -> ('b * 'a)*) -(*let swap (v1, v2) = (v2, v1)*) - diff --git a/lib/ocaml_rts/linksem/src_lem_library/lem_word.ml b/lib/ocaml_rts/linksem/src_lem_library/lem_word.ml deleted file mode 100644 index b446f885..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/lem_word.ml +++ /dev/null @@ -1,731 +0,0 @@ -(*Generated by Lem from word.lem.*) - - -open Lem_bool -open Lem_maybe -open Lem_num -open Lem_basic_classes -open Lem_list - - -(* ========================================================================== *) -(* Define general purpose word, i.e. sequences of bits of arbitrary length *) -(* ========================================================================== *) - -type bitSequence = BitSeq of - int option * (* length of the sequence, Nothing means infinite length *) - bool * bool (* sign of the word, used to fill up after concrete value is exhausted *) - list (* the initial part of the sequence, least significant bit first *) - -(*val bitSeqEq : bitSequence -> bitSequence -> bool*) -let instance_Basic_classes_Eq_Word_bitSequence_dict =({ - - isEqual_method = (=); - - isInequal_method = (fun n1 n2->not (n1 = n2))}) - -(*val boolListFrombitSeq : nat -> bitSequence -> list bool*) - -let rec boolListFrombitSeqAux n s bl = -(if n = 0 then [] else - (match bl with - | [] -> replicate n s - | b :: bl' -> b :: (boolListFrombitSeqAux (Nat_num.nat_monus n( 1)) s bl') - )) - -let boolListFrombitSeq n (BitSeq( _, s, bl)) = (boolListFrombitSeqAux n s bl) - - -(*val bitSeqFromBoolList : list bool -> maybe bitSequence*) -let bitSeqFromBoolList bl = -((match dest_init bl with - | None -> None - | Some (bl', s) -> Some (BitSeq( (Some (List.length bl)), s, bl')) - )) - - -(* cleans up the representation of a bitSequence without changing its semantics *) -(*val cleanBitSeq : bitSequence -> bitSequence*) -let cleanBitSeq (BitSeq( len, s, bl)) = ((match len with - | None -> (BitSeq( len, s, (List.rev (dropWhile ((=) s) (List.rev bl))))) - | Some n -> (BitSeq( len, s, (List.rev (dropWhile ((=) s) (List.rev (Lem_list.take (Nat_num.nat_monus n( 1)) bl)))))) -)) - - -(*val bitSeqTestBit : bitSequence -> nat -> maybe bool*) -let bitSeqTestBit (BitSeq( len, s, bl)) pos = - ((match len with - | None -> if pos < List.length bl then list_index bl pos else Some s - | Some l -> if (pos >= l) then None else - if ((pos = ( Nat_num.nat_monus l( 1))) || (pos >= List.length bl)) then Some s else - list_index bl pos - )) - -(*val bitSeqSetBit : bitSequence -> nat -> bool -> bitSequence*) -let bitSeqSetBit (BitSeq( len, s, bl)) pos v = -(let bl' = (if (pos < List.length bl) then bl else List.append bl (replicate pos s)) in - let bl'' = (Lem_list.list_update bl' pos v) in - let bs' = (BitSeq( len, s, bl'')) in - cleanBitSeq bs') - - -(*val resizeBitSeq : maybe nat -> bitSequence -> bitSequence*) -let resizeBitSeq new_len bs = -(let (BitSeq( len, s, bl)) = (cleanBitSeq bs) in - let shorten_opt = ((match (new_len, len) with - | (None, _) -> None - | (Some l1, None) -> Some l1 - | (Some l1, Some l2) -> if (l1 < l2) then Some l1 else None - )) in - (match shorten_opt with - | None -> BitSeq( new_len, s, bl) - | Some l1 -> ( - let bl' = (Lem_list.take l1 ( List.append bl [s])) in - (match dest_init bl' with - | None -> (BitSeq( len, s, bl)) (* do nothing if size 0 is requested *) - | Some (bl'', s') -> cleanBitSeq (BitSeq( new_len, s', bl'')) - )) - )) - -(*val bitSeqNot : bitSequence -> bitSequence*) -let bitSeqNot (BitSeq( len, s, bl)) = (BitSeq( len, (not s), (List.map not bl))) - -(*val bitSeqBinop : (bool -> bool -> bool) -> bitSequence -> bitSequence -> bitSequence*) - -(*val bitSeqBinopAux : (bool -> bool -> bool) -> bool -> list bool -> bool -> list bool -> list bool*) -let rec bitSeqBinopAux binop s1 bl1 s2 bl2 = -((match (bl1, bl2) with - | ([], []) -> [] - | (b1 :: bl1', []) -> (binop b1 s2) :: bitSeqBinopAux binop s1 bl1' s2 [] - | ([], b2 :: bl2') -> (binop s1 b2) :: bitSeqBinopAux binop s1 [] s2 bl2' - | (b1 :: bl1', b2 :: bl2') -> (binop b1 b2) :: bitSeqBinopAux binop s1 bl1' s2 bl2' - )) - -let bitSeqBinop binop bs1 bs2 = ( - let (BitSeq( len1, s1, bl1)) = (cleanBitSeq bs1) in - let (BitSeq( len2, s2, bl2)) = (cleanBitSeq bs2) in - - let len = ((match (len1, len2) with - | (Some l1, Some l2) -> Some (max l1 l2) - | _ -> None - )) in - let s = (binop s1 s2) in - let bl = (bitSeqBinopAux binop s1 bl1 s2 bl2) in - cleanBitSeq (BitSeq( len, s, bl)) -) - -let bitSeqAnd = (bitSeqBinop (&&)) -let bitSeqOr = (bitSeqBinop (||)) -let bitSeqXor = (bitSeqBinop (fun b1 b2->not (b1 = b2))) - -(*val bitSeqShiftLeft : bitSequence -> nat -> bitSequence*) -let bitSeqShiftLeft (BitSeq( len, s, bl)) n = (cleanBitSeq (BitSeq( len, s, ( List.append(replicate n false) bl)))) - -(*val bitSeqArithmeticShiftRight : bitSequence -> nat -> bitSequence*) -let bitSeqArithmeticShiftRight bs n = - (let (BitSeq( len, s, bl)) = (cleanBitSeq bs) in - cleanBitSeq (BitSeq( len, s, (drop n bl)))) - -(*val bitSeqLogicalShiftRight : bitSequence -> nat -> bitSequence*) -let bitSeqLogicalShiftRight bs n = - (if (n = 0) then cleanBitSeq bs else - let (BitSeq( len, s, bl)) = (cleanBitSeq bs) in - (match len with - | None -> cleanBitSeq (BitSeq( len, s, (drop n bl))) - | Some l -> cleanBitSeq (BitSeq( len, false, ( List.append(drop n bl) (replicate l s)))) - )) - - -(* integerFromBoolList sign bl creates an integer from a list of bits - (least significant bit first) and an explicitly given sign bit. - It uses two's complement encoding. *) -(*val integerFromBoolList : (bool * list bool) -> integer*) - -let rec integerFromBoolListAux (acc : Big_int.big_int) (bl : bool list) = - ((match bl with - | [] -> acc - | (true :: bl') -> integerFromBoolListAux ( Big_int.add_big_int( Big_int.mult_big_int acc(Big_int.big_int_of_int 2))(Big_int.big_int_of_int 1)) bl' - | (false :: bl') -> integerFromBoolListAux ( Big_int.mult_big_int acc(Big_int.big_int_of_int 2)) bl' - )) - -let integerFromBoolList (sign, bl) = - (if sign then - Big_int.minus_big_int( Big_int.add_big_int(integerFromBoolListAux(Big_int.big_int_of_int 0) (List.rev_map not bl))(Big_int.big_int_of_int 1)) - else integerFromBoolListAux(Big_int.big_int_of_int 0) (List.rev bl)) - -(* [boolListFromInteger i] creates a sign bit and a list of booleans from an integer. The len_opt tells it when to stop.*) -(*val boolListFromInteger : integer -> bool * list bool*) - -let rec boolListFromNatural acc (remainder : Big_int.big_int) = -(if ( Big_int.gt_big_int remainder(Big_int.big_int_of_int 0)) then - (boolListFromNatural (( Big_int.eq_big_int( Big_int.mod_big_int remainder(Big_int.big_int_of_int 2))(Big_int.big_int_of_int 1)) :: acc) - ( Big_int.div_big_int remainder(Big_int.big_int_of_int 2))) - else - List.rev acc) - -let boolListFromInteger (i : Big_int.big_int) = - (if ( Big_int.lt_big_int i(Big_int.big_int_of_int 0)) then - (true, List.map not (boolListFromNatural [] (Big_int.abs_big_int (Big_int.minus_big_int( Big_int.add_big_int i(Big_int.big_int_of_int 1)))))) - else - (false, boolListFromNatural [] (Big_int.abs_big_int i))) - - -(* [bitSeqFromInteger len_opt i] encodes [i] as a bitsequence with [len_opt] bits. If there are not enough - bits, truncation happens *) -(*val bitSeqFromInteger : maybe nat -> integer -> bitSequence*) -let bitSeqFromInteger len_opt i = -(let (s, bl) = (boolListFromInteger i) in - resizeBitSeq len_opt (BitSeq( None, s, bl))) - - -(*val integerFromBitSeq : bitSequence -> integer*) -let integerFromBitSeq bs = -(let (BitSeq( len, s, bl)) = (cleanBitSeq bs) in - integerFromBoolList (s, bl)) - - -(* Now we can via translation to integers map arithmetic operations to bitSequences *) - -(*val bitSeqArithUnaryOp : (integer -> integer) -> bitSequence -> bitSequence*) -let bitSeqArithUnaryOp uop bs = -(let (BitSeq( len, _, _)) = bs in - bitSeqFromInteger len (uop (integerFromBitSeq bs))) - -(*val bitSeqArithBinOp : (integer -> integer -> integer) -> bitSequence -> bitSequence -> bitSequence*) -let bitSeqArithBinOp binop bs1 bs2 = -(let (BitSeq( len1, _, _)) = bs1 in - let (BitSeq( len2, _, _)) = bs2 in - let len = ((match (len1, len2) with - | (Some l1, Some l2) -> Some (max l1 l2) - | _ -> None - )) in - bitSeqFromInteger len (binop (integerFromBitSeq bs1) (integerFromBitSeq bs2))) - -(*val bitSeqArithBinTest : forall 'a. (integer -> integer -> 'a) -> bitSequence -> bitSequence -> 'a*) -let bitSeqArithBinTest binop bs1 bs2 = (binop (integerFromBitSeq bs1) (integerFromBitSeq bs2)) - - -(* now instantiate the number interface for bit-sequences *) - -(*val bitSeqFromNumeral : numeral -> bitSequence*) - -(*val bitSeqLess : bitSequence -> bitSequence -> bool*) -let bitSeqLess bs1 bs2 = (bitSeqArithBinTest Big_int.lt_big_int bs1 bs2) - -(*val bitSeqLessEqual : bitSequence -> bitSequence -> bool*) -let bitSeqLessEqual bs1 bs2 = (bitSeqArithBinTest Big_int.le_big_int bs1 bs2) - -(*val bitSeqGreater : bitSequence -> bitSequence -> bool*) -let bitSeqGreater bs1 bs2 = (bitSeqArithBinTest Big_int.gt_big_int bs1 bs2) - -(*val bitSeqGreaterEqual : bitSequence -> bitSequence -> bool*) -let bitSeqGreaterEqual bs1 bs2 = (bitSeqArithBinTest Big_int.ge_big_int bs1 bs2) - -(*val bitSeqCompare : bitSequence -> bitSequence -> ordering*) -let bitSeqCompare bs1 bs2 = (bitSeqArithBinTest Big_int.compare_big_int bs1 bs2) - -let instance_Basic_classes_Ord_Word_bitSequence_dict =({ - - compare_method = bitSeqCompare; - - isLess_method = bitSeqLess; - - isLessEqual_method = bitSeqLessEqual; - - isGreater_method = bitSeqGreater; - - isGreaterEqual_method = bitSeqGreaterEqual}) - -let instance_Basic_classes_SetType_Word_bitSequence_dict =({ - - setElemCompare_method = bitSeqCompare}) - -(* arithmetic negation, don't mix up with bitwise negation *) -(*val bitSeqNegate : bitSequence -> bitSequence*) -let bitSeqNegate bs = (bitSeqArithUnaryOp Big_int.minus_big_int bs) - -let instance_Num_NumNegate_Word_bitSequence_dict =({ - - numNegate_method = bitSeqNegate}) - - -(*val bitSeqAdd : bitSequence -> bitSequence -> bitSequence*) -let bitSeqAdd bs1 bs2 = (bitSeqArithBinOp Big_int.add_big_int bs1 bs2) - -let instance_Num_NumAdd_Word_bitSequence_dict =({ - - numAdd_method = bitSeqAdd}) - -(*val bitSeqMinus : bitSequence -> bitSequence -> bitSequence*) -let bitSeqMinus bs1 bs2 = (bitSeqArithBinOp Big_int.sub_big_int bs1 bs2) - -let instance_Num_NumMinus_Word_bitSequence_dict =({ - - numMinus_method = bitSeqMinus}) - -(*val bitSeqSucc : bitSequence -> bitSequence*) -let bitSeqSucc bs = (bitSeqArithUnaryOp Big_int.succ_big_int bs) - -let instance_Num_NumSucc_Word_bitSequence_dict =({ - - succ_method = bitSeqSucc}) - -(*val bitSeqPred : bitSequence -> bitSequence*) -let bitSeqPred bs = (bitSeqArithUnaryOp Big_int.pred_big_int bs) - -let instance_Num_NumPred_Word_bitSequence_dict =({ - - pred_method = bitSeqPred}) - -(*val bitSeqMult : bitSequence -> bitSequence -> bitSequence*) -let bitSeqMult bs1 bs2 = (bitSeqArithBinOp Big_int.mult_big_int bs1 bs2) - -let instance_Num_NumMult_Word_bitSequence_dict =({ - - numMult_method = bitSeqMult}) - - -(*val bitSeqPow : bitSequence -> nat -> bitSequence*) -let bitSeqPow bs n = (bitSeqArithUnaryOp (fun i -> Big_int.power_big_int_positive_int i n) bs) - -let instance_Num_NumPow_Word_bitSequence_dict =({ - - numPow_method = bitSeqPow}) - -(*val bitSeqDiv : bitSequence -> bitSequence -> bitSequence*) -let bitSeqDiv bs1 bs2 = (bitSeqArithBinOp Big_int.div_big_int bs1 bs2) - -let instance_Num_NumIntegerDivision_Word_bitSequence_dict =({ - - div_method = bitSeqDiv}) - -let instance_Num_NumDivision_Word_bitSequence_dict =({ - - numDivision_method = bitSeqDiv}) - -(*val bitSeqMod : bitSequence -> bitSequence -> bitSequence*) -let bitSeqMod bs1 bs2 = (bitSeqArithBinOp Big_int.mod_big_int bs1 bs2) - -let instance_Num_NumRemainder_Word_bitSequence_dict =({ - - mod_method = bitSeqMod}) - -(*val bitSeqMin : bitSequence -> bitSequence -> bitSequence*) -let bitSeqMin bs1 bs2 = (bitSeqArithBinOp Big_int.min_big_int bs1 bs2) - -(*val bitSeqMax : bitSequence -> bitSequence -> bitSequence*) -let bitSeqMax bs1 bs2 = (bitSeqArithBinOp Big_int.max_big_int bs1 bs2) - -let instance_Basic_classes_OrdMaxMin_Word_bitSequence_dict =({ - - max_method = bitSeqMax; - - min_method = bitSeqMin}) - - - - -(* ========================================================================== *) -(* Interface for bitoperations *) -(* ========================================================================== *) - -type 'a wordNot_class= { - lnot_method : 'a -> 'a -} - -type 'a wordAnd_class= { - land_method : 'a -> 'a -> 'a -} - -type 'a wordOr_class= { - lor_method : 'a -> 'a -> 'a -} - - -type 'a wordXor_class= { - lxor_method : 'a -> 'a -> 'a -} - -type 'a wordLsl_class= { - lsl_method : 'a -> int -> 'a -} - -type 'a wordLsr_class= { - lsr_method : 'a -> int -> 'a -} - -type 'a wordAsr_class= { - asr_method : 'a -> int -> 'a -} - -(* ----------------------- *) -(* bitSequence *) -(* ----------------------- *) - -let instance_Word_WordNot_Word_bitSequence_dict =({ - - lnot_method = bitSeqNot}) - -let instance_Word_WordAnd_Word_bitSequence_dict =({ - - land_method = bitSeqAnd}) - -let instance_Word_WordOr_Word_bitSequence_dict =({ - - lor_method = bitSeqOr}) - -let instance_Word_WordXor_Word_bitSequence_dict =({ - - lxor_method = bitSeqXor}) - -let instance_Word_WordLsl_Word_bitSequence_dict =({ - - lsl_method = bitSeqShiftLeft}) - -let instance_Word_WordLsr_Word_bitSequence_dict =({ - - lsr_method = bitSeqLogicalShiftRight}) - -let instance_Word_WordAsr_Word_bitSequence_dict =({ - - asr_method = bitSeqArithmeticShiftRight}) - - -(* ----------------------- *) -(* int32 *) -(* ----------------------- *) - -(*val int32Lnot : int32 -> int32*) (* XXX: fix *) - -let instance_Word_WordNot_Num_int32_dict =({ - - lnot_method = Int32.lognot}) - - -(*val int32Lor : int32 -> int32 -> int32*) (* XXX: fix *) - -let instance_Word_WordOr_Num_int32_dict =({ - - lor_method = Int32.logor}) - -(*val int32Lxor : int32 -> int32 -> int32*) (* XXX: fix *) - -let instance_Word_WordXor_Num_int32_dict =({ - - lxor_method = Int32.logxor}) - -(*val int32Land : int32 -> int32 -> int32*) (* XXX: fix *) - -let instance_Word_WordAnd_Num_int32_dict =({ - - land_method = Int32.logand}) - -(*val int32Lsl : int32 -> nat -> int32*) (* XXX: fix *) - -let instance_Word_WordLsl_Num_int32_dict =({ - - lsl_method = Int32.shift_left}) - -(*val int32Lsr : int32 -> nat -> int32*) (* XXX: fix *) - -let instance_Word_WordLsr_Num_int32_dict =({ - - lsr_method = Int32.shift_right_logical}) - - -(*val int32Asr : int32 -> nat -> int32*) (* XXX: fix *) - -let instance_Word_WordAsr_Num_int32_dict =({ - - asr_method = Int32.shift_right}) - - -(* ----------------------- *) -(* int64 *) -(* ----------------------- *) - -(*val int64Lnot : int64 -> int64*) (* XXX: fix *) - -let instance_Word_WordNot_Num_int64_dict =({ - - lnot_method = Int64.lognot}) - -(*val int64Lor : int64 -> int64 -> int64*) (* XXX: fix *) - -let instance_Word_WordOr_Num_int64_dict =({ - - lor_method = Int64.logor}) - -(*val int64Lxor : int64 -> int64 -> int64*) (* XXX: fix *) - -let instance_Word_WordXor_Num_int64_dict =({ - - lxor_method = Int64.logxor}) - -(*val int64Land : int64 -> int64 -> int64*) (* XXX: fix *) - -let instance_Word_WordAnd_Num_int64_dict =({ - - land_method = Int64.logand}) - -(*val int64Lsl : int64 -> nat -> int64*) (* XXX: fix *) - -let instance_Word_WordLsl_Num_int64_dict =({ - - lsl_method = Int64.shift_left}) - -(*val int64Lsr : int64 -> nat -> int64*) (* XXX: fix *) - -let instance_Word_WordLsr_Num_int64_dict =({ - - lsr_method = Int64.shift_right_logical}) - -(*val int64Asr : int64 -> nat -> int64*) (* XXX: fix *) - -let instance_Word_WordAsr_Num_int64_dict =({ - - asr_method = Int64.shift_right}) - - -(* ----------------------- *) -(* Words via bit sequences *) -(* ----------------------- *) - -(*val defaultLnot : forall 'a. (bitSequence -> 'a) -> ('a -> bitSequence) -> 'a -> 'a*) -let defaultLnot fromBitSeq toBitSeq x = (fromBitSeq (bitSeqNegate (toBitSeq x))) - -(*val defaultLand : forall 'a. (bitSequence -> 'a) -> ('a -> bitSequence) -> 'a -> 'a -> 'a*) -let defaultLand fromBitSeq toBitSeq x1 x2 = (fromBitSeq (bitSeqAnd (toBitSeq x1) (toBitSeq x2))) - -(*val defaultLor : forall 'a. (bitSequence -> 'a) -> ('a -> bitSequence) -> 'a -> 'a -> 'a*) -let defaultLor fromBitSeq toBitSeq x1 x2 = (fromBitSeq (bitSeqOr (toBitSeq x1) (toBitSeq x2))) - -(*val defaultLxor : forall 'a. (bitSequence -> 'a) -> ('a -> bitSequence) -> 'a -> 'a -> 'a*) -let defaultLxor fromBitSeq toBitSeq x1 x2 = (fromBitSeq (bitSeqXor (toBitSeq x1) (toBitSeq x2))) - -(*val defaultLsl : forall 'a. (bitSequence -> 'a) -> ('a -> bitSequence) -> 'a -> nat -> 'a*) -let defaultLsl fromBitSeq toBitSeq x n = (fromBitSeq (bitSeqShiftLeft (toBitSeq x) n)) - -(*val defaultLsr : forall 'a. (bitSequence -> 'a) -> ('a -> bitSequence) -> 'a -> nat -> 'a*) -let defaultLsr fromBitSeq toBitSeq x n = (fromBitSeq (bitSeqLogicalShiftRight (toBitSeq x) n)) - -(*val defaultAsr : forall 'a. (bitSequence -> 'a) -> ('a -> bitSequence) -> 'a -> nat -> 'a*) -let defaultAsr fromBitSeq toBitSeq x n = (fromBitSeq (bitSeqArithmeticShiftRight (toBitSeq x) n)) - -(* ----------------------- *) -(* integer *) -(* ----------------------- *) - -(*val integerLnot : integer -> integer*) -let integerLnot i = (Big_int.minus_big_int( Big_int.add_big_int i(Big_int.big_int_of_int 1))) - -let instance_Word_WordNot_Num_integer_dict =({ - - lnot_method = integerLnot}) - - -(*val integerLor : integer -> integer -> integer*) -(*let integerLor i1 i2 = defaultLor integerFromBitSeq (bitSeqFromInteger Nothing) i1 i2*) - -let instance_Word_WordOr_Num_integer_dict =({ - - lor_method = Big_int.or_big_int}) - -(*val integerLxor : integer -> integer -> integer*) -(*let integerLxor i1 i2 = defaultLxor integerFromBitSeq (bitSeqFromInteger Nothing) i1 i2*) - -let instance_Word_WordXor_Num_integer_dict =({ - - lxor_method = Big_int.xor_big_int}) - -(*val integerLand : integer -> integer -> integer*) -(*let integerLand i1 i2 = defaultLand integerFromBitSeq (bitSeqFromInteger Nothing) i1 i2*) - -let instance_Word_WordAnd_Num_integer_dict =({ - - land_method = Big_int.and_big_int}) - -(*val integerLsl : integer -> nat -> integer*) -(*let integerLsl i n = defaultLsl integerFromBitSeq (bitSeqFromInteger Nothing) i n*) - -let instance_Word_WordLsl_Num_integer_dict =({ - - lsl_method = Big_int.shift_left_big_int}) - -(*val integerAsr : integer -> nat -> integer*) -(*let integerAsr i n = defaultAsr integerFromBitSeq (bitSeqFromInteger Nothing) i n*) - -let instance_Word_WordLsr_Num_integer_dict =({ - - lsr_method = Big_int.shift_right_big_int}) - -let instance_Word_WordAsr_Num_integer_dict =({ - - asr_method = Big_int.shift_right_big_int}) - - -(* ----------------------- *) -(* int *) -(* ----------------------- *) - -(* sometimes it is convenient to be able to perform bit-operations on ints. - However, since int is not well-defined (it has different size on different systems), - it should be used very carefully and only for operations that don't depend on the - bitwidth of int *) - -(*val intFromBitSeq : bitSequence -> int*) -let intFromBitSeq bs = (Big_int.int_of_big_int (integerFromBitSeq (resizeBitSeq (Some( 31)) bs))) - - -(*val bitSeqFromInt : int -> bitSequence*) -let bitSeqFromInt i = (bitSeqFromInteger (Some( 31)) (Big_int.big_int_of_int i)) - - -(*val intLnot : int -> int*) -(*let intLnot i = Instance_Num_NumNegate_Num_int.~((Instance_Num_NumAdd_Num_int.+) i 1)*) - -let instance_Word_WordNot_Num_int_dict =({ - - lnot_method = lnot}) - -(*val intLor : int -> int -> int*) -(*let intLor i1 i2 = defaultLor intFromBitSeq bitSeqFromInt i1 i2*) - -let instance_Word_WordOr_Num_int_dict =({ - - lor_method = (lor)}) - -(*val intLxor : int -> int -> int*) -(*let intLxor i1 i2 = defaultLxor intFromBitSeq bitSeqFromInt i1 i2*) - -let instance_Word_WordXor_Num_int_dict =({ - - lxor_method = (lxor)}) - -(*val intLand : int -> int -> int*) -(*let intLand i1 i2 = defaultLand intFromBitSeq bitSeqFromInt i1 i2*) - -let instance_Word_WordAnd_Num_int_dict =({ - - land_method = (land)}) - -(*val intLsl : int -> nat -> int*) -(*let intLsl i n = defaultLsl intFromBitSeq bitSeqFromInt i n*) - -let instance_Word_WordLsl_Num_int_dict =({ - - lsl_method = (lsl)}) - -(*val intAsr : int -> nat -> int*) -(*let intAsr i n = defaultAsr intFromBitSeq bitSeqFromInt i n*) - -let instance_Word_WordAsr_Num_int_dict =({ - - asr_method = (asr)}) - - - -(* ----------------------- *) -(* natural *) -(* ----------------------- *) - -(* some operations work also on positive numbers *) - -(*val naturalFromBitSeq : bitSequence -> natural*) -let naturalFromBitSeq bs = (Big_int.abs_big_int (integerFromBitSeq bs)) - -(*val bitSeqFromNatural : maybe nat -> natural -> bitSequence*) -let bitSeqFromNatural len n = (bitSeqFromInteger len ( n)) - -(*val naturalLor : natural -> natural -> natural*) -(*let naturalLor i1 i2 = defaultLor naturalFromBitSeq (bitSeqFromNatural Nothing) i1 i2*) - -let instance_Word_WordOr_Num_natural_dict =({ - - lor_method = Big_int.or_big_int}) - -(*val naturalLxor : natural -> natural -> natural*) -(*let naturalLxor i1 i2 = defaultLxor naturalFromBitSeq (bitSeqFromNatural Nothing) i1 i2*) - -let instance_Word_WordXor_Num_natural_dict =({ - - lxor_method = Big_int.xor_big_int}) - -(*val naturalLand : natural -> natural -> natural*) -(*let naturalLand i1 i2 = defaultLand naturalFromBitSeq (bitSeqFromNatural Nothing) i1 i2*) - -let instance_Word_WordAnd_Num_natural_dict =({ - - land_method = Big_int.and_big_int}) - -(*val naturalLsl : natural -> nat -> natural*) -(*let naturalLsl i n = defaultLsl naturalFromBitSeq (bitSeqFromNatural Nothing) i n*) - -let instance_Word_WordLsl_Num_natural_dict =({ - - lsl_method = Big_int.shift_left_big_int}) - -(*val naturalAsr : natural -> nat -> natural*) -(*let naturalAsr i n = defaultAsr naturalFromBitSeq (bitSeqFromNatural Nothing) i n*) - -let instance_Word_WordLsr_Num_natural_dict =({ - - lsr_method = Big_int.shift_right_big_int}) - -let instance_Word_WordAsr_Num_natural_dict =({ - - asr_method = Big_int.shift_right_big_int}) - - -(* ----------------------- *) -(* nat *) -(* ----------------------- *) - -(* sometimes it is convenient to be able to perform bit-operations on nats. - However, since nat is not well-defined (it has different size on different systems), - it should be used very carefully and only for operations that don't depend on the - bitwidth of nat *) - -(*val natFromBitSeq : bitSequence -> nat*) -let natFromBitSeq bs = (Big_int.int_of_big_int (naturalFromBitSeq (resizeBitSeq (Some( 31)) bs))) - - -(*val bitSeqFromNat : nat -> bitSequence*) -let bitSeqFromNat i = (bitSeqFromNatural (Some( 31)) (Big_int.big_int_of_int i)) - - -(*val natLor : nat -> nat -> nat*) -(*let natLor i1 i2 = defaultLor natFromBitSeq bitSeqFromNat i1 i2*) - -let instance_Word_WordOr_nat_dict =({ - - lor_method = (lor)}) - -(*val natLxor : nat -> nat -> nat*) -(*let natLxor i1 i2 = defaultLxor natFromBitSeq bitSeqFromNat i1 i2*) - -let instance_Word_WordXor_nat_dict =({ - - lxor_method = (lxor)}) - -(*val natLand : nat -> nat -> nat*) -(*let natLand i1 i2 = defaultLand natFromBitSeq bitSeqFromNat i1 i2*) - -let instance_Word_WordAnd_nat_dict =({ - - land_method = (land)}) - -(*val natLsl : nat -> nat -> nat*) -(*let natLsl i n = defaultLsl natFromBitSeq bitSeqFromNat i n*) - -let instance_Word_WordLsl_nat_dict =({ - - lsl_method = (lsl)}) - -(*val natAsr : nat -> nat -> nat*) -(*let natAsr i n = defaultAsr natFromBitSeq bitSeqFromNat i n*) - -let instance_Word_WordAsr_nat_dict =({ - - asr_method = (asr)}) - diff --git a/lib/ocaml_rts/linksem/src_lem_library/nat_big_num.ml b/lib/ocaml_rts/linksem/src_lem_library/nat_big_num.ml deleted file mode 100644 index 2320188c..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/nat_big_num.ml +++ /dev/null @@ -1,18 +0,0 @@ -module BI = Big_int - -type num = BI.big_int -let (<) = BI.lt_big_int -let (<=) = BI.le_big_int -let (>) = BI.gt_big_int -let (>=) = BI.ge_big_int -let (+) = BI.add_big_int -let (-) x y = - let d = BI.sub_big_int x y in - if d < BI.zero_big_int then - BI.zero_big_int - else - d -let ( * ) = BI.mult_big_int -let (/) = BI.div_big_int -let (mod) = BI.mod_big_int -let string_of_num = BI.string_of_big_int diff --git a/lib/ocaml_rts/linksem/src_lem_library/nat_big_num.mli b/lib/ocaml_rts/linksem/src_lem_library/nat_big_num.mli deleted file mode 100644 index b6f6eb63..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/nat_big_num.mli +++ /dev/null @@ -1,11 +0,0 @@ -type num -val (<) : num -> num -> bool -val (<=) : num -> num -> bool -val (>) : num -> num -> bool -val (>=) : num -> num -> bool -val (+) : num -> num -> num -val (-) : num -> num -> num -val ( * ) : num -> num -> num -val (/) : num -> num -> num -val (mod) : num -> num -> num -val string_of_num : num -> string diff --git a/lib/ocaml_rts/linksem/src_lem_library/nat_num.ml b/lib/ocaml_rts/linksem/src_lem_library/nat_num.ml deleted file mode 100755 index 50165e6d..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/nat_num.ml +++ /dev/null @@ -1,43 +0,0 @@ -type nat = int -type natural = Big_int.big_int - -let nat_monus x y = - let d = x - y in - if d < 0 then - 0 - else - d - -let natural_monus x y = - (if Big_int.le_big_int x y then - Big_int.zero_big_int - else - (Big_int.sub_big_int x y)) - -let nat_pred x = nat_monus x 1 -let natural_pred x = natural_monus x Big_int.unit_big_int - -let int_mod i n = - let r = i mod n in - if (r < 0) then r + n else r - -let int_div i n = - let r = i / n in - if (i mod n < 0) then r - 1 else r - -let int32_mod i n = - let r = Int32.rem i n in - if (r < Int32.zero) then Int32.add r n else r - -let int32_div i n = - let r = Int32.div i n in - if (Int32.rem i n < Int32.zero) then Int32.pred r else r - -let int64_mod i n = - let r = Int64.rem i n in - if (r < Int64.zero) then Int64.add r n else r - -let int64_div i n = - let r = Int64.div i n in - if (Int64.rem i n < Int64.zero) then Int64.pred r else r - diff --git a/lib/ocaml_rts/linksem/src_lem_library/nat_num.mli b/lib/ocaml_rts/linksem/src_lem_library/nat_num.mli deleted file mode 100755 index d918b9df..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/nat_num.mli +++ /dev/null @@ -1,14 +0,0 @@ -type nat = int -type natural = Big_int.big_int - -val natural_monus : natural -> natural -> natural -val natural_pred : natural -> natural - -val nat_pred : nat -> nat -val nat_monus : nat -> nat -> nat -val int_div : int -> int -> int -val int32_div : Int32.t -> Int32.t -> Int32.t -val int64_div : Int64.t -> Int64.t -> Int64.t -val int_mod : int -> int -> int -val int32_mod : Int32.t -> Int32.t -> Int32.t -val int64_mod : Int64.t -> Int64.t -> Int64.t diff --git a/lib/ocaml_rts/linksem/src_lem_library/pmap.ml b/lib/ocaml_rts/linksem/src_lem_library/pmap.ml deleted file mode 100755 index 9e9f607b..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/pmap.ml +++ /dev/null @@ -1,321 +0,0 @@ -(***********************************************************************) -(* *) -(* Objective Caml *) -(* *) -(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) -(* *) -(* Copyright 1996 Institut National de Recherche en Informatique et *) -(* en Automatique. All rights reserved. This file is distributed *) -(* under the terms of the GNU Library General Public License, with *) -(* the special exception on linking described in file ../LICENSE. *) -(* *) -(***********************************************************************) - -(* Modified by Susmit Sarkar 2010-11-30 *) -(* $Id: map.ml 10468 2010-05-25 13:29:43Z frisch $ *) - -(* A map from ordered keys *) - -type ('key,'a) rep = - Empty - | Node of ('key,'a) rep * 'key * 'a * ('key,'a) rep * int - -let height = function - Empty -> 0 - | Node(_,_,_,_,h) -> h - -let create l x d r = - let hl = height l and hr = height r in - Node(l, x, d, r, (if hl >= hr then hl + 1 else hr + 1)) - -let singleton x d = Node(Empty, x, d, Empty, 1) - -let bal l x d r = - let hl = match l with Empty -> 0 | Node(_,_,_,_,h) -> h in - let hr = match r with Empty -> 0 | Node(_,_,_,_,h) -> h in - if hl > hr + 2 then begin - match l with - Empty -> invalid_arg "Map.bal" - | Node(ll, lv, ld, lr, _) -> - if height ll >= height lr then - create ll lv ld (create lr x d r) - else begin - match lr with - Empty -> invalid_arg "Map.bal" - | Node(lrl, lrv, lrd, lrr, _)-> - create (create ll lv ld lrl) lrv lrd (create lrr x d r) - end - end else if hr > hl + 2 then begin - match r with - Empty -> invalid_arg "Map.bal" - | Node(rl, rv, rd, rr, _) -> - if height rr >= height rl then - create (create l x d rl) rv rd rr - else begin - match rl with - Empty -> invalid_arg "Map.bal" - | Node(rll, rlv, rld, rlr, _) -> - create (create l x d rll) rlv rld (create rlr rv rd rr) - end - end else - Node(l, x, d, r, (if hl >= hr then hl + 1 else hr + 1)) - -let empty = Empty - -let is_empty = function Empty -> true | _ -> false - -let rec add cmp x data = function - Empty -> - Node(Empty, x, data, Empty, 1) - | Node(l, v, d, r, h) -> - let c = cmp x v in - if c = 0 then - Node(l, x, data, r, h) - else if c < 0 then - bal (add cmp x data l) v d r - else - bal l v d (add cmp x data r) - -let rec find cmp x = function - Empty -> - raise Not_found - | Node(l, v, d, r, _) -> - let c = cmp x v in - if c = 0 then d - else find cmp x (if c < 0 then l else r) - -let rec mem cmp x = function - Empty -> - false - | Node(l, v, d, r, _) -> - let c = cmp x v in - c = 0 || mem cmp x (if c < 0 then l else r) - -let rec min_binding = function - Empty -> raise Not_found - | Node(Empty, x, d, r, _) -> (x, d) - | Node(l, x, d, r, _) -> min_binding l - -let rec max_binding = function - Empty -> raise Not_found - | Node(l, x, d, Empty, _) -> (x, d) - | Node(l, x, d, r, _) -> max_binding r - -let rec remove_min_binding = function - Empty -> invalid_arg "Map.remove_min_elt" - | Node(Empty, x, d, r, _) -> r - | Node(l, x, d, r, _) -> bal (remove_min_binding l) x d r - -let merge t1 t2 = - match (t1, t2) with - (Empty, t) -> t - | (t, Empty) -> t - | (_, _) -> - let (x, d) = min_binding t2 in - bal t1 x d (remove_min_binding t2) - -let rec remove cmp x = function - Empty -> - Empty - | Node(l, v, d, r, h) -> - let c = cmp x v in - if c = 0 then - merge l r - else if c < 0 then - bal (remove cmp x l) v d r - else - bal l v d (remove cmp x r) - -let rec iter f = function - Empty -> () - | Node(l, v, d, r, _) -> - iter f l; f v d; iter f r - -let rec map f = function - Empty -> - Empty - | Node(l, v, d, r, h) -> - let l' = map f l in - let d' = f d in - let r' = map f r in - Node(l', v, d', r', h) - -let rec mapi f = function - Empty -> - Empty - | Node(l, v, d, r, h) -> - let l' = mapi f l in - let d' = f v d in - let r' = mapi f r in - Node(l', v, d', r', h) - -let rec fold f m accu = - match m with - Empty -> accu - | Node(l, v, d, r, _) -> - fold f r (f v d (fold f l accu)) - -let rec for_all p = function - Empty -> true - | Node(l, v, d, r, _) -> p v d && for_all p l && for_all p r - -let rec exists p = function - Empty -> false - | Node(l, v, d, r, _) -> p v d || exists p l || exists p r - -let filter cmp p s = - let rec filt accu = function - | Empty -> accu - | Node(l, v, d, r, _) -> - filt (filt (if p v d then add cmp v d accu else accu) l) r in - filt Empty s - -let partition cmp p s = - let rec part (t, f as accu) = function - | Empty -> accu - | Node(l, v, d, r, _) -> - part (part (if p v d then (add cmp v d t, f) else (t, add cmp v d f)) l) r in - part (Empty, Empty) s - - (* Same as create and bal, but no assumptions are made on the - relative heights of l and r. *) - -let rec join cmp l v d r = - match (l, r) with - (Empty, _) -> add cmp v d r - | (_, Empty) -> add cmp v d l - | (Node(ll, lv, ld, lr, lh), Node(rl, rv, rd, rr, rh)) -> - if lh > rh + 2 then bal ll lv ld (join cmp lr v d r) else - if rh > lh + 2 then bal (join cmp l v d rl) rv rd rr else - create l v d r - - (* Merge two trees l and r into one. - All elements of l must precede the elements of r. - No assumption on the heights of l and r. *) - -let concat cmp t1 t2 = - match (t1, t2) with - (Empty, t) -> t - | (t, Empty) -> t - | (_, _) -> - let (x, d) = min_binding t2 in - join cmp t1 x d (remove_min_binding t2) - -let concat_or_join cmp t1 v d t2 = - match d with - | Some d -> join cmp t1 v d t2 - | None -> concat cmp t1 t2 - -let rec split cmp x = function - Empty -> - (Empty, None, Empty) - | Node(l, v, d, r, _) -> - let c = cmp x v in - if c = 0 then (l, Some d, r) - else if c < 0 then - let (ll, pres, rl) = split cmp x l in (ll, pres, join cmp rl v d r) - else - let (lr, pres, rr) = split cmp x r in (join cmp l v d lr, pres, rr) - -let rec merge cmp f s1 s2 = - match (s1, s2) with - (Empty, Empty) -> Empty - | (Node (l1, v1, d1, r1, h1), _) when h1 >= height s2 -> - let (l2, d2, r2) = split cmp v1 s2 in - concat_or_join cmp (merge cmp f l1 l2) v1 (f v1 (Some d1) d2) (merge cmp f r1 r2) - | (_, Node (l2, v2, d2, r2, h2)) -> - let (l1, d1, r1) = split cmp v2 s1 in - concat_or_join cmp (merge cmp f l1 l2) v2 (f v2 d1 (Some d2)) (merge cmp f r1 r2) - | _ -> - assert false - -type ('key,'a) enumeration = End | More of 'key * 'a * ('key,'a) rep * ('key,'a) enumeration - -let rec cons_enum m e = - match m with - Empty -> e - | Node(l, v, d, r, _) -> cons_enum l (More(v, d, r, e)) - -let compare cmp_key cmp_a m1 m2 = - let rec compare_aux e1 e2 = - match (e1, e2) with - (End, End) -> 0 - | (End, _) -> -1 - | (_, End) -> 1 - | (More(v1, d1, r1, e1), More(v2, d2, r2, e2)) -> - let c = cmp_key v1 v2 in - if c <> 0 then c else - let c = cmp_a d1 d2 in - if c <> 0 then c else - compare_aux (cons_enum r1 e1) (cons_enum r2 e2) - in compare_aux (cons_enum m1 End) (cons_enum m2 End) - -let equal cmp_key cmp_a m1 m2 = - let rec equal_aux e1 e2 = - match (e1, e2) with - (End, End) -> true - | (End, _) -> false - | (_, End) -> false - | (More(v1, d1, r1, e1), More(v2, d2, r2, e2)) -> - cmp_key v1 v2 = 0 && cmp_a d1 d2 && - equal_aux (cons_enum r1 e1) (cons_enum r2 e2) - in equal_aux (cons_enum m1 End) (cons_enum m2 End) - -let rec cardinal = function - Empty -> 0 - | Node(l, _, _, r, _) -> cardinal l + 1 + cardinal r - -let rec bindings_aux accu = function - Empty -> accu - | Node(l, v, d, r, _) -> bindings_aux ((v, d) :: bindings_aux accu r) l - -let bindings s = - bindings_aux [] s - -let choose = min_binding - - -(* Wrapper functions now *) - -type ('key,'a) map = {cmp:'key -> 'key -> int; m:('key,'a) rep} - -let empty cmp = {cmp = cmp; m = Empty} -let is_empty m = is_empty m.m -let mem k m = mem m.cmp k m.m -let add k a m = {m with m = add m.cmp k a m.m} -let singleton cmp k a = {cmp = cmp; m = singleton k a} -let remove k m = {m with m = remove m.cmp k m.m} -let merge f a b = {cmp = a.cmp; (* does not matter, a and b should have the same comparison function *) - m = merge a.cmp f a.m b.m;} -let union a b = merge (fun k o1 o2 -> - match (o1, o2) with - | (_, Some v) -> Some v - | (Some v, _) -> Some v - | (_, _) -> None) a b - let compare f a b = compare a.cmp f a.m b.m -let equal f a b = equal a.cmp f a.m b.m -let iter f m = iter f m.m -let fold f m b = fold f m.m b -let for_all f m = for_all f m.m -let exist f m = exists f m.m -let filter f m = {m with m = filter m.cmp f m.m} -let partition f m = - let m1,m2 = partition m.cmp f m.m in - ({m with m = m1},{m with m = m2}) -let cardinal m = cardinal m.m -let domain m = Pset.from_list m.cmp (List.map fst (bindings m.m)) -let range cmp m = Pset.from_list cmp (List.map snd (bindings m.m)) -let bindings_list m = bindings m.m -let bindings cmp m = Pset.from_list cmp (bindings m.m) -let min_binding m = min_binding m.m -let max_binding m = max_binding m.m -let choose m = choose m.m -let split k m = - let (m1,opt,m2) = split m.cmp k m.m in - ({m with m = m1},opt,{m with m = m2}) -let find k m = find m.cmp k m.m -let lookup k m = try Some (find k m) with Not_found -> None -let map f m = {m with m = map f m.m} -let mapi f m = {m with m = mapi f m.m} - -let from_set f s = Pset.fold (fun k m -> (add k (f k) m)) s (empty (Pset.get_elem_compare s)) diff --git a/lib/ocaml_rts/linksem/src_lem_library/pmap.mli b/lib/ocaml_rts/linksem/src_lem_library/pmap.mli deleted file mode 100755 index f2016418..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/pmap.mli +++ /dev/null @@ -1,190 +0,0 @@ -(***********************************************************************) -(* *) -(* Objective Caml *) -(* *) -(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) -(* *) -(* Copyright 1996 Institut National de Recherche en Informatique et *) -(* en Automatique. All rights reserved. This file is distributed *) -(* under the terms of the GNU Library General Public License, with *) -(* the special exception on linking described in file ../LICENSE. *) -(* *) -(***********************************************************************) - -(* Modified by Susmit Sarkar 2010-11-30 *) -(* $Id: map.mli 10632 2010-07-24 14:16:58Z garrigue $ *) - -(** Association tables over ordered types. - - This module implements applicative association tables, also known as - finite maps or dictionaries, given a total ordering function - over the keys. - All operations over maps are purely applicative (no side-effects). - The implementation uses balanced binary trees, and therefore searching - and insertion take time logarithmic in the size of the map. -*) - -type ('key,+'a) map - (** The type of maps from type ['key] to type ['a]. *) - -val empty: ('key -> 'key -> int) -> ('key,'a) map - (** The empty map. *) - -val is_empty: ('key,'a) map -> bool - (** Test whether a map is empty or not. *) - -val mem: 'key -> ('key,'a) map -> bool - (** [mem x m] returns [true] if [m] contains a binding for [x], - and [false] otherwise. *) - -val add: 'key -> 'a -> ('key,'a) map -> ('key,'a) map - (** [add x y m] returns a map containing the same bindings as - [m], plus a binding of [x] to [y]. If [x] was already bound - in [m], its previous binding disappears. *) - -val singleton: ('key -> 'key -> int) -> 'key -> 'a -> ('key,'a) map - (** [singleton x y] returns the one-element map that contains a binding [y] - for [x]. - @since 3.12.0 - *) - -val remove: 'key -> ('key,'a) map -> ('key,'a) map - (** [remove x m] returns a map containing the same bindings as - [m], except for [x] which is unbound in the returned map. *) - -val merge: - ('key -> 'a option -> 'b option -> 'c option) -> ('key,'a) map -> ('key,'b) map -> ('key,'c) map - (** [merge f m1 m2] computes a map whose keys is a subset of keys of [m1] - and of [m2]. The presence of each such binding, and the corresponding - value, is determined with the function [f]. - @since 3.12.0 - *) - -val union: ('key,'a) map -> ('key,'a) map -> ('key,'a) map - (** [union m1 m2] computes a map whose keys is a subset of keys of [m1] - and of [m2]. The bindings in m2 take precedence. - @since 3.12.0 - *) - -val compare: ('a -> 'a -> int) -> ('key,'a) map -> ('key,'a) map -> int - (** Total ordering between maps. The first argument is a total ordering - used to compare data associated with equal keys in the two maps. *) - -val equal: ('a -> 'a -> bool) -> ('key,'a) map -> ('key,'a) map -> bool - (** [equal cmp m1 m2] tests whether the maps [m1] and [m2] are - equal, that is, contain equal keys and associate them with - equal data. [cmp] is the equality predicate used to compare - the data associated with the keys. *) - -val iter: ('key -> 'a -> unit) -> ('key,'a) map -> unit - (** [iter f m] applies [f] to all bindings in map [m]. - [f] receives the key as first argument, and the associated value - as second argument. The bindings are passed to [f] in increasing - order with respect to the ordering over the type of the keys. *) - -val fold: ('key -> 'a -> 'b -> 'b) -> ('key,'a) map -> 'b -> 'b - (** [fold f m a] computes [(f kN dN ... (f k1 d1 a)...)], - where [k1 ... kN] are the keys of all bindings in [m] - (in increasing order), and [d1 ... dN] are the associated data. *) - -val for_all: ('key -> 'a -> bool) -> ('key,'a) map -> bool - (** [for_all p m] checks if all the bindings of the map - satisfy the predicate [p]. - @since 3.12.0 - *) - -val exist: ('key -> 'a -> bool) -> ('key,'a) map -> bool - (** [exists p m] checks if at least one binding of the map - satisfy the predicate [p]. - @since 3.12.0 - *) - -val filter: ('key -> 'a -> bool) -> ('key,'a) map -> ('key,'a) map - (** [filter p m] returns the map with all the bindings in [m] - that satisfy predicate [p]. - @since 3.12.0 - *) - -val partition: ('key -> 'a -> bool) -> ('key,'a) map -> ('key,'a) map * ('key,'a) map - (** [partition p m] returns a pair of maps [(m1, m2)], where - [m1] contains all the bindings of [s] that satisfy the - predicate [p], and [m2] is the map with all the bindings of - [s] that do not satisfy [p]. - @since 3.12.0 - *) - -val cardinal: ('key,'a) map -> int - (** Return the number of bindings of a map. - @since 3.12.0 - *) - -val bindings_list: ('key,'a) map -> ('key * 'a) list - (** Return the list of all bindings of the given map. - The returned list is sorted in increasing order with respect - to the ordering [Ord.compare], where [Ord] is the argument - given to {!Map.Make}. - @since 3.12.0 - *) - -val bindings: (('key * 'a) -> ('key * 'a) -> int) -> ('key,'a) map -> ('key * 'a) Pset.set - (** Return a set of all bindings of the given map. *) - -(** [domain m] returns the domain of the map [m], i.e. the - set of keys of this map. *) -val domain : ('key,'a) map -> 'key Pset.set - -(** [range m] returns the range of the map [m], i.e. the - set of all values stored in this map. *) -val range : ('a -> 'a -> int) -> ('key,'a) map -> 'a Pset.set - -val min_binding: ('key,'a) map -> ('key * 'a) - (** Return the smallest binding of the given map - (with respect to the [Ord.compare] ordering), or raise - [Not_found] if the map is empty. - @since 3.12.0 - *) - -val max_binding: ('key,'a) map -> ('key * 'a) - (** Same as {!Map.S.min_binding}, but returns the largest binding - of the given map. - @since 3.12.0 - *) - -val choose: ('key,'a) map -> ('key * 'a) - (** Return one binding of the given map, or raise [Not_found] if - the map is empty. Which binding is chosen is unspecified, - but equal bindings will be chosen for equal maps. - @since 3.12.0 - *) - -val split: 'key -> ('key,'a) map -> ('key,'a) map * 'a option * ('key,'a) map - (** [split x m] returns a triple [(l, data, r)], where - [l] is the map with all the bindings of [m] whose key - is strictly less than [x]; - [r] is the map with all the bindings of [m] whose key - is strictly greater than [x]; - [data] is [None] if [m] contains no binding for [x], - or [Some v] if [m] binds [v] to [x]. - @since 3.12.0 - *) - -val find: 'key -> ('key,'a) map -> 'a - (** [find x m] returns the current binding of [x] in [m], - or raises [Not_found] if no such binding exists. *) - -val lookup: 'key -> ('key,'a) map -> 'a option - (** [lookup x m] returns the current binding of [x] in [m]. In contrast to [find], - it returns [None] instead of raising an exception, if no such binding exists. *) - -val map: ('a -> 'b) -> ('key,'a) map -> ('key,'b) map - (** [map f m] returns a map with same domain as [m], where the - associated value [a] of all bindings of [m] has been - replaced by the result of the application of [f] to [a]. - The bindings are passed to [f] in increasing order - with respect to the ordering over the type of the keys. *) - -val mapi: ('key -> 'a -> 'b) -> ('key,'a) map -> ('key,'b) map - (** Same as {!Map.S.map}, but the function receives as arguments both the - key and the associated value for each binding of the map. *) - -val from_set : ('key -> 'v) -> ('key Pset.set) -> ('key, 'v) map diff --git a/lib/ocaml_rts/linksem/src_lem_library/pset.ml b/lib/ocaml_rts/linksem/src_lem_library/pset.ml deleted file mode 100755 index 35335e88..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/pset.ml +++ /dev/null @@ -1,522 +0,0 @@ -(***********************************************************************) -(* *) -(* Objective Caml *) -(* *) -(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) -(* *) -(* Copyright 1996 Institut National de Recherche en Informatique et *) -(* en Automatique. All rights reserved. This file is distributed *) -(* under the terms of the GNU Library General Public License, with *) -(* the special exception on linking described in file ../LICENSE. *) -(* *) -(***********************************************************************) - -(* Modified by Scott Owens 2010-10-28 *) - -(* $Id: set.ml 6694 2004-11-25 00:06:06Z doligez $ *) - -(* Sets over ordered types *) - -type 'a rep = Empty | Node of 'a rep * 'a * 'a rep * int - -(* Sets are represented by balanced binary trees (the heights of the - children differ by at most 2 *) - -let height = function - Empty -> 0 - | Node(_, _, _, h) -> h - -(* Creates a new node with left son l, value v and right son r. - We must have all elements of l < v < all elements of r. - l and r must be balanced and | height l - height r | <= 2. - Inline expansion of height for better speed. *) - -let create l v r = - let hl = match l with Empty -> 0 | Node(_,_,_,h) -> h in - let hr = match r with Empty -> 0 | Node(_,_,_,h) -> h in - Node(l, v, r, (if hl >= hr then hl + 1 else hr + 1)) - -(* Same as create, but performs one step of rebalancing if necessary. - Assumes l and r balanced and | height l - height r | <= 3. - Inline expansion of create for better speed in the most frequent case - where no rebalancing is required. *) - -let bal l v r = - let hl = match l with Empty -> 0 | Node(_,_,_,h) -> h in - let hr = match r with Empty -> 0 | Node(_,_,_,h) -> h in - if hl > hr + 2 then begin - match l with - Empty -> invalid_arg "Set.bal" - | Node(ll, lv, lr, _) -> - if height ll >= height lr then - create ll lv (create lr v r) - else begin - match lr with - Empty -> invalid_arg "Set.bal" - | Node(lrl, lrv, lrr, _)-> - create (create ll lv lrl) lrv (create lrr v r) - end - end else if hr > hl + 2 then begin - match r with - Empty -> invalid_arg "Set.bal" - | Node(rl, rv, rr, _) -> - if height rr >= height rl then - create (create l v rl) rv rr - else begin - match rl with - Empty -> invalid_arg "Set.bal" - | Node(rll, rlv, rlr, _) -> - create (create l v rll) rlv (create rlr rv rr) - end - end else - Node(l, v, r, (if hl >= hr then hl + 1 else hr + 1)) - -(* Insertion of one element *) - -let rec add cmp x = function - Empty -> Node(Empty, x, Empty, 1) - | Node(l, v, r, _) as t -> - let c = cmp x v in - if c = 0 then t else - if c < 0 then bal (add cmp x l) v r else bal l v (add cmp x r) - -(* Same as create and bal, but no assumptions are made on the - relative heights of l and r. *) - -let rec join cmp l v r = - match (l, r) with - (Empty, _) -> add cmp v r - | (_, Empty) -> add cmp v l - | (Node(ll, lv, lr, lh), Node(rl, rv, rr, rh)) -> - if lh > rh + 2 then bal ll lv (join cmp lr v r) else - if rh > lh + 2 then bal (join cmp l v rl) rv rr else - create l v r - -(* Smallest and greatest element of a set *) - -let rec min_elt = function - Empty -> raise Not_found - | Node(Empty, v, r, _) -> v - | Node(l, v, r, _) -> min_elt l - -let rec max_elt = function - Empty -> raise Not_found - | Node(l, v, Empty, _) -> v - | Node(l, v, r, _) -> max_elt r - -(* Remove the smallest element of the given set *) - -let rec remove_min_elt = function - Empty -> invalid_arg "Set.remove_min_elt" - | Node(Empty, v, r, _) -> r - | Node(l, v, r, _) -> bal (remove_min_elt l) v r - -(* Merge two trees l and r into one. - All elements of l must precede the elements of r. - Assume | height l - height r | <= 2. *) - -let merge t1 t2 = - match (t1, t2) with - (Empty, t) -> t - | (t, Empty) -> t - | (_, _) -> bal t1 (min_elt t2) (remove_min_elt t2) - -(* Merge two trees l and r into one. - All elements of l must precede the elements of r. - No assumption on the heights of l and r. *) - -let concat cmp t1 t2 = - match (t1, t2) with - (Empty, t) -> t - | (t, Empty) -> t - | (_, _) -> join cmp t1 (min_elt t2) (remove_min_elt t2) - -(* Splitting. split x s returns a triple (l, present, r) where - - l is the set of elements of s that are < x - - r is the set of elements of s that are > x - - present is false if s contains no element equal to x, - or true if s contains an element equal to x. *) - -let rec split cmp x = function - Empty -> - (Empty, false, Empty) - | Node(l, v, r, _) -> - let c = cmp x v in - if c = 0 then (l, true, r) - else if c < 0 then - let (ll, pres, rl) = split cmp x l in (ll, pres, join cmp rl v r) - else - let (lr, pres, rr) = split cmp x r in (join cmp l v lr, pres, rr) - -(* Implementation of the set operations *) - -let empty = Empty - -let is_empty = function Empty -> true | _ -> false - -let rec mem cmp x = function - Empty -> false - | Node(l, v, r, _) -> - let c = cmp x v in - c = 0 || mem cmp x (if c < 0 then l else r) - -let singleton x = Node(Empty, x, Empty, 1) - -let rec remove cmp x = function - Empty -> Empty - | Node(l, v, r, _) -> - let c = cmp x v in - if c = 0 then merge l r else - if c < 0 then bal (remove cmp x l) v r else bal l v (remove cmp x r) - -let rec union cmp s1 s2 = - match (s1, s2) with - (Empty, t2) -> t2 - | (t1, Empty) -> t1 - | (Node(l1, v1, r1, h1), Node(l2, v2, r2, h2)) -> - if h1 >= h2 then - if h2 = 1 then add cmp v2 s1 else begin - let (l2, _, r2) = split cmp v1 s2 in - join cmp (union cmp l1 l2) v1 (union cmp r1 r2) - end - else - if h1 = 1 then add cmp v1 s2 else begin - let (l1, _, r1) = split cmp v2 s1 in - join cmp (union cmp l1 l2) v2 (union cmp r1 r2) - end - -let rec inter cmp s1 s2 = - match (s1, s2) with - (Empty, t2) -> Empty - | (t1, Empty) -> Empty - | (Node(l1, v1, r1, _), t2) -> - match split cmp v1 t2 with - (l2, false, r2) -> - concat cmp (inter cmp l1 l2) (inter cmp r1 r2) - | (l2, true, r2) -> - join cmp (inter cmp l1 l2) v1 (inter cmp r1 r2) - -let rec diff cmp s1 s2 = - match (s1, s2) with - (Empty, t2) -> Empty - | (t1, Empty) -> t1 - | (Node(l1, v1, r1, _), t2) -> - match split cmp v1 t2 with - (l2, false, r2) -> - join cmp (diff cmp l1 l2) v1 (diff cmp r1 r2) - | (l2, true, r2) -> - concat cmp (diff cmp l1 l2) (diff cmp r1 r2) - -type 'a enumeration = End | More of 'a * 'a rep * 'a enumeration - -let rec cons_enum s e = - match s with - Empty -> e - | Node(l, v, r, _) -> cons_enum l (More(v, r, e)) - -let rec compare_aux cmp e1 e2 = - match (e1, e2) with - (End, End) -> 0 - | (End, _) -> -1 - | (_, End) -> 1 - | (More(v1, r1, e1), More(v2, r2, e2)) -> - let c = cmp v1 v2 in - if c <> 0 - then c - else compare_aux cmp (cons_enum r1 e1) (cons_enum r2 e2) - -let compare cmp s1 s2 = - compare_aux cmp (cons_enum s1 End) (cons_enum s2 End) - -let equal cmp s1 s2 = - compare cmp s1 s2 = 0 - -let rec subset cmp s1 s2 = - match (s1, s2) with - Empty, _ -> - true - | _, Empty -> - false - | Node (l1, v1, r1, _), (Node (l2, v2, r2, _) as t2) -> - let c = cmp v1 v2 in - if c = 0 then - subset cmp l1 l2 && subset cmp r1 r2 - else if c < 0 then - subset cmp (Node (l1, v1, Empty, 0)) l2 && subset cmp r1 t2 - else - subset cmp (Node (Empty, v1, r1, 0)) r2 && subset cmp l1 t2 - -let rec iter f = function - Empty -> () - | Node(l, v, r, _) -> iter f l; f v; iter f r - -let rec fold f s accu = - match s with - Empty -> accu - | Node(l, v, r, _) -> fold f r (f v (fold f l accu)) - -let map cmp f s = fold (fun e s -> add cmp (f e) s) s empty - -let map_union cmp f s = fold (fun e s -> union cmp (f e) s) s empty - - -let rec for_all p = function - Empty -> true - | Node(l, v, r, _) -> p v && for_all p l && for_all p r - -let rec exists p = function - Empty -> false - | Node(l, v, r, _) -> p v || exists p l || exists p r - -let filter cmp p s = - let rec filt accu = function - | Empty -> accu - | Node(l, v, r, _) -> - filt (filt (if p v then add cmp v accu else accu) l) r in - filt Empty s - -let partition cmp p s = - let rec part (t, f as accu) = function - | Empty -> accu - | Node(l, v, r, _) -> - part (part (if p v then (add cmp v t, f) else (t, add cmp v f)) l) r in - part (Empty, Empty) s - -let rec cardinal = function - Empty -> 0 - | Node(l, v, r, _) -> cardinal l + 1 + cardinal r - -let rec elements_aux accu = function - Empty -> accu - | Node(l, v, r, _) -> elements_aux (v :: elements_aux accu r) l - -let elements s = - elements_aux [] s - -let choose = min_elt - -type 'a set = { cmp : 'a -> 'a -> int; s : 'a rep } - -let empty c = { cmp = c; s = Empty; } - -let is_empty s = is_empty s.s - -let mem x s = mem s.cmp x s.s - -let add x s = { s with s = add s.cmp x s.s } - -let singleton c x = { cmp = c; s = singleton x } - -let remove x s = { s with s = remove s.cmp x s.s } - -let union s1 s2 = { s1 with s = union s1.cmp s1.s s2.s } - -let map_union c f s1 = { cmp = c; s = map_union c (fun x -> (f x).s) s1.s} - -let inter s1 s2 = { s1 with s = inter s1.cmp s1.s s2.s } - -let diff s1 s2 = { s1 with s = diff s1.cmp s1.s s2.s } - -let compare_by cmp s1 s2 = compare cmp s1.s s2.s - -let compare s1 s2 = compare s1.cmp s1.s s2.s - -let equal s1 s2 = equal s1.cmp s1.s s2.s - -let subset s1 s2 = subset s1.cmp s1.s s2.s -let subset_proper s1 s2 = (subset s1 s2) && not (equal s1 s2) - -let iter f s = iter f s.s - -let fold f s a = fold f s.s a - -let map c f s = {cmp = c; s = map c f s.s} - -let for_all p s = for_all p s.s - -let exists p s = exists p s.s - -let filter p s = { s with s = filter s.cmp p s.s } - -let partition p s = - let (r1,r2) = partition s.cmp p s.s in - ({s with s = r1}, {s with s = r2}) - -let cardinal s = cardinal s.s - -let elements s = elements s.s - -let min_elt s = min_elt s.s - -let min_elt_opt s = try Some (min_elt s) with Not_found -> None - -let max_elt s = max_elt s.s - -let max_elt_opt s = try Some (max_elt s) with Not_found -> None - -let choose s = choose s.s - -let set_case s c_emp c_sing c_else = match s.s with - Empty -> c_emp - | Node(Empty, v, Empty, _) -> c_sing v - | _ -> c_else - -let split x s = - let (l,present,r) = split s.cmp x s.s in - ({ s with s = l }, present, { s with s = r }) - -let from_list c l = - List.fold_left (fun s x -> add x s) (empty c) l - -let comprehension1 cmp f p s = - fold (fun x s -> if p x then add (f x) s else s) s (empty cmp) - -let comprehension2 cmp f p s1 s2 = - fold - (fun x1 s -> - fold - (fun x2 s -> - if p x1 x2 then add (f x1 x2) s else s) - s2 - s) - s1 - (empty cmp) - -let comprehension3 cmp f p s1 s2 s3 = - fold - (fun x1 s -> - fold - (fun x2 s -> - fold - (fun x3 s -> - if p x1 x2 x3 then add (f x1 x2 x3) s else s) - s3 - s) - s2 - s) - s1 - (empty cmp) - -let comprehension4 cmp f p s1 s2 s3 s4 = - fold - (fun x1 s -> - fold - (fun x2 s -> - fold - (fun x3 s -> - fold - (fun x4 s -> - if p x1 x2 x3 x4 then add (f x1 x2 x3 x4) s else s) - s4 - s) - s3 - s) - s2 - s) - s1 - (empty cmp) - -let comprehension5 cmp f p s1 s2 s3 s4 s5 = - fold - (fun x1 s -> - fold - (fun x2 s -> - fold - (fun x3 s -> - fold - (fun x4 s -> - fold - (fun x5 s -> - if p x1 x2 x3 x4 x5 then add (f x1 x2 x3 x4 x5) s else s) - s5 - s) - s4 - s) - s3 - s) - s2 - s) - s1 - (empty cmp) - -let comprehension6 cmp f p s1 s2 s3 s4 s5 s6 = - fold - (fun x1 s -> - fold - (fun x2 s -> - fold - (fun x3 s -> - fold - (fun x4 s -> - fold - (fun x5 s -> - fold - (fun x6 s -> - if p x1 x2 x3 x4 x5 x6 then add (f x1 x2 x3 x4 x5 x6) s else s) - s6 - s) - s5 - s) - s4 - s) - s3 - s) - s2 - s) - s1 - (empty cmp) - -let comprehension7 cmp f p s1 s2 s3 s4 s5 s6 s7 = - fold - (fun x1 s -> - fold - (fun x2 s -> - fold - (fun x3 s -> - fold - (fun x4 s -> - fold - (fun x5 s -> - fold - (fun x6 s -> - fold - (fun x7 s -> - if p x1 x2 x3 x4 x5 x6 x7 then add (f x1 x2 x3 x4 x5 x6 x7) s else s) - s7 - s) - s6 - s) - s5 - s) - s4 - s) - s3 - s) - s2 - s) - s1 - (empty cmp) - -let bigunion c xss = - fold union xss (empty c) - -let sigma c xs ys = - fold (fun x xys -> fold (fun y xys -> add (x,y) xys) (ys x) xys) xs (empty c) - -let cross c xs ys = sigma c xs (fun _ -> ys) - -let rec lfp s f = - let s' = f s in - if subset s' s then - s - else - lfp (union s' s) f - -let tc c r = - let one_step r = fold (fun (x,y) xs -> fold (fun (y',z) xs -> - if c (y,y) (y',y') = 0 then add (x,z) xs else xs) r xs) r (empty c) in - lfp r one_step - - -let get_elem_compare s = s.cmp - diff --git a/lib/ocaml_rts/linksem/src_lem_library/pset.mli b/lib/ocaml_rts/linksem/src_lem_library/pset.mli deleted file mode 100755 index 162d5f3b..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/pset.mli +++ /dev/null @@ -1,174 +0,0 @@ -(***********************************************************************) -(* *) -(* Objective Caml *) -(* *) -(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) -(* *) -(* Copyright 1996 Institut National de Recherche en Informatique et *) -(* en Automatique. All rights reserved. This file is distributed *) -(* under the terms of the GNU Library General Public License, with *) -(* the special exception on linking described in file ../LICENSE. *) -(* *) -(***********************************************************************) - -(* Modified by Scott Owens 2010-10-28 *) - -(* $Id: set.mli 6974 2005-07-21 14:52:45Z doligez $ *) - -(** Sets over ordered types. - - This module implements the set data structure, given a total ordering - function over the set elements. All operations over sets - are purely applicative (no side-effects). - The implementation uses balanced binary trees, and is therefore - reasonably efficient: insertion and membership take time - logarithmic in the size of the set, for instance. - *) - -type 'a set -(** The type of sets. *) - -val empty: ('a -> 'a -> int) -> 'a set -(** The empty set. *) - -val is_empty: 'a set -> bool -(** Test whether a set is empty or not. *) - -val from_list: ('a -> 'a -> int) -> 'a list -> 'a set - -val mem: 'a -> 'a set -> bool -(** [mem x s] tests whether [x] belongs to the set [s]. *) - -val add: 'a -> 'a set -> 'a set -(** [add x s] returns a set containing all elements of [s], - plus [x]. If [x] was already in [s], [s] is returned unchanged. *) - -val singleton: ('a -> 'a -> int) -> 'a -> 'a set -(** [singleton x] returns the one-element set containing only [x]. *) - -val remove: 'a -> 'a set -> 'a set -(** [remove x s] returns a set containing all elements of [s], - except [x]. If [x] was not in [s], [s] is returned unchanged. *) - -val union: 'a set -> 'a set -> 'a set -(** Set union. *) - -val inter: 'a set -> 'a set -> 'a set -(** Set intersection. *) - -(** Set difference. *) -val diff: 'a set -> 'a set -> 'a set - -val compare: 'a set -> 'a set -> int -(** Total ordering between sets. Can be used as the ordering function - for doing sets of sets. *) - -val equal: 'a set -> 'a set -> bool -(** [equal s1 s2] tests whether the sets [s1] and [s2] are - equal, that is, contain equal elements. *) - -val subset: 'a set -> 'a set -> bool -(** [subset s1 s2] tests whether the set [s1] is a subset of - the set [s2]. This includes the case where [s1] and [s2] are equal. *) - -val subset_proper : 'a set -> 'a set -> bool -(** [subset_proper s1 s2] tests whether the set [s1] is a proper subset of - the set [s2]. *) - -val iter: ('a -> unit) -> 'a set -> unit -(** [iter f s] applies [f] in turn to all elements of [s]. - The elements of [s] are presented to [f] in increasing order - with respect to the ordering over the type of the elements. *) - -val fold: ('a -> 'b -> 'b) -> 'a set -> 'b -> 'b -(** [fold f s a] computes [(f xN ... (f x2 (f x1 a))...)], - where [x1 ... xN] are the elements of [s], in increasing order. *) - -val map: ('b -> 'b -> int) -> ('a -> 'b) -> 'a set -> 'b set - -val map_union: ('b -> 'b -> int) -> ('a -> 'b set) -> 'a set -> 'b set -(** [map_union cmp f s] does the same as [bigunion cmp (map cmp' f s)]. - Because the set of sets is internally not constructed though the comparison function [cmp'] is - not needed. *) - -val for_all: ('a -> bool) -> 'a set -> bool -(** [for_all p s] checks if all elements of the set - satisfy the predicate [p]. *) - -val exists: ('a -> bool) -> 'a set -> bool -(** [exists p s] checks if at least one element of - the set satisfies the predicate [p]. *) - -val filter: ('a -> bool) -> 'a set -> 'a set -(** [filter p s] returns the set of all elements in [s] - that satisfy predicate [p]. *) - -val partition: ('a -> bool) -> 'a set -> 'a set * 'a set -(** [partition p s] returns a pair of sets [(s1, s2)], where - [s1] is the set of all the elements of [s] that satisfy the - predicate [p], and [s2] is the set of all the elements of - [s] that do not satisfy [p]. *) - -val cardinal: 'a set -> int -(** Return the number of elements of a set. *) - -val elements: 'a set -> 'a list -(** Return the list of all elements of the given set. - The returned list is sorted in increasing order with respect - to the ordering [Ord.compare], where [Ord] is the argument - given to {!Set.Make}. *) - -val min_elt: 'a set -> 'a -(** Return the smallest element of the given set - (with respect to the [Ord.compare] ordering), or raise - [Not_found] if the set is empty. *) - -val max_elt: 'a set -> 'a -(** Same as {!Set.S.min_elt}, but returns the largest element of the - given set. *) - -val min_elt_opt: 'a set -> 'a option -(** an optional version of [min_elt] *) - -val max_elt_opt: 'a set -> 'a option -(** an optional version of [max_elt] *) - -val choose: 'a set -> 'a -(** Return one element of the given set, or raise [Not_found] if - the set is empty. Which element is chosen is unspecified, - but equal elements will be chosen for equal sets. *) - -val set_case: 'a set -> 'b -> ('a -> 'b) -> 'b -> 'b -(** case-split function for sets *) - -val split: 'a -> 'a set -> 'a set * bool * 'a set - (** [split x s] returns a triple [(l, present, r)], where - [l] is the set of elements of [s] that are - strictly less than [x]; - [r] is the set of elements of [s] that are - strictly greater than [x]; - [present] is [false] if [s] contains no element equal to [x], - or [true] if [s] contains an element equal to [x]. *) - -val comprehension1 : ('b -> 'b -> int) -> ('a -> 'b) -> ('a -> bool) -> 'a set -> 'b set -val comprehension2 : ('c -> 'c -> int) -> ('a -> 'b -> 'c) -> ('a -> 'b -> bool) -> 'a set -> 'b set -> 'c set -val comprehension3 : ('d -> 'd -> int) -> ('a -> 'b -> 'c -> 'd) -> ('a -> 'b -> 'c -> bool) -> 'a set -> 'b set -> 'c set -> 'd set -val comprehension4 : ('e -> 'e -> int) -> ('a -> 'b -> 'c -> 'd -> 'e) -> ('a -> 'b -> 'c -> 'd -> bool) -> 'a set -> 'b set -> 'c set -> 'd set -> 'e set -val comprehension5 : ('f -> 'f -> int) -> ('a -> 'b -> 'c -> 'd -> 'e -> 'f) -> ('a -> 'b -> 'c -> 'd -> 'e -> bool) -> 'a set -> 'b set -> 'c set -> 'd set -> 'e set -> 'f set -val comprehension6 : ('g -> 'g -> int) -> ('a -> 'b -> 'c -> 'd -> 'e -> 'f -> 'g) -> ('a -> 'b -> 'c -> 'd -> 'e -> 'f -> bool) -> 'a set -> 'b set -> 'c set -> 'd set -> 'e set -> 'f set -> 'g set -val comprehension7 : ('h -> 'h -> int) -> ('a -> 'b -> 'c -> 'd -> 'e -> 'f -> 'g -> 'h) -> ('a -> 'b -> 'c -> 'd -> 'e -> 'f -> 'g -> bool) -> 'a set -> 'b set -> 'c set -> 'd set -> 'e set -> 'f set -> 'g set -> 'h set - -val bigunion : ('a -> 'a -> int) -> 'a set set -> 'a set - -val lfp : 'a set -> ('a set -> 'a set) -> 'a set -val tc : ('a * 'a -> 'a * 'a -> int) -> ('a * 'a) set -> ('a * 'a) set - - -val sigma : ('a * 'b -> 'a * 'b -> int) -> 'a set -> ('a -> 'b set) -> ('a * 'b) set -val cross : ('a * 'b -> 'a * 'b -> int) -> 'a set -> 'b set -> ('a * 'b) set - -val get_elem_compare : 'a set -> ('a -> 'a -> int) - -val compare_by: ('a->'a->int) -> 'a set -> 'a set -> int -(** set comparison parameterised by element comparison (ignoring the comparison functions of the argument sets*) - diff --git a/lib/ocaml_rts/linksem/src_lem_library/pset_using_lists.ml b/lib/ocaml_rts/linksem/src_lem_library/pset_using_lists.ml deleted file mode 100644 index 1fadd8f7..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/pset_using_lists.ml +++ /dev/null @@ -1,336 +0,0 @@ -(***********************************************************************) -(* *) -(* Objective Caml *) -(* *) -(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) -(* *) -(* Copyright 1996 Institut National de Recherche en Informatique et *) -(* en Automatique. All rights reserved. This file is distributed *) -(* under the terms of the GNU Library General Public License, with *) -(* the special exception on linking described in file ../LICENSE. *) -(* *) -(***********************************************************************) - -(* Modified by Scott Owens 2010-10-28 *) -(* Modified by Kyndylan Nienhuis 2013-04-.. *) - -(* $Id: set.ml 6694 2004-11-25 00:06:06Z doligez $ *) - -(* Sets over ordered types *) - - - -(* Implementation of the set operations *) - -type 'a rep = 'a list - -exception Not_implemented - -let rec add cmp x list = - x::list - -let empty = [] - -let is_empty = function [] -> true | _ -> false - -let rec mem cmp x = function - [] -> false - | v::l -> - let c = cmp x v in - c = 0 || mem cmp x l - -let singleton x = [x] - -let rec remove cmp x = function - [] -> [] - | v::l -> - let c = cmp x v in - if c = 0 then remove cmp x l else - v::(remove cmp x l) - -let compare cmp s1 s2 = - raise Not_implemented - -let equal cmp s1 s2 = - compare cmp s1 s2 = 0 - -let rec iter f = function - [] -> () - | v::l -> iter f l; f v - -let rec fold f s accu = - match s with - [] -> accu - | v::l -> f v (fold f l accu) - -let map cmp f s = fold (fun e s -> add cmp (f e) s) s empty - -let rec for_all p = function - [] -> true - | v::l -> p v && for_all p l - -let rec exists p = function - [] -> false - | v::l -> p v || exists p l - -let rec subset cmp s1 s2 = - for_all (fun e -> mem cmp e s2) s1 - -let filter cmp p s = - let rec filt accu = function - | [] -> accu - | v::r -> - filt (if p v then add cmp v accu else accu) r in - filt [] s - -let partition cmp p s = - let rec part (l, r as accu) = function - | [] -> accu - | h::t -> - part (if p h then (add cmp h l, r) else (l, add cmp h r)) t in - part ([], []) s - -let rec union cmp s1 s2 = - match s1 with - [] -> s2 - | v::l -> v::(union cmp l s2) - -let rec inter cmp s1 s2 = - filter cmp (fun e -> mem cmp e s2) s1 - -let rec cardinal cmp = function - [] -> 0 - | h::t -> (cardinal cmp (remove cmp h t)) + 1 - -let elements s = - s - -let diff cmp s s = - raise Not_implemented - -let min_elt s = - raise Not_implemented - -let max_elt s = - raise Not_implemented - -let split cmp x s = - raise Not_implemented - -(* It's not determenistic in the sense that s1.choose = s2.choose given that s1 equals s2 *) -let choose = function - [] -> raise Not_found - | h::_ -> h - -type 'a set = { cmp : 'a -> 'a -> int; s : 'a rep } - -let empty c = { cmp = c; s = []; } - -let is_empty s = is_empty s.s - -let mem x s = mem s.cmp x s.s - -let add x s = { s with s = add s.cmp x s.s } - -let singleton c x = { cmp = c; s = singleton x } - -let remove x s = { s with s = remove s.cmp x s.s } - -let union s1 s2 = { s1 with s = union s1.cmp s1.s s2.s } - -let inter s1 s2 = { s1 with s = inter s1.cmp s1.s s2.s } - -let diff s1 s2 = { s1 with s = diff s1.cmp s1.s s2.s } - -let compare s1 s2 = compare s1.cmp s1.s s2.s - -let equal s1 s2 = equal s1.cmp s1.s s2.s - -let subset s1 s2 = subset s1.cmp s1.s s2.s - -let iter f s = iter f s.s - -let fold f s a = fold f s.s a - -let map c f s = {cmp = c; s = map c f s.s} - -let for_all p s = for_all p s.s - -let exists p s = exists p s.s - -let filter p s = { s with s = filter s.cmp p s.s } - -let partition p s = - let (r1,r2) = partition s.cmp p s.s in - ({s with s = r1}, {s with s = r2}) - -let cardinal s = cardinal s.cmp s.s - -let elements s = elements s.s - -let min_elt s = min_elt s.s - -let max_elt s = max_elt s.s - -let choose s = choose s.s - -let split x s = - let (l,present,r) = split s.cmp x s.s in - ({ s with s = l }, present, { s with s = r }) - -let from_list c l = - {cmp = c; s = l} - -let comprehension1 cmp f p s = - fold (fun x s -> if p x then add (f x) s else s) s (empty cmp) - -let comprehension2 cmp f p s1 s2 = - fold - (fun x1 s -> - fold - (fun x2 s -> - if p x1 x2 then add (f x1 x2) s else s) - s2 - s) - s1 - (empty cmp) - -let comprehension3 cmp f p s1 s2 s3 = - fold - (fun x1 s -> - fold - (fun x2 s -> - fold - (fun x3 s -> - if p x1 x2 x3 then add (f x1 x2 x3) s else s) - s3 - s) - s2 - s) - s1 - (empty cmp) - -let comprehension4 cmp f p s1 s2 s3 s4 = - fold - (fun x1 s -> - fold - (fun x2 s -> - fold - (fun x3 s -> - fold - (fun x4 s -> - if p x1 x2 x3 x4 then add (f x1 x2 x3 x4) s else s) - s4 - s) - s3 - s) - s2 - s) - s1 - (empty cmp) - -let comprehension5 cmp f p s1 s2 s3 s4 s5 = - fold - (fun x1 s -> - fold - (fun x2 s -> - fold - (fun x3 s -> - fold - (fun x4 s -> - fold - (fun x5 s -> - if p x1 x2 x3 x4 x5 then add (f x1 x2 x3 x4 x5) s else s) - s5 - s) - s4 - s) - s3 - s) - s2 - s) - s1 - (empty cmp) - -let comprehension6 cmp f p s1 s2 s3 s4 s5 s6 = - fold - (fun x1 s -> - fold - (fun x2 s -> - fold - (fun x3 s -> - fold - (fun x4 s -> - fold - (fun x5 s -> - fold - (fun x6 s -> - if p x1 x2 x3 x4 x5 x6 then add (f x1 x2 x3 x4 x5 x6) s else s) - s6 - s) - s5 - s) - s4 - s) - s3 - s) - s2 - s) - s1 - (empty cmp) - -let comprehension7 cmp f p s1 s2 s3 s4 s5 s6 s7 = - fold - (fun x1 s -> - fold - (fun x2 s -> - fold - (fun x3 s -> - fold - (fun x4 s -> - fold - (fun x5 s -> - fold - (fun x6 s -> - fold - (fun x7 s -> - if p x1 x2 x3 x4 x5 x6 x7 then add (f x1 x2 x3 x4 x5 x6 x7) s else s) - s7 - s) - s6 - s) - s5 - s) - s4 - s) - s3 - s) - s2 - s) - s1 - (empty cmp) - -let bigunion c xss = - fold union xss (empty c) - -let rec lfp s f = - let s' = f s in - if subset s' s then - s - else - lfp (union s' s) f - -let cross c xs ys = - fold (fun x xys -> fold (fun y xys -> add (x,y) xys) ys xys) xs (empty c) - -let rec lfp s f = - let s' = f s in - if subset s' s then - s - else - lfp (union s' s) f - -let tc c r = - let one_step r = fold (fun (x,y) xs -> fold (fun (y',z) xs -> - if y = y' then add (x,z) xs else xs) r xs) r (empty c) in - lfp r one_step diff --git a/lib/ocaml_rts/linksem/src_lem_library/sum.ml b/lib/ocaml_rts/linksem/src_lem_library/sum.ml deleted file mode 100644 index a9ea35ae..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/sum.ml +++ /dev/null @@ -1,4 +0,0 @@ -type ('a, 'b) sum = - | Inl of ('a) - | Inr of ('b) - diff --git a/lib/ocaml_rts/linksem/src_lem_library/vector.ml b/lib/ocaml_rts/linksem/src_lem_library/vector.ml deleted file mode 100644 index ff9ddb24..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/vector.ml +++ /dev/null @@ -1,35 +0,0 @@ -open Nat_num - -type 'a vector = Vector of 'a array - -let vconcat (Vector a) (Vector b) = Vector(Array.append a b) - -let vmap f (Vector a) = Vector(Array.map f a) - -let vfold f base (Vector a) = Array.fold_left f base a - -let vzip (Vector a) (Vector b) = - Vector( Array.of_list (List.combine (Array.to_list a) (Array.to_list b))) - -let vmapacc f (Vector a) base = - let rec mapacc vl b = match vl with - | [] -> ([],b) - | v::vl -> let (v',b') = f v b in - let (vl',b'') = mapacc vl b' in - (v'::vl',b'') in - let vls,b = mapacc (Array.to_list a) base in - Vector(Array.of_list vls),b - -let vmapi f (Vector a) = Vector(Array.mapi f a) - -let extend default size (Vector a) = Vector(Array.append (Array.make size default) a) - -let duplicate (Vector a) = Vector(Array.append a (Array.copy a)) - -let vlength (Vector a) = Array.length a - -let vector_access n (Vector a) = a.(n) - -let vector_slice n1 n2 (Vector a) = Vector(Array.sub a n1 n2) - -let make_vector vs l = Vector(Array.of_list vs)
\ No newline at end of file diff --git a/lib/ocaml_rts/linksem/src_lem_library/vector.mli b/lib/ocaml_rts/linksem/src_lem_library/vector.mli deleted file mode 100644 index fbbe11ab..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/vector.mli +++ /dev/null @@ -1,28 +0,0 @@ -open Nat_num - -type 'a vector = Vector of 'a array - -val vconcat : 'a vector -> 'a vector -> 'a vector - -val vmap : ('a ->'b) -> 'a vector -> 'b vector - -val vfold : ('b -> 'a -> 'b) -> 'b -> 'a vector -> 'b - -val vzip : 'a vector -> 'b vector -> ('a * 'b) vector - -val vmapacc : ('a -> 'c -> ('b * 'c)) -> 'a vector -> 'c -> ('b vector) * 'c - -val vmapi : (nat -> 'a -> 'b) -> 'a vector -> 'b vector - -val extend : 'a -> nat -> 'a vector -> 'a vector - -val duplicate : 'a vector -> 'a vector - -val vlength : 'a vector -> nat - -val vector_access : nat ->'a vector -> 'a - -val vector_slice : nat -> nat ->'a vector -> 'a vector - -val make_vector : 'a list -> nat -> 'a vector - diff --git a/lib/ocaml_rts/linksem/src_lem_library/xstring.ml b/lib/ocaml_rts/linksem/src_lem_library/xstring.ml deleted file mode 100644 index 7a705aeb..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/xstring.ml +++ /dev/null @@ -1,22 +0,0 @@ -let explode s = - let rec exp i l = - if i < 0 then l else exp (i - 1) (s.[i] :: l) in - exp (String.length s - 1) [];; - -let implode l = - let res = String.create (List.length l) in - let rec imp i = function - | [] -> res - | c :: l -> res.[i] <- c; imp (i + 1) l in - imp 0 l;; - -let string_case s c_empty c_cons = begin - let len = String.length s in - if (len = 0) then c_empty else - c_cons (String.get s 0) (String.sub s 1 (len - 1)) -end;; - -let cons_string c s = begin - let cs = String.make 1 c in - cs ^ s -end;; diff --git a/lib/ocaml_rts/linksem/src_lem_library/xstring.mli b/lib/ocaml_rts/linksem/src_lem_library/xstring.mli deleted file mode 100644 index aa9182d7..00000000 --- a/lib/ocaml_rts/linksem/src_lem_library/xstring.mli +++ /dev/null @@ -1,4 +0,0 @@ -val explode : string -> char list -val implode : char list -> string -val cons_string : char -> string -> string -val string_case : string -> 'a -> (char -> string -> 'a) -> 'a diff --git a/lib/ocaml_rts/linksem/string_table.ml b/lib/ocaml_rts/linksem/string_table.ml deleted file mode 100644 index fc74e323..00000000 --- a/lib/ocaml_rts/linksem/string_table.ml +++ /dev/null @@ -1,123 +0,0 @@ -(*Generated by Lem from string_table.lem.*) -(** The [string_table] module implements string tables. An ELF file may have - * multiple different string tables used for different purposes. A string - * table is a string coupled with a delimiting character. Strings may be indexed - * at any position, not necessarily on a delimiter boundary. - *) - -open Lem_basic_classes -open Lem_list -open Lem_maybe -open Lem_num -open Lem_string -open Byte_sequence - -open Error -open Missing_pervasives -open Show - -(** [string_table] type, represents a string table with a fixed delimiting - * character and underlying string. - *) -type string_table - = Strings of (char * string) - -(** [mk_string_table base sep] constructs a string table using [base] as the - * base string and [sep] as the delimiting character to use to split [base] - * when trying to access the string stored in the table using the functions below. - *) -(*val mk_string_table : string -> char -> string_table*) -let mk_string_table base sep:string_table= - (Strings (sep, base)) - -(** [string_table_of_byte_sequence seq] constructs a string table, using the NUL - * character as terminator, from a byte sequence. *) -(*val string_table_of_byte_sequence : byte_sequence -> string_table*) -let string_table_of_byte_sequence seq:string_table= (mk_string_table (string_of_byte_sequence seq) null_char) - -(** [empty] is the empty string table with an arbitrary choice of delimiter. - *) -(*val empty : string_table*) -let empty0:string_table= (Strings (null_char, Xstring.implode [null_char])) - -(** [get_delimiating_character tbl] returns the delimiting character associated - * with the string table [tbl], used to split the strings. - *) -(*val get_delimiting_character : string_table -> char*) -let get_delimiting_character tbl:char= - ((match tbl with - | Strings (sep, base) -> sep - )) - -(** [get_base_string tbl] returns the base string of the string table [tbl]. - *) -(*val get_base_string : string_table -> string*) -let get_base_string tbl:string= - ((match tbl with - | Strings (sep, base) -> base - )) - -(** [size tbl] returns the size in bytes of the string table [tbl]. - *) -(*val size : string_table -> natural*) -let size0 tbl:Nat_big_num.num= (Nat_big_num.of_int (String.length (get_base_string tbl))) - -(** [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 concat1 xs:(string_table)error= - ((match xs with - | [] -> return empty0 - | x::xs -> - let delim = (get_delimiting_character x) in - if (List.for_all (fun x -> get_delimiting_character x = delim) (x::xs)) then - let base = (List.fold_right (^) (Lem_list.map get_base_string (x::xs)) "") in - return (mk_string_table base delim) - else - fail "concat: string tables must have same delimiting characters" - )) - -(** [get_string_at index tbl] returns the string starting at character [index] - * from the start of the base string until the first occurrence of the delimiting - * character. - *) -(*val get_string_at : natural -> string_table -> error string*) -let get_string_at index tbl:(string)error= - ((match Ml_bindings.string_suffix index (get_base_string tbl) with - | None -> Fail "get_string_at: index out of range" - | Some suffix -> - let delim = (get_delimiting_character tbl) in - (match Ml_bindings.string_index_of delim suffix with - | Some idx1 -> - (match Ml_bindings.string_prefix idx1 suffix with - | Some s -> Success s - | None -> Fail "get_string_at: index out of range" - ) - | None -> Success suffix - ) - )) - -(*val find_string : string -> string_table -> maybe natural*) -let find_string s t:(Nat_big_num.num)option= - ((match t with - Strings(delim, base) -> Ml_bindings.find_substring (s ^ Xstring.implode [delim]) base - )) - -(*val insert_string : string -> string_table -> (natural * string_table)*) -let insert_string s t:Nat_big_num.num*string_table= -( - (*let _ = errln ("Inserting string `" ^ s ^ "' into a string table") in*)let (inserted_idx, new_strtab) = ((match find_string s t with - None -> (match t with - Strings(delim, base) -> (Nat_big_num.of_int (String.length base), Strings(delim, (base ^ (s ^ (Xstring.implode [delim]))))) - ) - | Some pos -> (pos, t) - )) - in - (*let _ = errln ("Inserted string at idx " ^ (show inserted_idx) ^ ", see: " ^ (show (find_string s new_strtab))) - in*) - (inserted_idx, new_strtab)) - -let instance_Show_Show_String_table_string_table_dict:(string_table)show_class= ({ - - show_method = (fun tbl->Xstring.implode (Lem_list.map (fun c -> if c = '\000' then '\n' else c) (Xstring.explode (get_base_string tbl))))}) diff --git a/lib/ocaml_rts/linksem/test_image.ml b/lib/ocaml_rts/linksem/test_image.ml deleted file mode 100644 index f4a647e4..00000000 --- a/lib/ocaml_rts/linksem/test_image.ml +++ /dev/null @@ -1,146 +0,0 @@ -(*Generated by Lem from test_image.lem.*) -open Lem_basic_classes -open Lem_list -open Lem_map -open Lem_maybe -open Lem_set -open Missing_pervasives -open Lem_num - -open Lem_assert_extra - -open Error -open Elf64_file_of_elf_memory_image - -open Elf_relocation -open Elf_header -open Elf_file -open Elf_interpreted_segment -open Elf_program_header_table -open Elf_symbol_table -open Elf_types_native_uint - -open Abi_amd64_relocation -open Abis - -open Elf_memory_image -open Memory_image - -open Command_line -open Input_list -open Linkable_list -open Byte_sequence -open Link - -open Show - -let ref_rec:symbol_reference= ({ ref_symname = "test" (* symbol name *) - ; ref_syment = -({ elf64_st_name = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_st_info = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_st_other = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_st_shndx = (Uint32.of_string (Nat_big_num.to_string shn_undef)) - ; elf64_st_value = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_st_size = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - }) - ; ref_sym_scn =(Nat_big_num.of_int 0) - ; ref_sym_idx =(Nat_big_num.of_int 0) - }) - -(* the record representing the symbol reference and relocation site *) -let ref_and_reloc_rec:symbol_reference_and_reloc_site= - ({ - ref = ref_rec - ; maybe_def_bound_to = None - ; maybe_reloc = (Some( - { - ref_relent = - ({ elf64_ra_offset = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_ra_info = (Uint64.of_string (Nat_big_num.to_string r_x86_64_32)) - ; elf64_ra_addend = (Nat_big_num.to_int64(Nat_big_num.of_int 0)) - }) - ; ref_rel_scn =(Nat_big_num.of_int 0) - ; ref_rel_idx =(Nat_big_num.of_int 0) - ; ref_src_scn =(Nat_big_num.of_int 0) - } - )) - }) - -let def_rec:symbol_definition= - ({ def_symname = "test" - ; def_syment = ({ elf64_st_name = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_st_info = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_st_other = (Uint32.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_st_shndx = (Uint32.of_string (Nat_big_num.to_string shn_undef)) - ; elf64_st_value = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - ; elf64_st_size = (Uint64.of_string (Nat_big_num.to_string (Nat_big_num.of_int 0))) - }) - ; def_sym_scn =(Nat_big_num.of_int 0) - ; def_sym_idx =(Nat_big_num.of_int 1) - ; def_linkable_idx =(Nat_big_num.of_int 0) - }) - -(*val meta : nat -> list ((maybe element_range) * elf_range_tag)*) -let meta offset:((string*(Nat_big_num.num*Nat_big_num.num))option*(any_abi_feature)range_tag)list= ([ - (Some (".text", (Nat_big_num.of_int 1,Nat_big_num.of_int 4)), SymbolRef(ref_and_reloc_rec)) - ; (Some (".data", (Nat_big_num.of_int offset,Nat_big_num.of_int 8)), SymbolDef(def_rec)) -]) - - -let img0 (addr : int) (data_size : int) instr_bytes:(any_abi_feature)annotated_memory_image= - (let initial_img = - ({ - elements = (Lem_map.fromList - (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) [(".text", { - startpos = (Some(Nat_big_num.of_int 4194304)) - ; length1 = (Some(Nat_big_num.of_int 16)) - ; contents = (Lem_list.map (fun x -> Some x) instr_bytes) - }); - (".data", { - startpos = (Some(Nat_big_num.of_int 4194320)) - ; length1 = (Some (Nat_big_num.of_int data_size)) - ; contents = (Lem_list.map (fun x -> Some x) (Lem_list.replicate data_size (Char.chr (Nat_big_num.to_int (Nat_big_num.of_int 42))))) - }) - ]) - ; by_range = (Pset.from_list (pairCompare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))) compare) (meta ( Nat_num.nat_monus addr( 4194316)))) - ; by_tag = (by_tag_from_by_range - (instance_Basic_classes_SetType_Maybe_maybe_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_var_dict - (instance_Basic_classes_SetType_tup2_dict - instance_Basic_classes_SetType_Num_natural_dict - instance_Basic_classes_SetType_Num_natural_dict))) instance_Basic_classes_SetType_var_dict ((Pset.from_list (pairCompare (maybeCompare (pairCompare compare (pairCompare Nat_big_num.compare Nat_big_num.compare))) compare) (meta ( Nat_num.nat_monus addr( 4194316)))))) - }) - in - let ref_input_item - = ("test.o", Reloc(Sequence([])), ((File(Filename("blah"), Command_line.null_input_file_options)), [InCommandLine(Nat_big_num.of_int 0)])) - in - let ref_linkable_item = (RelocELF(initial_img), ref_input_item, Input_list.null_input_options) - in - let bindings_by_name = (Lem_map.fromList - (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) [ - ("test", [(Nat_big_num.of_int 0, ((Nat_big_num.of_int 0, ref_rec, ref_linkable_item), Some(Nat_big_num.of_int 0, def_rec, ref_linkable_item)))]) - ]) - in - relocate_output_image Abis.sysv_amd64_std_abi bindings_by_name initial_img) - -(* XXX: DPM, no longer needed? -let compute_relocated_bytes () = - let res = - let relocatable_program = - List.map byte_of_natural [72; 199; 4; 37; 0; 0; 0; 0; 5; 0; 0; 0; 72; 139; 4; 37; 0; 0; 0; 0] - in - let ef = elf64_file_of_elf_memory_image sysv_amd64_std_abi id "at_least_some_relocations_relocate.out" (img relocatable_program) in - get_elf64_executable_image ef >>= fun (segs_and_provenance, entry, mach) -> - if mach = elf_ma_x86_64 then - let filtered = List.filter (fun x -> x.elf64_segment_type = elf_pt_load) (List.map (fun (x, y) -> x) segs_and_provenance) in - let filtered = List.map Byte_sequence.byte_list_of_byte_sequence (List.map (fun x -> x.elf64_segment_body) filtered) in - let _ = List.map (fun x -> outln (show x)) filtered in - return () - else - failwith "wrong machine type returned" - in match res with - | Success s -> outln "success" - | Fail e -> errln e - end -*) diff --git a/lib/ocaml_rts/linksem/uint16_wrapper.ml b/lib/ocaml_rts/linksem/uint16_wrapper.ml deleted file mode 100644 index 0b26a5c3..00000000 --- a/lib/ocaml_rts/linksem/uint16_wrapper.ml +++ /dev/null @@ -1,48 +0,0 @@ -type uint16 = Big_int.big_int - -(* 2^16 - 1 *) -let max_int = Big_int.big_int_of_string "65535" -;; - -let of_bigint (i : Big_int.big_int) = - Big_int.mod_big_int i max_int -;; - -let to_bigint (u : uint16) = u -;; - -let shift_left i s = - Big_int.mod_big_int (Big_int.shift_left_big_int i s) max_int -;; - -let shift_right i s = - Big_int.mod_big_int (Big_int.shift_right_big_int i s) max_int -;; - -let logand l r = - Big_int.mod_big_int (Big_int.and_big_int l r) max_int -;; - -let logor l r = - Big_int.mod_big_int (Big_int.or_big_int l r) max_int -;; - -let of_dual c1 c2 = - let b1 = Big_int.big_int_of_int (Char.code c1) in - let b2 = shift_left (Big_int.big_int_of_int (Char.code c2)) 8 in - Big_int.add_big_int b1 b2 -;; - -let to_bytes u = - let b0 = Char.chr (Big_int.int_of_big_int (logand u (Big_int.big_int_of_string "255"))) in (* 0xFF *) - let b1 = Char.chr (Big_int.int_of_big_int (shift_right (logand u (Big_int.big_int_of_string "65280")) 8)) in (* 0xFF00 *) - b1, b0 -;; - -let to_string (u : uint16) = - Big_int.string_of_big_int u -;; - -let equal u1 u2 = - Big_int.eq_big_int u1 u2 -;;
\ No newline at end of file diff --git a/lib/ocaml_rts/linksem/uint32_wrapper.ml b/lib/ocaml_rts/linksem/uint32_wrapper.ml deleted file mode 100644 index 50c295d4..00000000 --- a/lib/ocaml_rts/linksem/uint32_wrapper.ml +++ /dev/null @@ -1,97 +0,0 @@ -type uint32 = Nat_big_num.num - -(* 2^32 - 1 *) -let max_int = - Nat_big_num.of_string "4294967295" -;; - -let add l r = - Nat_big_num.modulus (Nat_big_num.add l r) max_int -;; - -let of_char (c : char) : uint32 = - Nat_big_num.of_int (Char.code c) -;; - -let of_int (i : int) = - Nat_big_num.of_int i -;; - -let of_bigint (i : Nat_big_num.num) : uint32 = - Nat_big_num.modulus i max_int -;; - -let of_int32 (i : Int32.t) = - Nat_big_num.of_int32 i -;; - -let to_bigint (u : uint32) : Nat_big_num.num = u -;; - -let shift_left i s = - Nat_big_num.modulus (Nat_big_num.shift_left i s) max_int -;; - -let shift_right i s = - Nat_big_num.modulus (Nat_big_num.shift_right i s) max_int -;; - -let logand l r = - Nat_big_num.modulus (Nat_big_num.bitwise_and l r) max_int -;; - -let logor l r = - Nat_big_num.modulus (Nat_big_num.bitwise_or l r) max_int -;; - -let to_string l = - Nat_big_num.to_string l -;; - -let to_char u = - Char.chr (Nat_big_num.to_int u) -;; - -let equal l r = - Nat_big_num.equal l r -;; - -let of_quad c1 c2 c3 c4 = - let b1 = Nat_big_num.of_int (Char.code c1) in - let b2 = shift_left (Nat_big_num.of_int (Char.code c2)) 8 in - let b3 = shift_left (Nat_big_num.of_int (Char.code c3)) 16 in - let b4 = shift_left (Nat_big_num.of_int (Char.code c4)) 24 in - Nat_big_num.add b1 (Nat_big_num.add b2 (Nat_big_num.add b3 b4)) -;; - -let of_quad_native c1 c2 c3 c4 = - let b1 = Uint32.of_int (Char.code c1) in - let b2 = Uint32.shift_left (Uint32.of_int (Char.code c2)) 8 in - let b3 = Uint32.shift_left (Uint32.of_int (Char.code c3)) 16 in - let b4 = Uint32.shift_left (Uint32.of_int (Char.code c4)) 24 in - Uint32.add b1 (Uint32.add b2 (Uint32.add b3 b4)) -;; - -let of_dual_native c1 c2 = of_quad_native c1 c2 '\000' '\000' -;; - -let to_bytes u : char * char * char * char = - let b0 = Char.chr (Nat_big_num.to_int (logand u (Nat_big_num.of_string "255"))) in - let b1 = Char.chr (Nat_big_num.to_int (shift_right (logand u (Nat_big_num.of_string "65280")) 8)) in - let b2 = Char.chr (Nat_big_num.to_int (shift_right (logand u (Nat_big_num.of_string "16711680")) 16)) in - let b3 = Char.chr (Nat_big_num.to_int (shift_right (logand u (Nat_big_num.of_string "4278190080")) 24)) in - b0, b1, b2, b3 -;; - -let to_bytes_native u : char * char * char * char = - let b0 = Char.chr (Uint32.to_int (Uint32.logand u (Uint32.of_string "255"))) in - let b1 = Char.chr (Uint32.to_int (Uint32.shift_right (Uint32.logand u (Uint32.of_string "65280")) 8)) in - let b2 = Char.chr (Uint32.to_int (Uint32.shift_right (Uint32.logand u (Uint32.of_string "16711680")) 16)) in - let b3 = Char.chr (Uint32.to_int (Uint32.shift_right (Uint32.logand u (Uint32.of_string "4278190080")) 24)) in - b0, b1, b2, b3 -;; - -let to_dual_bytes_native u : char * char = - let (b3, b2, b1, b0) = to_bytes_native u in - b3, b2 -;; diff --git a/lib/ocaml_rts/linksem/uint64_wrapper.ml b/lib/ocaml_rts/linksem/uint64_wrapper.ml deleted file mode 100644 index 344ce4be..00000000 --- a/lib/ocaml_rts/linksem/uint64_wrapper.ml +++ /dev/null @@ -1,119 +0,0 @@ -type uint64 - = Nat_big_num.num - -(* 2^64 - 1 *) -let max_int = - let x = Nat_big_num.of_string "4294967296" in - let y = Nat_big_num.mul x (Nat_big_num.of_int 2) in - Nat_big_num.sub y (Nat_big_num.of_int 1) -;; - -let add l r = - Nat_big_num.modulus (Nat_big_num.add l r) max_int -;; - -let minus l r = - Nat_big_num.modulus (Nat_big_num.sub l r) max_int -;; - -let of_int i = - Nat_big_num.of_int i -;; - -let of_int64 (i : Int64.t) = - Nat_big_num.of_int64 i -;; - -let shift_left i s = - Nat_big_num.modulus (Nat_big_num.shift_left i s) max_int -;; - -let shift_right i s = - Nat_big_num.modulus (Nat_big_num.shift_right i s) max_int -;; - -let logand l r = - Nat_big_num.modulus (Nat_big_num.bitwise_and l r) max_int -;; - -let logor l r = - Nat_big_num.modulus (Nat_big_num.bitwise_or l r) max_int -;; - -let to_string l = - Nat_big_num.to_string l -;; - -let equal l r = - Nat_big_num.equal l r -;; - -let of_oct c1 c2 c3 c4 c5 c6 c7 c8 = - let b1 = Nat_big_num.of_int (Char.code c1) in - let b2 = shift_left (Nat_big_num.of_int (Char.code c2)) 8 in - let b3 = shift_left (Nat_big_num.of_int (Char.code c3)) 16 in - let b4 = shift_left (Nat_big_num.of_int (Char.code c4)) 24 in - let b5 = shift_left (Nat_big_num.of_int (Char.code c5)) 32 in - let b6 = shift_left (Nat_big_num.of_int (Char.code c6)) 40 in - let b7 = shift_left (Nat_big_num.of_int (Char.code c7)) 48 in - let b8 = shift_left (Nat_big_num.of_int (Char.code c8)) 56 in - Nat_big_num.add b1 (Nat_big_num.add b2 - (Nat_big_num.add b3 (Nat_big_num.add b4 - (Nat_big_num.add b5 (Nat_big_num.add b6 - (Nat_big_num.add b7 b8)))))) -;; - -let of_oct_native c1 c2 c3 c4 c5 c6 c7 c8 = - let b1 = Uint64.of_int (Char.code c1) in - let b2 = Uint64.shift_left (Uint64.of_int (Char.code c2)) 8 in - let b3 = Uint64.shift_left (Uint64.of_int (Char.code c3)) 16 in - let b4 = Uint64.shift_left (Uint64.of_int (Char.code c4)) 24 in - let b5 = Uint64.shift_left (Uint64.of_int (Char.code c5)) 32 in - let b6 = Uint64.shift_left (Uint64.of_int (Char.code c6)) 40 in - let b7 = Uint64.shift_left (Uint64.of_int (Char.code c7)) 48 in - let b8 = Uint64.shift_left (Uint64.of_int (Char.code c8)) 56 in - Uint64.add b1 (Uint64.add b2 - (Uint64.add b3 (Uint64.add b4 - (Uint64.add b5 (Uint64.add b6 - (Uint64.add b7 b8)))))) -;; - -let to_bigint (u : uint64) : Nat_big_num.num = - u -;; - -let of_bigint (u : Nat_big_num.num) : uint64 = - Nat_big_num.modulus u max_int -;; - -let to_bytes u : char * char * char * char * char * char * char * char = - let u1 = Nat_big_num.mul (Nat_big_num.of_string "4278190080") (Nat_big_num.of_string "255") in (* 0xFF00000000 *) - let u2 = Nat_big_num.mul (Nat_big_num.of_string "4278190080") (Nat_big_num.of_string "65280") in (* 0xFF0000000000 *) - let u3 = Nat_big_num.mul (Nat_big_num.of_string "4278190080") (Nat_big_num.of_string "16711680") in (* 0xFF000000000000 *) - let u4 = Nat_big_num.mul (Nat_big_num.of_string "4278190080") (Nat_big_num.of_string "4278190080") in (* 0xFF00000000000000 *) - let b0 = Char.chr (Nat_big_num.to_int (logand u (Nat_big_num.of_string "255"))) in (* 0xFF *) - let b1 = Char.chr (Nat_big_num.to_int (shift_right (logand u (Nat_big_num.of_string "65280")) 8)) in (* 0xFF00 *) - let b2 = Char.chr (Nat_big_num.to_int (shift_right (logand u (Nat_big_num.of_string "16711680")) 16)) in (* 0xFF0000 *) - let b3 = Char.chr (Nat_big_num.to_int (shift_right (logand u (Nat_big_num.of_string "4278190080")) 24)) in (* 0xFF000000 *) - let b4 = Char.chr (Nat_big_num.to_int (shift_right (logand u u1) 32)) in (* 0xFF00000000 *) - let b5 = Char.chr (Nat_big_num.to_int (shift_right (logand u u2) 40)) in (* 0xFF0000000000 *) - let b6 = Char.chr (Nat_big_num.to_int (shift_right (logand u u3) 48)) in (* 0xFF000000000000 *) - let b7 = Char.chr (Nat_big_num.to_int (shift_right (logand u u4) 56)) in (* 0xFF00000000000000 *) - b0,b1,b2,b3,b4,b5,b6,b7 -;; - -let to_bytes_native u : char * char * char * char * char * char * char * char = - let u1 = Uint64.mul (Uint64.of_string "4278190080") (Uint64.of_string "255") in (* 0xFF00000000 *) - let u2 = Uint64.mul (Uint64.of_string "4278190080") (Uint64.of_string "65280") in (* 0xFF0000000000 *) - let u3 = Uint64.mul (Uint64.of_string "4278190080") (Uint64.of_string "16711680") in (* 0xFF000000000000 *) - let u4 = Uint64.mul (Uint64.of_string "4278190080") (Uint64.of_string "4278190080") in (* 0xFF00000000000000 *) - let b0 = Char.chr (Uint64.to_int (Uint64.logand u (Uint64.of_string "255"))) in (* 0xFF *) - let b1 = Char.chr (Uint64.to_int (Uint64.shift_right (Uint64.logand u (Uint64.of_string "65280")) 8)) in (* 0xFF00 *) - let b2 = Char.chr (Uint64.to_int (Uint64.shift_right (Uint64.logand u (Uint64.of_string "16711680")) 16)) in (* 0xFF0000 *) - let b3 = Char.chr (Uint64.to_int (Uint64.shift_right (Uint64.logand u (Uint64.of_string "4278190080")) 24)) in (* 0xFF000000 *) - let b4 = Char.chr (Uint64.to_int (Uint64.shift_right (Uint64.logand u u1) 32)) in (* 0xFF00000000 *) - let b5 = Char.chr (Uint64.to_int (Uint64.shift_right (Uint64.logand u u2) 40)) in (* 0xFF0000000000 *) - let b6 = Char.chr (Uint64.to_int (Uint64.shift_right (Uint64.logand u u3) 48)) in (* 0xFF000000000000 *) - let b7 = Char.chr (Uint64.to_int (Uint64.shift_right (Uint64.logand u u4) 56)) in (* 0xFF00000000000000 *) - b0,b1,b2,b3,b4,b5,b6,b7 -;; diff --git a/lib/ocaml_rts/linksem/utility.ml b/lib/ocaml_rts/linksem/utility.ml deleted file mode 100644 index 8b137891..00000000 --- a/lib/ocaml_rts/linksem/utility.ml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/lib/ocaml_rts/sail_lib.ml b/lib/ocaml_rts/sail_lib.ml deleted file mode 100644 index b24e2fec..00000000 --- a/lib/ocaml_rts/sail_lib.ml +++ /dev/null @@ -1,473 +0,0 @@ -open Big_int - -type 'a return = { return : 'b . 'a -> 'b } - -let opt_trace = ref false - -let trace_depth = ref 0 -let random = ref false - -let sail_call (type t) (f : _ -> t) = - let module M = - struct exception Return of t end - in - let return = { return = (fun x -> raise (M.Return x)) } in - try - f return - with M.Return x -> x - -let trace str = - if !opt_trace - then - begin - if !trace_depth < 0 then trace_depth := 0 else (); - prerr_endline (String.make (!trace_depth * 2) ' ' ^ str) - end - else () - -let trace_write name str = - trace ("Write: " ^ name ^ " " ^ str) - -let trace_read name str = - trace ("Read: " ^ name ^ " " ^ str) - -let sail_trace_call (type t) (name : string) (in_string : string) (string_of_out : t -> string) (f : _ -> t) = - let module M = - struct exception Return of t end - in - let return = { return = (fun x -> raise (M.Return x)) } in - trace ("Call: " ^ name ^ " " ^ in_string); - incr trace_depth; - let result = try f return with M.Return x -> x in - decr trace_depth; - trace ("Return: " ^ string_of_out result); - result - -let trace_call str = - trace str; incr trace_depth - -type bit = B0 | B1 - -let and_bit = function - | B1, B1 -> B1 - | _, _ -> B0 - -let or_bit = function - | B0, B0 -> B0 - | _, _ -> B1 - -let xor_bit = function - | B1, B0 -> B1 - | B0, B1 -> B1 - | _, _ -> B0 - -let and_vec (xs, ys) = - assert (List.length xs = List.length ys); - List.map2 (fun x y -> and_bit (x, y)) xs ys - -let and_bool (b1, b2) = b1 && b2 - -let or_vec (xs, ys) = - assert (List.length xs = List.length ys); - List.map2 (fun x y -> or_bit (x, y)) xs ys - -let or_bool (b1, b2) = b1 || b2 - -let xor_vec (xs, ys) = - assert (List.length xs = List.length ys); - List.map2 (fun x y -> xor_bit (x, y)) xs ys - -let xor_bool (b1, b2) = (b1 || b2) && (b1 != b2) - -let undefined_bit () = - if !random - then (if Random.bool () then B0 else B1) - else B0 - -let undefined_bool () = - if !random then Random.bool () else false - -let rec undefined_vector (len, item) = - if eq_big_int len zero_big_int - then [] - else item :: undefined_vector (sub_big_int len unit_big_int, item) - -let undefined_string () = "" - -let undefined_unit () = () - -let undefined_int () = - if !random then big_int_of_int (Random.int 0xFFFF) else zero_big_int - -let undefined_nat () = zero_big_int - -let undefined_range (lo, hi) = lo - -let internal_pick list = - if !random - then List.nth list (Random.int (List.length list)) - else List.nth list 0 - -let eq_int (n, m) = eq_big_int n m - -let rec drop n xs = - match n, xs with - | 0, xs -> xs - | n, [] -> [] - | n, (x :: xs) -> drop (n -1) xs - -let rec take n xs = - match n, xs with - | 0, xs -> [] - | n, (x :: xs) -> x :: take (n - 1) xs - | n, [] -> [] - -let subrange (list, n, m) = - let n = int_of_big_int n in - let m = int_of_big_int m in - List.rev (take (n - (m - 1)) (drop m (List.rev list))) - -let slice (list, n, m) = - let n = int_of_big_int n in - let m = int_of_big_int m in - List.rev (take m (drop n (List.rev list))) - -let eq_list (xs, ys) = List.for_all2 (fun x y -> x = y) xs ys - -let access (xs, n) = List.nth (List.rev xs) (int_of_big_int n) - -let append (xs, ys) = xs @ ys - -let update (xs, n, x) = - let n = (List.length xs - int_of_big_int n) - 1 in - take n xs @ [x] @ drop (n + 1) xs - -let update_subrange (xs, n, m, ys) = - let rec aux xs o = function - | [] -> xs - | (y :: ys) -> aux (update (xs, o, y)) (sub_big_int o unit_big_int) ys - in - aux xs n ys - - -let length xs = big_int_of_int (List.length xs) - -let big_int_of_bit = function - | B0 -> zero_big_int - | B1 -> unit_big_int - -let uint xs = - let uint_bit x (n, pos) = - add_big_int n (mult_big_int (power_int_positive_int 2 pos) (big_int_of_bit x)), pos + 1 - in - fst (List.fold_right uint_bit xs (zero_big_int, 0)) - -let sint = function - | [] -> zero_big_int - | [msb] -> minus_big_int (big_int_of_bit msb) - | msb :: xs -> - let msb_pos = List.length xs in - let complement = - minus_big_int (mult_big_int (power_int_positive_int 2 msb_pos) (big_int_of_bit msb)) - in - add_big_int complement (uint xs) - -let add (x, y) = add_big_int x y -let sub (x, y) = sub_big_int x y -let mult (x, y) = mult_big_int x y -let quotient (x, y) = fst (quomod_big_int x y) -let modulus (x, y) = snd (quomod_big_int x y) - -let add_bit_with_carry (x, y, carry) = - match x, y, carry with - | B0, B0, B0 -> B0, B0 - | B0, B1, B0 -> B1, B0 - | B1, B0, B0 -> B1, B0 - | B1, B1, B0 -> B0, B1 - | B0, B0, B1 -> B1, B0 - | B0, B1, B1 -> B0, B1 - | B1, B0, B1 -> B0, B1 - | B1, B1, B1 -> B1, B1 - -let sub_bit_with_carry (x, y, carry) = - match x, y, carry with - | B0, B0, B0 -> B0, B0 - | B0, B1, B0 -> B0, B1 - | B1, B0, B0 -> B1, B0 - | B1, B1, B0 -> B0, B0 - | B0, B0, B1 -> B1, B0 - | B0, B1, B1 -> B0, B0 - | B1, B0, B1 -> B1, B1 - | B1, B1, B1 -> B1, B0 - -let not_bit = function - | B0 -> B1 - | B1 -> B0 - -let not_vec xs = List.map not_bit xs - -let add_vec_carry (xs, ys) = - assert (List.length xs = List.length ys); - let (carry, result) = - List.fold_right2 (fun x y (c, result) -> let (z, c) = add_bit_with_carry (x, y, c) in (c, z :: result)) xs ys (B0, []) - in - carry, result - -let add_vec (xs, ys) = snd (add_vec_carry (xs, ys)) - -let rec replicate_bits (bits, n) = - if le_big_int n zero_big_int - then [] - else bits @ replicate_bits (bits, sub_big_int n unit_big_int) - -let identity x = x - -let rec bits_of_big_int bit n = - if not (eq_big_int bit zero_big_int) - then - begin - if gt_big_int (div_big_int n bit) zero_big_int - then B1 :: bits_of_big_int (div_big_int bit (big_int_of_int 2)) (sub_big_int n bit) - else B0 :: bits_of_big_int (div_big_int bit (big_int_of_int 2)) n - end - else [] - -let add_vec_int (v, n) = - let n_bits = bits_of_big_int (power_int_positive_int 2 (List.length v - 1)) n in - add_vec(v, n_bits) - -let sub_vec (xs, ys) = add_vec (xs, add_vec_int (not_vec ys, unit_big_int)) - -let sub_vec_int (v, n) = - let n_bits = bits_of_big_int (power_int_positive_int 2 (List.length v - 1)) n in - sub_vec(v, n_bits) - -let get_slice_int (n, m, o) = - let bits = bits_of_big_int (power_int_positive_big_int 2 (add_big_int n o)) (abs_big_int m) in - let bits = - if lt_big_int m zero_big_int - then sub_vec (List.map (fun _ -> B0) bits, bits) - else bits - in - let slice = List.rev (take (int_of_big_int n) (drop (int_of_big_int o) (List.rev bits))) in - assert (eq_big_int (big_int_of_int (List.length slice)) n); - slice - -let hex_char = function - | '0' -> [B0; B0; B0; B0] - | '1' -> [B0; B0; B0; B1] - | '2' -> [B0; B0; B1; B0] - | '3' -> [B0; B0; B1; B1] - | '4' -> [B0; B1; B0; B0] - | '5' -> [B0; B1; B0; B1] - | '6' -> [B0; B1; B1; B0] - | '7' -> [B0; B1; B1; B1] - | '8' -> [B1; B0; B0; B0] - | '9' -> [B1; B0; B0; B1] - | 'A' | 'a' -> [B1; B0; B1; B0] - | 'B' | 'b' -> [B1; B0; B1; B1] - | 'C' | 'c' -> [B1; B1; B0; B0] - | 'D' | 'd' -> [B1; B1; B0; B1] - | 'E' | 'e' -> [B1; B1; B1; B0] - | 'F' | 'f' -> [B1; B1; B1; B1] - -let list_of_string s = - let rec aux i acc = - if i < 0 then acc - else aux (i-1) (s.[i] :: acc) - in aux (String.length s - 1) [] - -let bits_of_string str = - List.concat (List.map hex_char (list_of_string str)) - -let concat_str (str1, str2) = str1 ^ str2 - -let rec break n = function - | [] -> [] - | (_ :: _ as xs) -> [take n xs] @ break n (drop n xs) - -let string_of_bit = function - | B0 -> "0" - | B1 -> "1" - -let string_of_hex = function - | [B0; B0; B0; B0] -> "0" - | [B0; B0; B0; B1] -> "1" - | [B0; B0; B1; B0] -> "2" - | [B0; B0; B1; B1] -> "3" - | [B0; B1; B0; B0] -> "4" - | [B0; B1; B0; B1] -> "5" - | [B0; B1; B1; B0] -> "6" - | [B0; B1; B1; B1] -> "7" - | [B1; B0; B0; B0] -> "8" - | [B1; B0; B0; B1] -> "9" - | [B1; B0; B1; B0] -> "A" - | [B1; B0; B1; B1] -> "B" - | [B1; B1; B0; B0] -> "C" - | [B1; B1; B0; B1] -> "D" - | [B1; B1; B1; B0] -> "E" - | [B1; B1; B1; B1] -> "F" - -let string_of_bits bits = - if List.length bits mod 4 == 0 - then "0x" ^ String.concat "" (List.map string_of_hex (break 4 bits)) - else "0b" ^ String.concat "" (List.map string_of_bit bits) - -let hex_slice (str, n, m) = - let bits = List.concat (List.map hex_char (list_of_string (String.sub str 2 (String.length str - 2)))) in - let padding = replicate_bits([B0], n) in - let bits = padding @ bits in - let slice = List.rev (take (int_of_big_int n) (drop (int_of_big_int m) (List.rev bits))) in - slice - -let putchar n = - print_char (char_of_int (int_of_big_int n)); - flush stdout - -let rec bits_of_int bit n = - if bit <> 0 - then - begin - if n / bit > 0 - then B1 :: bits_of_int (bit / 2) (n - bit) - else B0 :: bits_of_int (bit / 2) n - end - else [] - -let byte_of_int n = bits_of_int 128 n - -module BigIntHash = - struct - type t = big_int - let equal i j = eq_big_int i j - let hash i = Hashtbl.hash i - end - -module RAM = Hashtbl.Make(BigIntHash) - -let ram : int RAM.t = RAM.create 256 - -let write_ram' (addr_size, data_size, hex_ram, addr, data) = - let data = List.map (fun byte -> int_of_big_int (uint byte)) (break 8 data) in - let rec write_byte i byte = - trace (Printf.sprintf "Store: %s 0x%02X" (string_of_big_int (add_big_int addr (big_int_of_int i))) byte); - RAM.add ram (add_big_int addr (big_int_of_int i)) byte - in - List.iteri write_byte (List.rev data) - -let write_ram (addr_size, data_size, hex_ram, addr, data) = - write_ram' (addr_size, data_size, hex_ram, uint addr, data) - -let wram addr byte = - RAM.add ram addr byte - -let read_ram (addr_size, data_size, hex_ram, addr) = - let addr = uint addr in - let rec read_byte i = - if eq_big_int i zero_big_int - then [] - else - begin - let loc = sub_big_int (add_big_int addr i) unit_big_int in - let byte = try RAM.find ram loc with Not_found -> 0 in - trace (Printf.sprintf "Load: %s 0x%02X" (string_of_big_int loc) byte); - byte_of_int byte @ read_byte (sub_big_int i unit_big_int) - end - in - read_byte data_size - -let rec reverse_endianness bits = - if List.length bits <= 8 then bits else - reverse_endianness (drop 8 bits) @ (take 8 bits) - -(* FIXME: Casts can't be externed *) -let zcast_unit_vec x = [x] - -let shl_int (n, m) = shift_left_big_int n (int_of_big_int m) -let shr_int (n, m) = shift_right_big_int n (int_of_big_int m) - -let debug (str1, n, str2, v) = prerr_endline (str1 ^ string_of_big_int n ^ str2 ^ string_of_bits v) - -let eq_string (str1, str2) = String.compare str1 str2 == 0 - -let lt_int (x, y) = lt_big_int x y - -let set_slice (out_len, slice_len, out, n, slice) = - let out = update_subrange(out, add_big_int n (big_int_of_int (List.length slice - 1)), n, slice) in - assert (List.length out = int_of_big_int out_len); - out - -let set_slice_int (_, _, _, _) = assert false - -let eq_real (x, y) = Num.eq_num x y -let lt_real (x, y) = Num.lt_num x y -let gt_real (x, y) = Num.gt_num x y -let lteq_real (x, y) = Num.le_num x y -let gteq_real (x, y) = Num.ge_num x y - -let round_down x = Num.big_int_of_num (Num.floor_num x) -let round_up x = Num.big_int_of_num (Num.ceiling_num x) -let quotient_real (x, y) = Num.div_num x y -let mult_real (x, y) = Num.mult_num x y -let real_power (x, y) = Num.power_num x (Num.num_of_big_int y) -let add_real (x, y) = Num.add_num x y -let sub_real (x, y) = Num.sub_num x y - -let abs_real x = Num.abs_num x - -let lt (x, y) = lt_big_int x y -let gt (x, y) = gt_big_int x y -let lteq (x, y) = le_big_int x y -let gteq (x, y) = ge_big_int x y - -let pow2 x = power_big_int_positive_int x 2 - -let max_int (x, y) = max_big_int x y -let min_int (x, y) = min_big_int x y -let abs_int x = abs_big_int x - -let undefined_real () = Num.num_of_int 0 - -let real_of_string str = - try - let point = String.index str '.' in - let whole = Num.num_of_string (String.sub str 0 point) in - let frac_str = String.sub str (point + 1) (String.length str - (point + 1)) in - let frac = Num.div_num (Num.num_of_string frac_str) (Num.num_of_big_int (power_int_positive_int 10 (String.length frac_str))) in - Num.add_num whole frac - with - | Not_found -> Num.num_of_string str - -(* Not a very good sqrt implementation *) -let sqrt_real x = real_of_string (string_of_float (sqrt (Num.float_of_num x))) - -let print_int (str, x) = - print_endline (str ^ string_of_big_int x) - -let print_bits (str, xs) = - print_endline (str ^ string_of_bits xs) - -let reg_deref r = !r - -let string_of_zbit = function - | B0 -> "0" - | B1 -> "1" -let string_of_znat n = string_of_big_int n -let string_of_zint n = string_of_big_int n -let string_of_zunit () = "()" -let string_of_zbool = function - | true -> "true" - | false -> "false" -let string_of_zreal r = Num.string_of_num r -let string_of_zstring str = "\"" ^ String.escaped str ^ "\"" - -let rec string_of_list sep string_of = function - | [] -> "" - | [x] -> string_of x - | x::ls -> (string_of x) ^ sep ^ (string_of_list sep string_of ls) - -let zero_extend (vec, n) = - let m = int_of_big_int n in - if m <= List.length vec - then take m vec - else replicate_bits ([B0], big_int_of_int (m - List.length vec)) @ vec diff --git a/lib/ocaml_rts/spec.ml b/lib/ocaml_rts/spec.ml deleted file mode 100644 index 3e551774..00000000 --- a/lib/ocaml_rts/spec.ml +++ /dev/null @@ -1,4 +0,0 @@ - -let zmain () = () - -let initialize_registers () = () |
