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
|
from future.utils import viewitems
import miasm.expression.expression as m2_expr
from miasm.core.utils import BoundedDict
class Translator(object):
"Abstract parent class for translators."
# Registered translators
available_translators = []
# Implemented language
__LANG__ = ""
@classmethod
def register(cls, translator):
"""Register a translator
@translator: Translator sub-class
"""
cls.available_translators.append(translator)
@classmethod
def to_language(cls, target_lang, *args, **kwargs):
"""Return the corresponding translator instance
@target_lang: str (case insensitive) wanted language
Raise a NotImplementedError in case of unmatched language
"""
target_lang = target_lang.lower()
for translator in cls.available_translators:
if translator.__LANG__.lower() == target_lang:
return translator(*args, **kwargs)
raise NotImplementedError("Unknown target language: %s" % target_lang)
@classmethod
def available_languages(cls):
"Return the list of registered languages"
return [translator.__LANG__ for translator in cls.available_translators]
def __init__(self, cache_size=1000):
"""Instance a translator
@cache_size: (optional) Expr cache size
"""
self._cache = BoundedDict(cache_size)
def from_ExprInt(self, expr):
"""Translate an ExprInt
@expr: ExprInt to translate
"""
raise NotImplementedError("Abstract method")
def from_ExprId(self, expr):
"""Translate an ExprId
@expr: ExprId to translate
"""
raise NotImplementedError("Abstract method")
def from_ExprLoc(self, expr):
"""Translate an ExprLoc
@expr: ExprLoc to translate
"""
raise NotImplementedError("Abstract method")
def from_ExprCompose(self, expr):
"""Translate an ExprCompose
@expr: ExprCompose to translate
"""
raise NotImplementedError("Abstract method")
def from_ExprSlice(self, expr):
"""Translate an ExprSlice
@expr: ExprSlice to translate
"""
raise NotImplementedError("Abstract method")
def from_ExprOp(self, expr):
"""Translate an ExprOp
@expr: ExprOp to translate
"""
raise NotImplementedError("Abstract method")
def from_ExprMem(self, expr):
"""Translate an ExprMem
@expr: ExprMem to translate
"""
raise NotImplementedError("Abstract method")
def from_ExprAssign(self, expr):
"""Translate an ExprAssign
@expr: ExprAssign to translate
"""
raise NotImplementedError("Abstract method")
def from_ExprCond(self, expr):
"""Translate an ExprCond
@expr: ExprCond to translate
"""
raise NotImplementedError("Abstract method")
def from_expr(self, expr):
"""Translate an expression according to its type
@expr: expression to translate
"""
# Use cache
if expr in self._cache:
return self._cache[expr]
# Handle Expr type
handlers = {
m2_expr.ExprInt: self.from_ExprInt,
m2_expr.ExprId: self.from_ExprId,
m2_expr.ExprLoc: self.from_ExprLoc,
m2_expr.ExprCompose: self.from_ExprCompose,
m2_expr.ExprSlice: self.from_ExprSlice,
m2_expr.ExprOp: self.from_ExprOp,
m2_expr.ExprMem: self.from_ExprMem,
m2_expr.ExprAssign: self.from_ExprAssign,
m2_expr.ExprCond: self.from_ExprCond
}
for target, handler in viewitems(handlers):
if isinstance(expr, target):
## Compute value and update the internal cache
ret = handler(expr)
self._cache[expr] = ret
return ret
raise ValueError("Unhandled type for %s" % expr)
|