Miasm2
 All Classes Namespaces Files Functions Variables Typedefs Properties Macros
Classes | Functions | Variables
miasm2.core.parse_asm Namespace Reference

Classes

class  Directive
 
class  DirectiveAlign
 
class  DirectiveDontSplit
 
class  DirectiveSplit
 

Functions

def guess_next_new_label
 
def replace_expr_labels
 
def replace_orphan_labels
 
def parse_txt
 

Variables

dictionary declarator
 
dictionary size2pck
 
tuple EMPTY_RE = re.compile(r'\s*$')
 
tuple COMMENT_RE = re.compile(r'\s*;\S*')
 
tuple LOCAL_LABEL_RE = re.compile(r'\s*(\.L\S+)\s*:')
 
tuple DIRECTIVE_START_RE = re.compile(r'\s*\.')
 
tuple DIRECTIVE_RE = re.compile(r'\s*\.(\S+)')
 
tuple LABEL_RE = re.compile(r'\s*(\S+)\s*:')
 
tuple FORGET_LABEL_RE = re.compile(r'\s*\.LF[BE]\d\s*:')
 
int STATE_NO_BLOC = 0
 
int STATE_IN_BLOC = 1
 

Function Documentation

def miasm2.core.parse_asm.guess_next_new_label (   symbol_pool)
Generate a new label
@symbol_pool: the asm_symbol_pool instance

Definition at line 63 of file parse_asm.py.

63 
64 def guess_next_new_label(symbol_pool):
65  """Generate a new label
66  @symbol_pool: the asm_symbol_pool instance"""
67  i = 0
68  gen_name = "loc_%.8X"
69  while True:
70  name = gen_name % i
71  label = symbol_pool.getby_name(name)
72  if label is None:
73  return symbol_pool.add_label(name)
74  i += 1
75 

+ Here is the caller graph for this function:

def miasm2.core.parse_asm.parse_txt (   mnemo,
  attrib,
  txt,
  symbol_pool = None 
)
Parse an assembly listing. Returns a couple (blocks, symbol_pool), where
blocks is a list of asm_bloc and symbol_pool the associated asm_symbol_pool

@mnemo: architecture used
@attrib: architecture attribute
@txt: assembly listing
@symbol_pool: (optional) the asm_symbol_pool instance used to handle labels
of the listing

Definition at line 105 of file parse_asm.py.

106 def parse_txt(mnemo, attrib, txt, symbol_pool=None):
107  """Parse an assembly listing. Returns a couple (blocks, symbol_pool), where
108  blocks is a list of asm_bloc and symbol_pool the associated asm_symbol_pool
109 
110  @mnemo: architecture used
111  @attrib: architecture attribute
112  @txt: assembly listing
113  @symbol_pool: (optional) the asm_symbol_pool instance used to handle labels
114  of the listing
115 
116  """
117 
118  if symbol_pool is None:
119  symbol_pool = asmbloc.asm_symbol_pool()
120 
121  C_NEXT = asmbloc.asm_constraint.c_next
122  C_TO = asmbloc.asm_constraint.c_to
123 
124  lines = []
125  # parse each line
126  for line in txt.split('\n'):
127  # empty
128  if EMPTY_RE.match(line):
129  continue
130  # comment
131  if COMMENT_RE.match(line):
132  continue
133  # labels to forget
134  if FORGET_LABEL_RE.match(line):
135  continue
136  # label beginning with .L
137  match_re = LABEL_RE.match(line)
138  if match_re:
139  label_name = match_re.group(1)
140  label = symbol_pool.getby_name_create(label_name)
141  lines.append(label)
142  continue
143  # directive
144  if DIRECTIVE_START_RE.match(line):
145  match_re = DIRECTIVE_RE.match(line)
146  directive = match_re.group(1)
147  if directive in ['text', 'data', 'bss']:
148  continue
149  if directive in ['string', 'ascii']:
150  # XXX HACK
151  line = line.replace(r'\n', '\n').replace(r'\r', '\r')
152  raw = line[line.find(r'"') + 1:line.rfind(r'"')]
153  raw = raw.decode('string_escape')
154  if directive == 'string':
155  raw += "\x00"
156  lines.append(asmbloc.asm_raw(raw))
157  continue
158  if directive == 'ustring':
159  # XXX HACK
160  line = line.replace(r'\n', '\n').replace(r'\r', '\r')
161  raw = line[line.find(r'"') + 1:line.rfind(r'"')] + "\x00"
162  raw = raw.decode('string_escape')
163  raw = "".join([string + '\x00' for string in raw])
164  lines.append(asmbloc.asm_raw(raw))
165  continue
166  if directive in declarator:
167  data_raw = line[match_re.end():].split(' ', 1)[1]
168  data_raw = data_raw.split(',')
169  size = declarator[directive]
170  expr_list = []
171 
172  # parser
173  base_expr = gen_base_expr()[2]
174  my_var_parser = parse_ast(lambda x: m2_expr.ExprId(x, size),
175  lambda x:
176  m2_expr.ExprInt(x, size))
177  base_expr.setParseAction(my_var_parser)
178 
179  for element in data_raw:
180  element = element.strip()
181  element_expr = base_expr.parseString(element)[0]
182  expr_list.append(element_expr.canonize())
183 
184  raw_data = asmbloc.asm_raw(expr_list)
185  raw_data.element_size = size
186  lines.append(raw_data)
187  continue
188  if directive == 'comm':
189  # TODO
190  continue
191  if directive == 'split': # custom command
192  lines.append(DirectiveSplit())
193  continue
194  if directive == 'dontsplit': # custom command
195  lines.append(DirectiveDontSplit())
196  continue
197  if directive == "align":
198  align_value = int(line[match_re.end():], 0)
199  lines.append(DirectiveAlign(align_value))
200  continue
201  if directive in ['file', 'intel_syntax', 'globl', 'local',
202  'type', 'size', 'align', 'ident', 'section']:
203  continue
204  if directive[0:4] == 'cfi_':
205  continue
206 
207  raise ValueError("unknown directive %s" % str(directive))
208 
209  # label
210  match_re = LABEL_RE.match(line)
211  if match_re:
212  label_name = match_re.group(1)
213  label = symbol_pool.getby_name_create(label_name)
214  lines.append(label)
215  continue
216 
217  # code
218  if ';' in line:
219  line = line[:line.find(';')]
220  line = line.strip(' ').strip('\t')
221  instr = mnemo.fromstring(line, attrib)
222 
223  # replace orphan asm_label with labels from symbol_pool
224  replace_orphan_labels(instr, symbol_pool)
225 
226  if instr.dstflow():
227  instr.dstflow2label(symbol_pool)
228  lines.append(instr)
229 
230  asmbloc.log_asmbloc.info("___pre asm oki___")
231  # make blocks
232 
233  cur_block = None
234  state = STATE_NO_BLOC
235  i = 0
236  blocks = []
237  block_to_nlink = None
238  block_may_link = False
239  delayslot = 0
240  while i < len(lines):
241  if delayslot:
242  if delayslot == 0:
243  state = STATE_NO_BLOC
244  else:
245  delayslot -= 1
246  line = lines[i]
247  # no current block
248  if state == STATE_NO_BLOC:
249  if isinstance(line, DirectiveDontSplit):
250  block_to_nlink = cur_block
251  i += 1
252  continue
253  elif isinstance(line, DirectiveSplit):
254  block_to_nlink = None
255  i += 1
256  continue
257  elif not isinstance(line, asmbloc.asm_label):
258  # First line must be a label. If it's not the case, generate
259  # it.
260  label = guess_next_new_label(symbol_pool)
261  cur_block = asmbloc.asm_bloc(label, alignment=mnemo.alignment)
262  else:
263  cur_block = asmbloc.asm_bloc(line, alignment=mnemo.alignment)
264  i += 1
265  # Generate the current bloc
266  blocks.append(cur_block)
267  state = STATE_IN_BLOC
268  if block_to_nlink:
269  block_to_nlink.addto(
270  asmbloc.asm_constraint(cur_block.label,
271  C_NEXT))
272  block_to_nlink = None
273  continue
274 
275  # in block
276  elif state == STATE_IN_BLOC:
277  if isinstance(line, DirectiveSplit):
278  state = STATE_NO_BLOC
279  block_to_nlink = None
280  elif isinstance(line, DirectiveDontSplit):
281  state = STATE_NO_BLOC
282  block_to_nlink = cur_block
283  elif isinstance(line, DirectiveAlign):
284  cur_block.alignment = line.alignment
285  elif isinstance(line, asmbloc.asm_raw):
286  cur_block.addline(line)
287  block_to_nlink = cur_block
288  elif isinstance(line, asmbloc.asm_label):
289  if block_to_nlink:
290  cur_block.addto(
291  asmbloc.asm_constraint(line, C_NEXT))
292  block_to_nlink = None
293  state = STATE_NO_BLOC
294  continue
295  # instruction
296  elif isinstance(line, instruction):
297  cur_block.addline(line)
298  block_to_nlink = cur_block
299  if not line.breakflow():
300  i += 1
301  continue
302  if delayslot:
303  raise RuntimeError("Cannot have breakflow in delayslot")
304  if line.dstflow():
305  for dst in line.getdstflow(symbol_pool):
306  if not isinstance(dst, m2_expr.ExprId):
307  continue
308  if dst in mnemo.regs.all_regs_ids:
309  continue
310  cur_block.addto(asmbloc.asm_constraint(dst, C_TO))
311 
312  if not line.splitflow():
313  block_to_nlink = None
314 
315  delayslot = line.delayslot
316  if delayslot == 0:
317  state = STATE_NO_BLOC
318  else:
319  raise RuntimeError("unknown class %s" % line.__class__)
320  i += 1
321 
322  for block in blocks:
323  asmbloc.log_asmbloc.info(block)
324  return blocks, symbol_pool
def gen_base_expr
Definition: cpu.py:309

+ Here is the call graph for this function:

def miasm2.core.parse_asm.replace_expr_labels (   expr,
  symbol_pool,
  replace_id 
)
Create asm_label of the expression @expr in the @symbol_pool
Update @replace_id

Definition at line 76 of file parse_asm.py.

76 
77 def replace_expr_labels(expr, symbol_pool, replace_id):
78  """Create asm_label of the expression @expr in the @symbol_pool
79  Update @replace_id"""
80 
81  if not (isinstance(expr, m2_expr.ExprId) and
82  isinstance(expr.name, asmbloc.asm_label)):
83  return expr
84 
85  old_lbl = expr.name
86  new_lbl = symbol_pool.getby_name_create(old_lbl.name)
87  replace_id[expr] = m2_expr.ExprId(new_lbl, expr.size)
88  return replace_id[expr]
89 

+ Here is the caller graph for this function:

def miasm2.core.parse_asm.replace_orphan_labels (   instr,
  symbol_pool 
)
Link orphan labels used by @instr to the @symbol_pool

Definition at line 90 of file parse_asm.py.

90 
91 def replace_orphan_labels(instr, symbol_pool):
92  """Link orphan labels used by @instr to the @symbol_pool"""
93 
94  for i, arg in enumerate(instr.args):
95  replace_id = {}
96  arg.visit(lambda e: replace_expr_labels(e,
97  symbol_pool,
98  replace_id))
99  instr.args[i] = instr.args[i].replace_expr(replace_id)
100 

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

tuple miasm2.core.parse_asm.COMMENT_RE = re.compile(r'\s*;\S*')

Definition at line 24 of file parse_asm.py.

dictionary miasm2.core.parse_asm.declarator
Initial value:
1 = {'byte': 8,
2  'word': 16,
3  'dword': 32,
4  'qword': 64,
5  'long': 32,
6  }

Definition at line 10 of file parse_asm.py.

tuple miasm2.core.parse_asm.DIRECTIVE_RE = re.compile(r'\s*\.(\S+)')

Definition at line 27 of file parse_asm.py.

tuple miasm2.core.parse_asm.DIRECTIVE_START_RE = re.compile(r'\s*\.')

Definition at line 26 of file parse_asm.py.

tuple miasm2.core.parse_asm.EMPTY_RE = re.compile(r'\s*$')

Definition at line 23 of file parse_asm.py.

tuple miasm2.core.parse_asm.FORGET_LABEL_RE = re.compile(r'\s*\.LF[BE]\d\s*:')

Definition at line 29 of file parse_asm.py.

tuple miasm2.core.parse_asm.LABEL_RE = re.compile(r'\s*(\S+)\s*:')

Definition at line 28 of file parse_asm.py.

tuple miasm2.core.parse_asm.LOCAL_LABEL_RE = re.compile(r'\s*(\.L\S+)\s*:')

Definition at line 25 of file parse_asm.py.

dictionary miasm2.core.parse_asm.size2pck
Initial value:
1 = {8: 'B',
2  16: 'H',
3  32: 'I',
4  64: 'Q',
5  }

Definition at line 17 of file parse_asm.py.

int miasm2.core.parse_asm.STATE_IN_BLOC = 1

Definition at line 102 of file parse_asm.py.

int miasm2.core.parse_asm.STATE_NO_BLOC = 0

Definition at line 101 of file parse_asm.py.