package linksem

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file abi_amd64_relocation.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
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
(*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_wrapper.uint64),(Nat_big_num.num))relocation_frame)error=
   (if is_elf64_relocatable_file ef.elf64_file_header then
    let (rel_type1, _) = (parse_elf64_relocation_info 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_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 bind (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 bind (lookupM 
  (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "S" val_map1) (fun s_val -> bind (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 bind (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 bind (lookupM 
  (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "L" val_map1) (fun l_val -> bind (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 bind (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 bind (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 bind (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 bind (lookupM 
  (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "G" val_map1) (fun g_val -> bind (lookupM 
  (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "GOT" val_map1) (fun got_val -> bind (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 bind (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 bind (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 bind (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 bind (lookupM 
  (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "S" val_map1) (fun s_val -> bind (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 bind (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 bind (lookupM 
  (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "S" val_map1) (fun s_val -> bind (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 bind (lookupM 
  (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "S" val_map1) (fun s_val -> bind (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 bind (lookupM 
  (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "S" val_map1) (fun s_val -> bind (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 bind (lookupM 
  (instance_Map_MapKeyType_var_dict instance_Basic_classes_SetType_var_dict) "GOT" val_map1) (fun got_val -> bind (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 bind (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 bind (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 bind (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")
OCaml

Innovation. Community. Security.