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_utilities.ml.html
Source file abi_utilities.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
(*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" )) (** Extracting useful information from relocs *) (*val parse_elf64_relocation_info : elf64_xword -> (natural (* type *) * natural (* symbol *))*) let parse_elf64_relocation_info w:Nat_big_num.num*Nat_big_num.num= (let mask = (Uint64_wrapper.of_bigint (natural_of_hex "0xffffffff")) in let typ = (Ml_bindings.nat_big_num_of_uint64 (Uint64_wrapper.logand w mask)) in let sym1 = (Ml_bindings.nat_big_num_of_uint64 (Uint64_wrapper.shift_right w 32)) in (typ, sym1))
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>