33 assert(isinstance(label, asmbloc.asm_label))
43 """Find the IRDst affectation and update dst, dst_linenb accordingly"""
44 if self.
_dst is not None:
47 for linenb, ir
in enumerate(self.
irs):
49 if isinstance(i.dst, m2_expr.ExprId)
and i.dst.name ==
"IRDst":
51 raise ValueError(
'Multiple destinations!')
59 """Find and replace the IRDst affectation's source by @value"""
64 for i, expr
in enumerate(ir):
65 if isinstance(expr.dst, m2_expr.ExprId)
and expr.dst.name ==
"IRDst":
66 ir[i] = m2_expr.ExprAff(expr.dst, value)
69 dst = property(_get_dst, _set_dst)
73 """Line number of the IRDst setting statement in the current irs"""
78 Computes the variables read and written by each instructions
79 Initialize attributes needed for in/out and reach computation.
80 @regs_ids : ids of registers used in IR
85 for _
in xrange(len(self.
irs))]
87 for _
in xrange(len(self.
irs))]
88 self.
cur_kill = [{reg: set()
for reg
in regs_ids}
89 for _
in xrange(len(self.
irs))]
91 for _
in xrange(len(self.
irs))]
92 self.
defout = [{reg: set()
for reg
in regs_ids}
93 for _
in xrange(len(self.
irs))]
95 for k, ir
in enumerate(self.
irs):
98 r.update(x
for x
in i.get_r(
True)
99 if isinstance(x, m2_expr.ExprId))
100 w.update(x
for x
in i.get_w()
101 if isinstance(x, m2_expr.ExprId))
102 if isinstance(i.dst, m2_expr.ExprMem):
103 r.update(x
for x
in i.dst.arg.get_r(
True)
104 if isinstance(x, m2_expr.ExprId))
107 if isinstance(x, m2_expr.ExprId))
113 o.append(
'%s' % self.
label)
114 for expr
in self.
irs:
124 def __init__(self, arch, attrib, symbol_pool=None):
125 if symbol_pool
is None:
129 self.
pc = arch.getpc(attrib)
130 self.
sp = arch.getsp(attrib)
135 ir_bloc_cur, ir_blocs_extra = self.get_ir(l)
136 return ir_bloc_cur, ir_blocs_extra
139 """Transforms an ExprId/ExprInt/label/int into a label
140 @ad: an ExprId/ExprInt/label/int"""
142 if (isinstance(ad, m2_expr.ExprId)
and
143 isinstance(ad.name, asmbloc.asm_label)):
145 if isinstance(ad, m2_expr.ExprInt):
147 if type(ad)
in [int, long]:
148 ad = self.symbol_pool.getby_offset_create(ad)
149 elif isinstance(ad, asmbloc.asm_label):
150 ad = self.symbol_pool.getby_name_create(ad.name)
154 """Returns the irbloc associated to an ExprId/ExprInt/label/int
155 @ad: an ExprId/ExprInt/label/int"""
158 return self.blocs.get(label,
None)
161 b = asmbloc.asm_bloc(l)
167 If multiple affection to a same ExprId are present in @affect_list,
168 merge them (in place).
169 For instance, XCGH AH, AL semantic is
171 RAX = {RAX[0:8],0,8, RAX[0:8],8,16, RAX[16:64],16,64}
172 RAX = {RAX[8:16],0,8, RAX[8:64],8,64}
174 This function will update @affect_list to replace previous ExprAff by
176 RAX = {RAX[8:16],0,8, RAX[0:8],8,16, RAX[16:64],16,64}
182 for expr
in affect_list:
183 effect[expr.dst] = effect.get(expr.dst, []) + [expr]
186 for dst, expr_list
in effect.items():
187 if len(expr_list) <= 1:
191 if any(map(
lambda e: not(isinstance(e.src, m2_expr.ExprCompose)),
196 e_colision = reduce(
lambda x, y: x.union(y),
197 (e.get_modified_slice()
for e
in expr_list),
200 known_intervals = sorted([(x[1], x[2])
for x
in e_colision])
205 remaining = ((m2_expr.ExprSlice(dst, *interval),
208 for interval
in missing_i)
211 slices = sorted(e_colision.union(remaining), key=
lambda x: x[1])
212 final_dst = m2_expr.ExprCompose(slices)
215 for expr
in expr_list:
216 affect_list.remove(expr)
219 affect_list.append(m2_expr.ExprAff(dst, final_dst))
224 for irb
in self.blocs.values():
226 if l.offset <= offset < l.offset + l.l:
231 c.irs.append([m2_expr.ExprAff(self.
pc, m2_expr.ExprInt_from(self.
pc,
242 ir_blocs_all.append(c)
243 ir_bloc_cur, ir_blocs_extra = self.
instr2ir(l)
245 if gen_pc_updt
is not False:
248 c.irs.append(ir_bloc_cur)
253 for b
in ir_blocs_extra:
254 b.lines = [l] * len(b.irs)
255 ir_blocs_all += ir_blocs_extra
270 all_pc = self.arch.pc.values()
279 if b.dst
is not None:
283 b.irs.append([m2_expr.ExprAff(self.IRDst, dst)])
284 b.lines.append(b.lines[-1])
290 self.set_empty_dst_to_next(bloc, ir_blocs)
291 self.gen_edges(bloc, ir_blocs)
294 self.irbloc_fix_regs_for_mode(irb, self.attrib)
297 for affect_list
in irb.irs:
298 self.merge_multi_affect(affect_list)
300 self.blocs[irb.label] = irb
304 """Returns the label associated to an instruction
305 @instr: current instruction"""
307 return self.symbol_pool.getby_offset_create(instr.offset)
311 l = self.symbol_pool.gen_label()
315 l = self.symbol_pool.getby_offset_create(instr.offset + instr.l)
319 for b
in self.blocs.values():
321 for i, r
in enumerate(ir):
326 for i, l
in enumerate(irs):
327 irs[i] = l.replace_expr(rep)
331 Calls get_rw(irb) for each bloc
332 @regs_ids : ids of registers used in IR
334 for b
in self.blocs.values():
338 return isinstance(l, m2_expr.ExprId)
and isinstance(l.name,
def expraff_fix_regs_for_mode
def set_empty_dst_to_next
def irbloc_fix_regs_for_mode
def expr_fix_regs_for_mode