Source file elf64_file_of_elf_memory_image.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
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
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_num
open Lem_maybe
open Lem_assert_extra
open Byte_pattern
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
type make_concrete_fn = Memory_image.element -> Memory_image.element
let elf64_file_of_elf_memory_image a make_concrete fname1 img2:elf64_file=
(
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
t
) basic_shstrtab section_tags_bare)
in
let phoff =( (Nat_big_num.of_int 64))
in
let max_phnum1 = ( a.max_phnum)
in
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 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
let element_section_tag_pairs_sorted_by_address = ( List.sort
(fun (isec1, (el1, range1)) -> (fun (isec2, (el2, range2)) -> (
let (addr1, sz1) = ((match Pmap.lookup el1 img2.elements with
Some(e) ->
(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 ->
let sz = (if 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
sz
)
in
let (last_off, section_file_offsets) = (List.fold_left (fun (current_off, offs_so_far) -> (fun (isec1, (el_name, el_range)) ->
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
current_off bump
| None ->
if flag_is_set shf_alloc isec1.elf64_section_flags then (failwith "allocatable section with no address")
else current_off
))
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)
; 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 =
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
concretise_byte_pattern (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 =
(
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_wrapper.of_bigint idx1)
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_wrapper.of_bigint 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_wrapper.of_bigint
(
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 0)
| _ -> failwith
("internal error: multiple sections named "
^ el_name)
) ),
Uint64_wrapper.of_bigint
( 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_wrapper.of_bigint len ))
in
{ elf64_st_name = nameidx
; elf64_st_info = (d.def_syment.elf64_st_info)
; elf64_st_other = (d.def_syment.elf64_st_other)
; elf64_st_shndx = shndx1 ; elf64_st_value = svalue
; elf64_st_size = sz }
| _ -> failwith "not a symbol tag, in symbol_tags"
) :: x2 else x2) (list_combine symbol_ranges symbol_tags) x2))
in
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))
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_wrapper.of_bigint 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 = (byte_sequence_of_byte_list (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.concat (Lem_list.map (bytes_of_elf64_symbol_table_entry endian) symtab))
; elf64_section_name_as_string = ".symtab"
};
{ 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 = (byte_sequence_of_byte_list (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 = ({
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_wrapper.of_bigint (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_wrapper.of_bigint n
| None -> failwith ("internal error: section name `" ^ (s ^ "' not in shstrtab"))
))
; elf64_sh_type = (Uint32_wrapper.of_bigint isec1.elf64_section_type)
; elf64_sh_flags = (Uint64_wrapper.of_bigint isec1.elf64_section_flags)
; elf64_sh_addr = (Uint64_wrapper.of_bigint isec1.elf64_section_addr)
; elf64_sh_offset = (Uint64_wrapper.of_bigint isec1.elf64_section_offset)
; elf64_sh_size = (Uint64_wrapper.of_bigint isec1.elf64_section_size)
; elf64_sh_link = (Uint32_wrapper.of_bigint isec1.elf64_section_link)
; elf64_sh_info = (Uint32_wrapper.of_bigint isec1.elf64_section_info)
; elf64_sh_addralign = (Uint64_wrapper.of_bigint isec1.elf64_section_align)
; elf64_sh_entsize = (Uint64_wrapper.of_bigint isec1.elf64_section_entsize)
}
)) all_sections_sorted_with_offsets))
; elf64_file_interpreted_segments = ([
])
; elf64_file_interpreted_sections = (null_elf64_interpreted_section :: all_sections_sorted_with_offsets)
; elf64_file_bits_and_bobs = ([])
})