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
|
#!/bin/python3
import os
import sys
from dietc import *
def main():
prog = Program(open(sys.argv[1], "rb").read())
for function in prog.functions:
fn_locals = function.locals()
start_i = function.code_start()
new_body = []
for op in function.body:
new_body.append(op)
# only look for casts to void
if " = ( " not in op.line: continue
if op.lhs_type(prog) != PointerType(BasicType("void")): continue
# if one is found, construct & annotate its type
rhs_type = prog.object_types[op[-2]]
type_ptr = describe_type(prog, rhs_type, new_body)
new_body.append(Instruction(
f"annotate_type({op[0]}, {type_ptr});"))
function.body = new_body
prog.preamble.append("#include <stddef.h>")
prog.print()
def describe_type(prog, type_, new_body):
name = f"type_{count()}"
if isinstance(type_, BasicType):
new_body.append(Instruction(
f"void *{name} = make_basic(\"{type_.name}\", sizeof({type_.name}));"))
elif isinstance(type_, ArrayType):
base = describe_type(prog, type_.base, new_body)
new_body.append(Instruction(
f"void *{name} = make_array({base}, {type_.length});"))
elif isinstance(type_, PointerType):
base = describe_type(prog, type_.base, new_body)
new_body.append(Instruction(
f"void *{name} = make_pointer({base});"))
elif isinstance(type_, AggregateType):
tname = prog.type_to_name[type_]
new_body.append(Instruction(
f"void *{name} = make_struct(sizeof({tname}));"))
for fn, ft in reversed(type_.fields):
field = describe_type(prog, ft, new_body)
new_body.append(Instruction(
f"prepend_member({name}, {field}, \"{fn}\", offsetof({tname}, {fn}));"))
else: raise NotImplementedError
return name
main()
|