diff options
Diffstat (limited to 'miasm2/core/cpu.py')
| -rw-r--r-- | miasm2/core/cpu.py | 95 |
1 files changed, 50 insertions, 45 deletions
diff --git a/miasm2/core/cpu.py b/miasm2/core/cpu.py index 6c3de8a7..1326d08b 100644 --- a/miasm2/core/cpu.py +++ b/miasm2/core/cpu.py @@ -8,13 +8,12 @@ from collections import defaultdict import pyparsing import miasm2.expression.expression as m2_expr -from miasm2.core import asmblock from miasm2.core.bin_stream import bin_stream, bin_stream_str from miasm2.core.utils import Disasm_Exception from miasm2.expression.simplifications import expr_simp -from miasm2.core.asm_ast import AstNode, AstInt, AstId, AstMem, AstOp +from miasm2.core.asm_ast import AstNode, AstInt, AstId, AstOp log = logging.getLogger("cpuhelper") console_handler = logging.StreamHandler() @@ -672,7 +671,7 @@ class bs_swapargs(bs_divert): class m_arg(object): - def fromstring(self, text, symbol_pool, parser_result=None): + def fromstring(self, text, loc_db, parser_result=None): if parser_result: e, start, stop = parser_result[self.parser] self.expr = e @@ -682,11 +681,11 @@ class m_arg(object): except StopIteration: return None, None arg = v[0] - expr = self.asm_ast_to_expr(arg, symbol_pool) + expr = self.asm_ast_to_expr(arg, loc_db) self.expr = expr return start, stop - def asm_ast_to_expr(self, arg, symbol_pool): + def asm_ast_to_expr(self, arg, loc_db): raise NotImplementedError("Virtual") @@ -709,7 +708,7 @@ class reg_noarg(object): reg_info = None parser = None - def fromstring(self, text, symbol_pool, parser_result=None): + def fromstring(self, text, loc_db, parser_result=None): if parser_result: e, start, stop = parser_result[self.parser] self.expr = e @@ -719,7 +718,7 @@ class reg_noarg(object): except StopIteration: return None, None arg = v[0] - expr = self.parses_to_expr(arg, symbol_pool) + expr = self.parses_to_expr(arg, loc_db) self.expr = expr return start, stop @@ -985,18 +984,24 @@ class instruction(object): self.mode = mode self.args = args self.additional_info = additional_info + self.offset = None + self.l = None + self.b = None def gen_args(self, args): out = ', '.join([str(x) for x in args]) return out def __str__(self): + return self.to_string() + + def to_string(self, loc_db=None): o = "%-10s " % self.name args = [] for i, arg in enumerate(self.args): if not isinstance(arg, m2_expr.Expr): raise ValueError('zarb arg type') - x = self.arg2str(arg, pos = i) + x = self.arg2str(arg, i, loc_db) args.append(x) o += self.gen_args(args) return o @@ -1011,40 +1016,40 @@ class instruction(object): if symbols is None: symbols = {} args_out = [] - for a in self.args: - e = a + for expr in self.args: # try to resolve symbols using symbols (0 for default value) - ids = m2_expr.get_expr_ids(e) - fixed_ids = {} - for x in ids: - if isinstance(x.name, asmblock.AsmLabel): - name = x.name.name - # special symbol $ - if name == '$': - fixed_ids[x] = self.get_asm_offset(x) - continue - if name == '_': - fixed_ids[x] = self.get_asm_next_offset(x) - continue - if not name in symbols: - raise ValueError('unresolved symbol! %r' % x) - else: - name = x.name - if not name in symbols: + loc_keys = m2_expr.get_expr_locs(expr) + fixed_expr = {} + for exprloc in loc_keys: + loc_key = exprloc.loc_key + names = symbols.get_location_names(loc_key) + # special symbols + if '$' in names: + fixed_expr[exprloc] = self.get_asm_offset(exprloc) continue - if symbols[name].offset is None: - raise ValueError('The offset of label "%s" cannot be ' - 'determined' % name) + if '_' in names: + fixed_expr[exprloc] = self.get_asm_next_offset(exprloc) + continue + if not names: + raise ValueError('Unresolved symbol: %r' % exprloc) + + offset = symbols.get_location_offset(loc_key) + if offset is None: + raise ValueError( + 'The offset of loc_key "%s" cannot be determined' % name + ) else: - size = x.size + # Fix symbol with its offset + size = exprloc.size if size is None: - default_size = self.get_symbol_size(x, symbols) + default_size = self.get_symbol_size(exprloc, symbols) size = default_size - value = m2_expr.ExprInt(symbols[name].offset, size) - fixed_ids[x] = value - e = e.replace_expr(fixed_ids) - e = expr_simp(e) - args_out.append(e) + value = m2_expr.ExprInt(offset, size) + fixed_expr[exprloc] = value + + expr = expr.replace_expr(fixed_expr) + expr = expr_simp(expr) + args_out.append(expr) return args_out def get_info(self, c): @@ -1275,7 +1280,7 @@ class cls_mn(object): return out[0] @classmethod - def fromstring(cls, text, symbol_pool, mode = None): + def fromstring(cls, text, loc_db, mode = None): global total_scans name = re.search('(\S+)', text).groups() if not name: @@ -1315,11 +1320,11 @@ class cls_mn(object): if start != 0: v, start, stop = [None], None, None if v != [None]: - v = f.asm_ast_to_expr(v[0], symbol_pool) + v = f.asm_ast_to_expr(v[0], loc_db) if v is None: v, start, stop = [None], None, None parsers[(i, start_i)][p] = v, start, stop - start, stop = f.fromstring(args_str, symbol_pool, parsers[(i, start_i)]) + start, stop = f.fromstring(args_str, loc_db, parsers[(i, start_i)]) if start != 0: log.debug("cannot fromstring %r", args_str) cannot_parse = True @@ -1524,12 +1529,12 @@ class cls_mn(object): def parse_prefix(self, v): return 0 - def set_dst_symbol(self, symbol_pool): - dst = self.getdstflow(symbol_pool) + def set_dst_symbol(self, loc_db): + dst = self.getdstflow(loc_db) args = [] for d in dst: if isinstance(d, m2_expr.ExprInt): - l = symbol_pool.getby_offset_create(int(d)) + l = loc_db.get_or_create_offset_location(int(d)) a = m2_expr.ExprId(l.name, d.size) else: @@ -1537,7 +1542,7 @@ class cls_mn(object): args.append(a) self.args_symb = args - def getdstflow(self, symbol_pool): + def getdstflow(self, loc_db): return [self.args[0].expr] @@ -1558,7 +1563,7 @@ class imm_noarg(object): return None return v - def fromstring(self, text, symbol_pool, parser_result=None): + def fromstring(self, text, loc_db, parser_result=None): if parser_result: e, start, stop = parser_result[self.parser] else: |