diff options
Diffstat (limited to 'src/miasm/ir/translators/translator.py')
| -rw-r--r-- | src/miasm/ir/translators/translator.py | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/src/miasm/ir/translators/translator.py b/src/miasm/ir/translators/translator.py new file mode 100644 index 00000000..c9368f09 --- /dev/null +++ b/src/miasm/ir/translators/translator.py @@ -0,0 +1,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) + |