about summary refs log tree commit diff stats
path: root/miasm2/arch/arm/ira.py
blob: 8cfe2da0b363399a7e193773bb21ae788038280b (plain) (blame)
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
#!/usr/bin/env python
#-*- coding:utf-8 -*-

from miasm2.expression.expression import *
from miasm2.ir.ir import ir, irbloc
from miasm2.ir.analysis import ira
from miasm2.arch.arm.sem import ir_arml, ir_armtl, ir_armb, ir_armtb
from miasm2.arch.arm.regs import *
# from miasm2.core.graph import DiGraph


class ir_a_arml_base(ir_arml, ira):
    def __init__(self, symbol_pool=None):
        ir_arml.__init__(self, symbol_pool)
        self.ret_reg = self.arch.regs.R0

class ir_a_armb_base(ir_armb, ira):
    def __init__(self, symbol_pool=None):
        ir_armb.__init__(self, symbol_pool)
        self.ret_reg = self.arch.regs.R0


class ir_a_arml(ir_a_arml_base):

    def __init__(self, symbol_pool=None):
        ir_a_arml_base.__init__(self, symbol_pool)
        self.ret_reg = self.arch.regs.R0

    # for test XXX TODO
    def set_dead_regs(self, b):
        b.rw[-1][1].add(self.arch.regs.zf)
        b.rw[-1][1].add(self.arch.regs.nf)
        b.rw[-1][1].add(self.arch.regs.of)
        b.rw[-1][1].add(self.arch.regs.cf)

    def call_effects(self, ad):
        irs = [[ExprAff(self.ret_reg, ExprOp('call_func_ret', ad, self.sp)),
                ExprAff(self.sp, ExprOp('call_func_stack', ad, self.sp)),
                ]]
        return irs

    def post_add_bloc(self, bloc, ir_blocs):
        ir.post_add_bloc(self, bloc, ir_blocs)
        # flow_graph = DiGraph()
        for irb in ir_blocs:
            # print 'X'*40
            # print irb
            pc_val = None
            lr_val = None
            for exprs in irb.irs:
                for e in exprs:
                    if e.dst == PC:
                        pc_val = e.src
                    if e.dst == LR:
                        lr_val = e.src
            if pc_val is None or lr_val is None:
                continue
            if not isinstance(lr_val, ExprInt):
                continue

            l = bloc.lines[-1]
            if lr_val.arg != l.offset + l.l:
                continue
            # print 'IS CALL!'
            lbl = bloc.get_next()
            new_lbl = self.gen_label()
            irs = self.call_effects(pc_val)
            irs.append([ExprAff(self.IRDst, ExprId(lbl, size=self.pc.size))])
            nbloc = irbloc(new_lbl, irs)
            nbloc.lines = [l]
            self.blocs[new_lbl] = nbloc
            irb.dst = ExprId(new_lbl, size=self.pc.size)

        """
        if not bloc.lines:
            return
        l = bloc.lines[-1]
        sub_call_dst = None
        if not l.is_subcall():
            return
        sub_call_dst = l.args[0]
        if self.ExprIsLabel(sub_call_dst):
            sub_call_dst = sub_call_dst.name
        for b in ir_blocs:
            l = b.lines[-1]
            sub_call_dst_b = None
            sub_call_dst_b = l.args[0]
            #if self.ExprIsLabel(sub_call_dst_b):
            #    sub_call_dst_b = sub_call_dst.name
            #if str(b.dst) == str(sub_call_dst_b):
            #    pass
            if not l.is_subcall():
                continue
            if b.dst != sub_call_dst_b:
                continue
            sub_call_dst_b = l.args[0]
            if self.ExprIsLabel(sub_call_dst_b):
                sub_call_dst_b = sub_call_dst.name
            lbl = bloc.get_next()
            new_lbl = self.gen_label()
            irs = self.call_effects(l.args[0])
            nbloc = irbloc(new_lbl, ExprId(lbl, size=self.pc.size), irs)
            nbloc.lines = [l]
            self.blocs[new_lbl] = nbloc
            b.dst = ExprId(new_lbl, size=self.pc.size)
        return
        """

    def get_out_regs(self, b):
        return set([self.ret_reg, self.sp])

    def sizeof_char(self):
        return 8

    def sizeof_short(self):
        return 16

    def sizeof_int(self):
        return 32

    def sizeof_long(self):
        return 32

    def sizeof_pointer(self):
        return 32

class ir_a_armb(ir_a_armb_base, ir_a_arml):

    def __init__(self, symbol_pool=None):
        ir_a_armb_base.__init__(self, symbol_pool)
        self.ret_reg = self.arch.regs.R0


class ir_a_armtl(ir_armtl, ir_a_arml):
    def __init__(self, symbol_pool):
        ir_armtl.__init__(self, symbol_pool)
        self.ret_reg = self.arch.regs.R0

class ir_a_armtb(ir_a_armtl, ir_armtb, ir_a_armb):
    def __init__(self, symbol_pool):
        ir_armtb.__init__(self, symbol_pool)
        self.ret_reg = self.arch.regs.R0