package linksem
A formalisation of the core ELF and DWARF file formats written in Lem
Install
Dune Dependency
Authors
Maintainers
Sources
0.8.tar.gz
md5=2075c56715539b3b8f54ae65cc808b8c
sha512=f7c16e4036a1440a6a8d13707a43f0f9f9db0c68489215f948cc300b6a164dba5bf852e58f89503e9d9f38180ee658d9478156ca1a1ef64d6861eec5f9cf43d2
doc/src/linksem_zarith/abi_amd64_serialisation.ml.html
Source file abi_amd64_serialisation.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
(*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 = [] |> *)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>