Miasm2
 All Classes Namespaces Files Functions Variables Typedefs Properties Macros
Functions | Variables
miasm2.ir.ir2C Namespace Reference

Functions

def init_arch_C
 
def patch_c_id
 
def patch_c_new_id
 
def set_pc
 
def gen_resolve_int
 
def gen_resolve_id_lbl
 
def gen_resolve_id
 
def gen_resolve_mem
 
def gen_resolve_other
 
def gen_resolve_dst_simple
 
def gen_irdst
 
def Expr2C
 
def label2offset
 
def expr2pyobj
 
def ir2C
 
def irblocs2C
 

Variables

tuple log_to_c_h = logging.getLogger("ir_helper")
 
tuple console_handler = logging.StreamHandler()
 
tuple translator = Translator.to_language("C")
 
list prefetch_id = []
 
dictionary prefetch_id_size = {}
 
string name = 'pfmem%.2d_%d'
 
tuple c = m2_expr.ExprId(name, size)
 
int mask_int = 0xffffffffffffffff
 
string pre_instr_test_exception = r""
 
string code_exception_fetch_mem_at_instr = r""
 
string code_exception_fetch_mem_post_instr = r""
 
string code_exception_fetch_mem_at_instr_noautomod = r""
 
string code_exception_fetch_mem_post_instr_noautomod = r""
 
string code_exception_at_instr = r""
 
string code_exception_post_instr = r""
 
string code_exception_at_instr_noautomod = r""
 
string code_exception_post_instr_noautomod = r""
 
string goto_local_code = r""
 
dictionary my_size_mask
 
tuple exception_flags = m2_expr.ExprId('exception_flags', 32)
 

Function Documentation

def miasm2.ir.ir2C.Expr2C (   ir_arch,
  l,
  exprs,
  gen_exception_code = False 
)

Definition at line 203 of file ir2C.py.

204 def Expr2C(ir_arch, l, exprs, gen_exception_code=False):
205  id_to_update = []
206  out = ["// %s" % (l)]
207  out_pc = []
208 
209  dst_dict = {}
210  src_mem = {}
211 
212  prefect_index = {8: 0, 16: 0, 32: 0, 64: 0}
213  new_expr = []
214 
215  e = set_pc(ir_arch, l.offset & mask_int)
216  #out.append("%s;" % patch_c_id(ir_arch.arch, e)))
217 
218  pc_is_dst = False
219  fetch_mem = False
220  set_exception_flags = False
221  for e in exprs:
222  assert isinstance(e, m2_expr.ExprAff)
223  assert not isinstance(e.dst, m2_expr.ExprOp)
224  if isinstance(e.dst, m2_expr.ExprId):
225  if not e.dst in dst_dict:
226  dst_dict[e.dst] = []
227  dst_dict[e.dst].append(e)
228  else:
229  new_expr.append(e)
230  # test exception flags
231  ops = m2_expr.get_expr_ops(e)
232  if set(['umod', 'udiv']).intersection(ops):
233  set_exception_flags = True
234  if e.dst == exception_flags:
235  set_exception_flags = True
236  # TODO XXX test function whose set exception_flags
237 
238  # search mem lookup for generate mem read prefetch
239  rs = e.src.get_r(mem_read=True)
240  for r in rs:
241  if (not isinstance(r, m2_expr.ExprMem)) or r in src_mem:
242  continue
243  fetch_mem = True
244  index = prefect_index[r.size]
245  prefect_index[r.size] += 1
246  pfmem = prefetch_id_size[r.size][index]
247  src_mem[r] = pfmem
248 
249  for dst, exs in dst_dict.items():
250  if len(exs) == 1:
251  new_expr += exs
252  continue
253  exs = [expr_simp(x) for x in exs]
254  log_to_c_h.debug('warning: detected multi dst to same id')
255  log_to_c_h.debug('\t'.join([str(x) for x in exs]))
256  new_expr += exs
257  out_mem = []
258 
259  # first, generate mem prefetch
260  mem_k = src_mem.keys()
261  mem_k.sort()
262  for k in mem_k:
263  str_src = translator.from_expr(patch_c_id(ir_arch.arch, k))
264  str_dst = translator.from_expr(patch_c_id(ir_arch.arch, src_mem[k]))
265  out.append('%s = %s;' % (str_dst, str_src))
266  src_w_len = {}
267  for k, v in src_mem.items():
268  src_w_len[k] = v
269  for e in new_expr:
270 
271  src, dst = e.src, e.dst
272  # reload src using prefetch
273  src = src.replace_expr(src_w_len)
274  if dst is ir_arch.IRDst:
275  out += gen_irdst(ir_arch, src)
276  continue
277 
278 
279  str_src = translator.from_expr(patch_c_id(ir_arch.arch, src))
280  str_dst = translator.from_expr(patch_c_id(ir_arch.arch, dst))
281 
282 
283 
284  if isinstance(dst, m2_expr.ExprId):
285  id_to_update.append(dst)
286  str_dst = patch_c_new_id(ir_arch.arch, dst)
287  if dst in ir_arch.arch.regs.regs_flt_expr:
288  # dont mask float affectation
289  out.append('%s = (%s);' % (str_dst, str_src))
290  else:
291  out.append('%s = (%s)&0x%X;' % (str_dst, str_src,
292  my_size_mask[src.size]))
293  elif isinstance(dst, m2_expr.ExprMem):
294  fetch_mem = True
295  str_dst = str_dst.replace('MEM_LOOKUP', 'MEM_WRITE')
296  out_mem.append('%s, %s);' % (str_dst[:-1], str_src))
297 
298  if e.dst == ir_arch.arch.pc[ir_arch.attrib]:
299  pc_is_dst = True
300  out_pc += ["return JIT_RET_NO_EXCEPTION;"]
301 
302  # if len(id_to_update) != len(set(id_to_update)):
303  # raise ValueError('Not implemented: multi dst to same id!', str([str(x)
304  # for x in exprs]))
305  out += out_mem
306 
307  if gen_exception_code:
308  if fetch_mem:
309  e = set_pc(ir_arch, l.offset & mask_int)
310  s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e))
311  s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)'%(l.offset & mask_int)
312  out.append(code_exception_fetch_mem_at_instr_noautomod % s1)
313  if set_exception_flags:
314  e = set_pc(ir_arch, l.offset & mask_int)
315  s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e))
316  s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)'%(l.offset & mask_int)
317  out.append(code_exception_at_instr_noautomod % s1)
318 
319  for i in id_to_update:
320  if i is ir_arch.IRDst:
321  continue
322  out.append('%s = %s;' %
323  (patch_c_id(ir_arch.arch, i), patch_c_new_id(ir_arch.arch, i)))
324 
325  post_instr = []
326  # test stop exec ####
327  if gen_exception_code:
328  if set_exception_flags:
329  if pc_is_dst:
330  post_instr.append("if (VM_exception_flag) { " +
331  "/*pc = 0x%X; */return JIT_RET_EXCEPTION; }" % (l.offset))
332  else:
333  e = set_pc(ir_arch, l.offset & mask_int)
334  s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e))
335  s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)'%(l.offset & mask_int)
336  e = set_pc(ir_arch, (l.offset + l.l) & mask_int)
337  s2 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e))
338  s2 += ';\n Resolve_dst(BlockDst, 0x%X, 0)'%((l.offset + l.l) & mask_int)
339  post_instr.append(
340  code_exception_post_instr_noautomod % (s1, s2))
341 
342  if fetch_mem:
343  if l.additional_info.except_on_instr:
344  offset = l.offset
345  else:
346  offset = l.offset + l.l
347 
348  e = set_pc(ir_arch, offset & mask_int)
349  s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e))
350  s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)'%(offset & mask_int)
351  post_instr.append(
352  code_exception_fetch_mem_post_instr_noautomod % (s1))
353 
354  # pc manip after all modifications
355  return out, post_instr, post_instr + out_pc
356 
def patch_c_new_id
Definition: ir2C.py:43
def set_pc
Definition: ir2C.py:150
def patch_c_id
Definition: ir2C.py:39
def Expr2C
Definition: ir2C.py:203
def gen_irdst
Definition: ir2C.py:191

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.ir.ir2C.expr2pyobj (   arch,
  e 
)

Definition at line 365 of file ir2C.py.

366 def expr2pyobj(arch, e):
367  if isinstance(e, m2_expr.ExprId):
368  if isinstance(e.name, asmbloc.asm_label):
369  src_c = 'PyString_FromStringAndSize("%s", %d)' % (
370  e.name.name, len(e.name.name))
371  else:
372  src_c = 'PyLong_FromUnsignedLongLong(%s)' % patch_c_id(arch, e)
373  else:
374  raise NotImplementedError('unknown type for e: %s' % type(e))
375  return src_c
376 
def patch_c_id
Definition: ir2C.py:39
def expr2pyobj
Definition: ir2C.py:365

+ Here is the call graph for this function:

def miasm2.ir.ir2C.gen_irdst (   ir_arch,
  e 
)

Definition at line 191 of file ir2C.py.

192 def gen_irdst(ir_arch, e):
193  out = []
194  if isinstance(e, m2_expr.ExprCond):
195  dst_cond_c = translator.from_expr(patch_c_id(ir_arch.arch, e.cond))
196  out.append("if (%s)"%dst_cond_c)
197  out.append(' %s;'%(gen_resolve_dst_simple(ir_arch, e.src1)))
198  out.append("else")
199  out.append(' %s;'%(gen_resolve_dst_simple(ir_arch, e.src2)))
200  else:
201  out.append('%s;'%(gen_resolve_dst_simple(ir_arch, e)))
202  return out
def patch_c_id
Definition: ir2C.py:39
def gen_irdst
Definition: ir2C.py:191
def gen_resolve_dst_simple
Definition: ir2C.py:177

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.ir.ir2C.gen_resolve_dst_simple (   ir_arch,
  e 
)

Definition at line 177 of file ir2C.py.

178 def gen_resolve_dst_simple(ir_arch, e):
179  if isinstance(e, m2_expr.ExprInt):
180  return gen_resolve_int(ir_arch, e)
181  elif isinstance(e, m2_expr.ExprId) and isinstance(e.name,
182  asmbloc.asm_label):
183  return gen_resolve_id_lbl(ir_arch, e)
184  elif isinstance(e, m2_expr.ExprId):
185  return gen_resolve_id(ir_arch, e)
186  elif isinstance(e, m2_expr.ExprMem):
187  return gen_resolve_mem(ir_arch, e)
188  else:
189  return gen_resolve_other(ir_arch, e)
190 
def gen_resolve_id_lbl
Definition: ir2C.py:161
def gen_resolve_other
Definition: ir2C.py:174
def gen_resolve_id
Definition: ir2C.py:168
def gen_resolve_mem
Definition: ir2C.py:171
def gen_resolve_dst_simple
Definition: ir2C.py:177
def gen_resolve_int
Definition: ir2C.py:158

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.ir.ir2C.gen_resolve_id (   ir_arch,
  e 
)

Definition at line 168 of file ir2C.py.

169 def gen_resolve_id(ir_arch, e):
170  return 'Resolve_dst(BlockDst, %s, 0)'%(translator.from_expr(patch_c_id(ir_arch.arch, e)))
def patch_c_id
Definition: ir2C.py:39
def gen_resolve_id
Definition: ir2C.py:168

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.ir.ir2C.gen_resolve_id_lbl (   ir_arch,
  e 
)

Definition at line 161 of file ir2C.py.

162 def gen_resolve_id_lbl(ir_arch, e):
163  if e.name.name.startswith("lbl_gen_"):
164  # TODO XXX CLEAN
165  return 'Resolve_dst(BlockDst, 0x%X, 1)'%(e.name.index)
166  else:
167  return 'Resolve_dst(BlockDst, 0x%X, 0)'%(e.name.offset)
def gen_resolve_id_lbl
Definition: ir2C.py:161

+ Here is the caller graph for this function:

def miasm2.ir.ir2C.gen_resolve_int (   ir_arch,
  e 
)

Definition at line 158 of file ir2C.py.

159 def gen_resolve_int(ir_arch, e):
160  return 'Resolve_dst(BlockDst, 0x%X, 0)' % (e.arg)
def gen_resolve_int
Definition: ir2C.py:158

+ Here is the caller graph for this function:

def miasm2.ir.ir2C.gen_resolve_mem (   ir_arch,
  e 
)

Definition at line 171 of file ir2C.py.

172 def gen_resolve_mem(ir_arch, e):
173  return 'Resolve_dst(BlockDst, %s, 0)'%(translator.from_expr(patch_c_id(ir_arch.arch, e)))
def patch_c_id
Definition: ir2C.py:39
def gen_resolve_mem
Definition: ir2C.py:171

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.ir.ir2C.gen_resolve_other (   ir_arch,
  e 
)

Definition at line 174 of file ir2C.py.

175 def gen_resolve_other(ir_arch, e):
176  return 'Resolve_dst(BlockDst, %s, 0)'%(translator.from_expr(patch_c_id(ir_arch.arch, e)))
def gen_resolve_other
Definition: ir2C.py:174
def patch_c_id
Definition: ir2C.py:39

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.ir.ir2C.init_arch_C (   arch)

Definition at line 28 of file ir2C.py.

28 
29 def init_arch_C(arch):
30  arch.id2Cid = {}
31  for x in arch.regs.all_regs_ids + prefetch_id:
32  arch.id2Cid[x] = m2_expr.ExprId('((vm_cpu_t*)jitcpu->cpu)->' + str(x), x.size)
33 
34  arch.id2newCid = {}
35 
36  for x in arch.regs.all_regs_ids + prefetch_id:
37  arch.id2newCid[x] = m2_expr.ExprId('((vm_cpu_t*)jitcpu->cpu)->%s_new' % x, x.size)
38 
def init_arch_C
Definition: ir2C.py:28
def miasm2.ir.ir2C.ir2C (   ir_arch,
  irbloc,
  lbl_done,
  gen_exception_code = False,
  log_mn = False,
  log_regs = False 
)

Definition at line 378 of file ir2C.py.

379  gen_exception_code=False, log_mn=False, log_regs=False):
380  out = []
381  # print "TRANS"
382  # print irbloc
383  out.append(["%s:" % irbloc.label.name])
384  #out.append(['printf("%s:\n");' % irbloc.label.name])
385  assert len(irbloc.irs) == len(irbloc.lines)
386  for l, exprs in zip(irbloc.lines, irbloc.irs):
387  if l.offset not in lbl_done:
388  e = set_pc(ir_arch, l.offset & mask_int)
389  s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e))
390  s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)'%(l.offset & mask_int)
391  out.append([pre_instr_test_exception % (s1)])
392  lbl_done.add(l.offset)
393 
394  if log_regs:
395  out.append([r'dump_gpregs(jitcpu->cpu);'])
396 
397  if log_mn:
398  out.append(['printf("%.8X %s\\n");' % (l.offset, str(l))])
399  # print l
400  # gen pc update
401  post_instr = ""
402  c_code, post_instr, _ = Expr2C(ir_arch, l, exprs, gen_exception_code)
403  out.append(c_code + post_instr)
404  out.append([goto_local_code ] )
405  return out
406 
def set_pc
Definition: ir2C.py:150
def patch_c_id
Definition: ir2C.py:39
def Expr2C
Definition: ir2C.py:203

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.ir.ir2C.irblocs2C (   ir_arch,
  resolvers,
  label,
  irblocs,
  gen_exception_code = False,
  log_mn = False,
  log_regs = False 
)

Definition at line 408 of file ir2C.py.

409  gen_exception_code=False, log_mn=False, log_regs=False):
410  out = []
411 
412  lbls = [b.label for b in irblocs]
413  lbls_local = []
414  for l in lbls:
415  if l.name.startswith('lbl_gen_'):
416  l.index = int(l.name[8:], 16)
417  lbls_local.append(l)
418  lbl_index_min, lbl_index_max = 0, 0
419  lbls_index = [l.index for l in lbls if hasattr(l, 'index')]
420  lbls_local.sort(key=lambda x:x.index)
421 
422  if lbls_index:
423  lbl_index_min = min(lbls_index)
424  lbl_index_max = max(lbls_index)
425  for l in lbls_local:
426  l.index -= lbl_index_min
427 
428  out.append("void* local_labels[] = {%s};"%(', '.join(["&&%s"%l.name for l in lbls_local])))
429 
430  out.append("goto %s;" % label.name)
431  bloc_labels = [x.label for x in irblocs]
432  assert label in bloc_labels
433 
434  lbl_done = set([None])
435 
436  for irbloc in irblocs:
437  # XXXX TEST
438  if irbloc.label.offset is None:
439  b_out = ir2C(ir_arch, irbloc, lbl_done, gen_exception_code)
440  else:
441  b_out = ir2C(
442  ir_arch, irbloc, lbl_done, gen_exception_code, log_mn, log_regs)
443  for exprs in b_out:
444  for l in exprs:
445  out.append(l)
446  dst = irbloc.dst
447  out.append("")
448 
449  return out
450 
def ir2C
Definition: ir2C.py:378

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.ir.ir2C.label2offset (   e)

Definition at line 357 of file ir2C.py.

358 def label2offset(e):
359  if not isinstance(e, m2_expr.ExprId):
360  return e
361  if not isinstance(e.name, asmbloc.asm_label):
362  return e
363  return m2_expr.ExprInt_from(e, e.name.offset)
364 
def label2offset
Definition: ir2C.py:357
def miasm2.ir.ir2C.patch_c_id (   arch,
  e 
)

Definition at line 39 of file ir2C.py.

39 
40 def patch_c_id(arch, e):
41  return e.replace_expr(arch.id2Cid)
42 
def patch_c_id
Definition: ir2C.py:39

+ Here is the caller graph for this function:

def miasm2.ir.ir2C.patch_c_new_id (   arch,
  e 
)

Definition at line 43 of file ir2C.py.

43 
44 def patch_c_new_id(arch, e):
45  return e.replace_expr(arch.id2newCid)
46 
def patch_c_new_id
Definition: ir2C.py:43

+ Here is the caller graph for this function:

def miasm2.ir.ir2C.set_pc (   ir_arch,
  src 
)

Definition at line 150 of file ir2C.py.

151 def set_pc(ir_arch, src):
152  dst = ir_arch.jit_pc
153  if not isinstance(src, m2_expr.Expr):
154  src = m2_expr.ExprInt_from(dst, src)
155  e = m2_expr.ExprAff(dst, src.zeroExtend(dst.size))
156  return e
157 
def set_pc
Definition: ir2C.py:150

+ Here is the caller graph for this function:

Variable Documentation

tuple miasm2.ir.ir2C.c = m2_expr.ExprId(name, size)

Definition at line 23 of file ir2C.py.

string miasm2.ir.ir2C.code_exception_at_instr = r""

Definition at line 91 of file ir2C.py.

string miasm2.ir.ir2C.code_exception_at_instr_noautomod = r""

Definition at line 113 of file ir2C.py.

string miasm2.ir.ir2C.code_exception_fetch_mem_at_instr = r""

Definition at line 59 of file ir2C.py.

string miasm2.ir.ir2C.code_exception_fetch_mem_at_instr_noautomod = r""

Definition at line 75 of file ir2C.py.

string miasm2.ir.ir2C.code_exception_fetch_mem_post_instr = r""

Definition at line 66 of file ir2C.py.

string miasm2.ir.ir2C.code_exception_fetch_mem_post_instr_noautomod = r""

Definition at line 82 of file ir2C.py.

string miasm2.ir.ir2C.code_exception_post_instr = r""

Definition at line 99 of file ir2C.py.

string miasm2.ir.ir2C.code_exception_post_instr_noautomod = r""

Definition at line 120 of file ir2C.py.

tuple miasm2.ir.ir2C.console_handler = logging.StreamHandler()

Definition at line 9 of file ir2C.py.

tuple miasm2.ir.ir2C.exception_flags = m2_expr.ExprId('exception_flags', 32)

Definition at line 147 of file ir2C.py.

string miasm2.ir.ir2C.goto_local_code = r""

Definition at line 132 of file ir2C.py.

tuple miasm2.ir.ir2C.log_to_c_h = logging.getLogger("ir_helper")

Definition at line 8 of file ir2C.py.

int miasm2.ir.ir2C.mask_int = 0xffffffffffffffff

Definition at line 47 of file ir2C.py.

dictionary miasm2.ir.ir2C.my_size_mask
Initial value:
1 = {1: 1, 2: 3, 3: 7, 7: 0x7f,
2  8: 0xFF,
3  16: 0xFFFF,
4  32: 0xFFFFFFFF,
5  64: 0xFFFFFFFFFFFFFFFFL}

Definition at line 141 of file ir2C.py.

string miasm2.ir.ir2C.name = 'pfmem%.2d_%d'

Definition at line 22 of file ir2C.py.

string miasm2.ir.ir2C.pre_instr_test_exception = r""

Definition at line 50 of file ir2C.py.

list miasm2.ir.ir2C.prefetch_id = []

Definition at line 17 of file ir2C.py.

dictionary miasm2.ir.ir2C.prefetch_id_size = {}

Definition at line 18 of file ir2C.py.

tuple miasm2.ir.ir2C.translator = Translator.to_language("C")

Definition at line 15 of file ir2C.py.