Exemplo n.º 1
0
    def disbloc(self, addr, cpu, vm):
        "Disassemble a new bloc and JiT it"

        # Get the bloc
        if isinstance(addr, asmbloc.asm_label):
            addr = addr.offset

        l = self.ir_arch.symbol_pool.getby_offset_create(addr)
        cur_bloc = asmbloc.asm_bloc(l)

        # Disassemble it
        try:
            asmbloc.dis_bloc(
                self.ir_arch.arch,
                self.bs,
                cur_bloc,
                addr,
                set(),
                self.ir_arch.symbol_pool,
                [],
                follow_call=False,
                patch_instr_symb=True,
                dontdis_retcall=False,
                lines_wd=self.options["jit_maxline"],
                # max 10 asm lines
                attrib=self.ir_arch.attrib,
                split_dis=self.split_dis)
        except IOError:
            # vm_exception_flag is set
            pass

        # Logging
        if self.log_newbloc:
            print cur_bloc
        if self.disasm_cb is not None:
            self.disasm_cb(cur_bloc)

        # Check for empty blocks
        if not cur_bloc.lines:
            raise ValueError("Cannot JIT a block without any assembly line")

        # Update label -> bloc
        self.lbl2bloc[l] = cur_bloc

        # Store min/max bloc address needed in jit automod code
        self.get_bloc_min_max(cur_bloc)

        # JiT it
        self.add_bloc(cur_bloc)

        # Update jitcode mem range
        self.add_bloc_to_mem_interval(vm, cur_bloc)
Exemplo n.º 2
0
    def disbloc(self, addr, cpu, vm):
        "Disassemble a new bloc and JiT it"

        # Get the bloc
        if isinstance(addr, asmbloc.asm_label):
            addr = addr.offset

        l = self.ir_arch.symbol_pool.getby_offset_create(addr)
        cur_bloc = asmbloc.asm_bloc(l)

        # Disassemble it
        try:
            asmbloc.dis_bloc(
                self.ir_arch.arch,
                self.bs,
                cur_bloc,
                addr,
                set(),
                self.ir_arch.symbol_pool,
                [],
                follow_call=False,
                dontdis_retcall=False,
                lines_wd=self.options["jit_maxline"],
                # max 10 asm lines
                attrib=self.ir_arch.attrib,
                split_dis=self.split_dis,
            )
        except IOError:
            # vm_exception_flag is set
            pass

        # Logging
        if self.log_newbloc:
            print cur_bloc
        if self.disasm_cb is not None:
            self.disasm_cb(cur_bloc)

        # Check for empty blocks
        if not cur_bloc.lines:
            raise ValueError("Cannot JIT a block without any assembly line")

        # Update label -> bloc
        self.lbl2bloc[l] = cur_bloc

        # Store min/max bloc address needed in jit automod code
        self.get_bloc_min_max(cur_bloc)

        # JiT it
        self.add_bloc(cur_bloc)

        # Update jitcode mem range
        self.add_bloc_to_mem_interval(vm, cur_bloc)
Exemplo n.º 3
0
    def disbloc(self, addr, vm):
        """Disassemble a new bloc and JiT it
        @addr: address of the block to disassemble (asm_label or int)
        @vm: VmMngr instance
        """

        # Get the bloc
        if isinstance(addr, asmbloc.asm_label):
            addr = addr.offset

        # Prepare disassembler
        self.mdis.job_done.clear()
        self.mdis.lines_wd = self.options["jit_maxline"]
        self.mdis.dis_bloc_callback = self.disasm_cb

        # Disassemble it
        try:
            cur_bloc = self.mdis.dis_bloc(addr)
        except IOError:
            # vm_exception_flag is set
            cur_bloc = asmbloc.asm_bloc(label)

        # Logging
        if self.log_newbloc:
            print cur_bloc

        # Check for empty blocks
        if not cur_bloc.lines:
            raise ValueError("Cannot JIT a block without any assembly line")

        # Update label -> bloc
        self.lbl2bloc[cur_bloc.label] = cur_bloc

        # Store min/max bloc address needed in jit automod code
        self.get_bloc_min_max(cur_bloc)

        # JiT it
        self.add_bloc(cur_bloc)

        # Update jitcode mem range
        self.add_bloc_to_mem_interval(vm, cur_bloc)
Exemplo n.º 4
0
Arquivo: ir.py Projeto: blaquee/miasm
 def add_instr(self, l, ad=0, gen_pc_updt = False):
     b = asm_bloc(self.gen_label())
     b.lines = [l]
     self.add_bloc(b, gen_pc_updt)
Exemplo n.º 5
0
 def add_instr(self, l, ad=0, gen_pc_updt=False):
     b = asm_bloc(self.gen_label())
     b.lines = [l]
     self.add_bloc(b, gen_pc_updt)
Exemplo n.º 6
0
def parse_txt(mnemo, attrib, txt, symbol_pool=None, gen_label_index=0):
    if symbol_pool is None:
        symbol_pool = asmbloc.asm_symbol_pool()

    lines_text = []
    lines_data = []
    lines_bss = []

    C_NEXT = asmbloc.asm_constraint.c_next
    C_TO = asmbloc.asm_constraint.c_to

    lines = lines_text
    # parse each line
    for line in txt.split('\n'):
        # empty
        if re.match(r'\s*$', line):
            continue
        # comment
        if re.match(r'\s*;\S*', line):
            continue
        # labels to forget
        r = re.match(r'\s*\.LF[BE]\d\s*:', line)
        if r:
            continue
        # label beginning with .L
        r = re.match(r'\s*(\.L\S+)\s*:', line)
        if r:
            l = r.groups()[0]
            l = symbol_pool.getby_name_create(l)
            lines.append(l)
            continue
        # directive
        if re.match(r'\s*\.', line):
            r = re.match(r'\s*\.(\S+)', line)
            directive = r.groups()[0]
            if directive == 'text':
                lines = lines_text
                continue
            if directive == 'data':
                lines = lines_data
                continue
            if directive == 'bss':
                lines = lines_bss
                continue
            if directive in ['string', 'ascii']:
                # XXX HACK
                line = line.replace(r'\n', '\n').replace(r'\r', '\r')
                raw = line[line.find(r'"') + 1:line.rfind(r"'")]
                raw = raw.decode('string_escape')
                if directive == 'string':
                    raw += "\x00"
                lines.append(asmbloc.asm_raw(raw))
                continue
            if directive == 'ustring':
                # XXX HACK
                line = line.replace(r'\n', '\n').replace(r'\r', '\r')
                raw = line[line.find(r'"') + 1:line.rfind(r"'")] + "\x00"
                raw = raw.decode('string_escape')
                raw = "".join([string + '\x00' for string in raw])
                lines.append(asmbloc.asm_raw(raw))
                continue
            if directive in declarator:
                data_raw = line[r.end():].split(' ', 1)[1]
                data_raw = data_raw.split(',')
                size = declarator[directive]
                data_int = []

                # parser
                base_expr = gen_base_expr()[2]
                my_var_parser = parse_ast(lambda x: m2_expr.ExprId(x, size),
                                          lambda x:
                                              m2_expr.ExprInt_fromsize(size, x))
                base_expr.setParseAction(my_var_parser)

                for b in data_raw:
                    b = b.strip()
                    x = base_expr.parseString(b)[0]
                    data_int.append(x.canonize())

                raw = data_int
                x = asmbloc.asm_raw(raw)
                x.element_size = size
                lines.append(x)
                continue
            if directive == 'comm':
                # TODO
                continue
            if directive == 'split':  # custom command
                x = asmbloc.asm_raw()
                x.split = True
                lines.append(x)
                continue
            if directive == 'dontsplit':  # custom command
                lines.append(asmbloc.asm_raw())
                continue
            if directive == "align":
                align_value = int(line[r.end():])
                lines.append(DirectiveAlign(align_value))
                continue
            if directive in ['file', 'intel_syntax', 'globl', 'local',
                             'type', 'size', 'align', 'ident', 'section']:
                continue
            if directive[0:4] == 'cfi_':
                continue

            raise ValueError("unknown directive %s" % str(directive))

        # label
        r = re.match(r'\s*(\S+)\s*:', line)
        if r:
            l = r.groups()[0]
            l = symbol_pool.getby_name_create(l)
            lines.append(l)
            continue

        # code
        if ';' in line:
            line = line[:line.find(';')]
        line = line.strip(' ').strip('\t')
        instr = mnemo.fromstring(line, attrib)

        # replace orphan asm_label with labels from symbol_pool
        replace_orphan_labels(instr, symbol_pool)

        if instr.dstflow():
            instr.dstflow2label(symbol_pool)
        lines.append(instr)

    asmbloc.log_asmbloc.info("___pre asm oki___")
    # make blocs

    blocs_sections = []
    bloc_num = 0
    b = None
    for lines in [lines_text, lines_data, lines_bss]:
        state = 0
        i = 0
        blocs = []
        blocs_sections.append(blocs)
        bloc_to_nlink = None
        block_may_link = False
        while i < len(lines):
            # no current bloc
            if state == 0:
                if not isinstance(lines[i], asmbloc.asm_label):
                    l = guess_next_new_label(symbol_pool)
                    lines[i:i] = [l]
                else:
                    l = lines[i]
                    b = asmbloc.asm_bloc(l, alignment=mnemo.alignment)
                    b.bloc_num = bloc_num
                    bloc_num += 1
                    blocs.append(b)
                    state = 1
                    i += 1
                    if bloc_to_nlink:
                        bloc_to_nlink.addto(asmbloc.asm_constraint(b.label,
                                                                   C_NEXT))
                        bloc_to_nlink = None

            # in bloc
            elif state == 1:
                if isinstance(lines[i], asmbloc.asm_raw):
                    if hasattr(lines[i], 'split'):
                        state = 0
                        block_may_link = False
                        i += 1
                    else:
                        state = 1
                        block_may_link = True
                        b.addline(lines[i])
                        i += 1
                elif isinstance(lines[i], DirectiveAlign):
                    b.alignment = lines[i].alignment
                    i += 1
                # asmbloc.asm_label
                elif isinstance(lines[i], asmbloc.asm_label):
                    if block_may_link:
                        b.addto(
                            asmbloc.asm_constraint(lines[i], C_NEXT))
                        block_may_link = False
                    state = 0
                # instruction
                else:
                    b.addline(lines[i])
                    if lines[i].dstflow():
                        for x in lines[i].getdstflow(symbol_pool):
                            if not isinstance(x, m2_expr.ExprId):
                                continue
                            if x in mnemo.regs.all_regs_ids:
                                continue
                            b.addto(asmbloc.asm_constraint(x, C_TO))

                        # TODO XXX redo this really

                        if not lines[i].breakflow() and i + 1 < len(lines):
                            if isinstance(lines[i + 1], asmbloc.asm_label):
                                l = lines[i + 1]
                            else:
                                l = guess_next_new_label(symbol_pool)
                                lines[i + 1:i + 1] = [l]
                        else:
                            state = 0

                        if lines[i].splitflow():
                            bloc_to_nlink = b
                    if not lines[i].breakflow() or lines[i].splitflow():
                        block_may_link = True
                    else:
                        block_may_link = False

                    i += 1

    for block in blocs_sections[0]:
        asmbloc.log_asmbloc.info(block)

    return blocs_sections, symbol_pool
Exemplo n.º 7
0
def 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

    """

    if symbol_pool is None:
        symbol_pool = asmbloc.asm_symbol_pool()

    C_NEXT = asmbloc.asm_constraint.c_next
    C_TO = asmbloc.asm_constraint.c_to

    lines = []
    # parse each line
    for line in txt.split('\n'):
        # empty
        if EMPTY_RE.match(line):
            continue
        # comment
        if COMMENT_RE.match(line):
            continue
        # labels to forget
        if FORGET_LABEL_RE.match(line):
            continue
        # label beginning with .L
        match_re = LABEL_RE.match(line)
        if match_re:
            label_name = match_re.group(1)
            label = symbol_pool.getby_name_create(label_name)
            lines.append(label)
            continue
        # directive
        if DIRECTIVE_START_RE.match(line):
            match_re = DIRECTIVE_RE.match(line)
            directive = match_re.group(1)
            if directive in ['text', 'data', 'bss']:
                continue
            if directive in ['string', 'ascii']:
                # XXX HACK
                line = line.replace(r'\n', '\n').replace(r'\r', '\r')
                raw = line[line.find(r'"') + 1:line.rfind(r'"')]
                raw = raw.decode('string_escape')
                if directive == 'string':
                    raw += "\x00"
                lines.append(asmbloc.asm_raw(raw))
                continue
            if directive == 'ustring':
                # XXX HACK
                line = line.replace(r'\n', '\n').replace(r'\r', '\r')
                raw = line[line.find(r'"') + 1:line.rfind(r'"')] + "\x00"
                raw = raw.decode('string_escape')
                raw = "".join([string + '\x00' for string in raw])
                lines.append(asmbloc.asm_raw(raw))
                continue
            if directive in declarator:
                data_raw = line[match_re.end():].split(' ', 1)[1]
                data_raw = data_raw.split(',')
                size = declarator[directive]
                expr_list = []

                # parser
                base_expr = gen_base_expr()[2]
                my_var_parser = parse_ast(lambda x: m2_expr.ExprId(x, size),
                                          lambda x:
                                              m2_expr.ExprInt(x, size))
                base_expr.setParseAction(my_var_parser)

                for element in data_raw:
                    element = element.strip()
                    element_expr = base_expr.parseString(element)[0]
                    expr_list.append(element_expr.canonize())

                raw_data = asmbloc.asm_raw(expr_list)
                raw_data.element_size = size
                lines.append(raw_data)
                continue
            if directive == 'comm':
                # TODO
                continue
            if directive == 'split':  # custom command
                lines.append(DirectiveSplit())
                continue
            if directive == 'dontsplit':  # custom command
                lines.append(DirectiveDontSplit())
                continue
            if directive == "align":
                align_value = int(line[match_re.end():], 0)
                lines.append(DirectiveAlign(align_value))
                continue
            if directive in ['file', 'intel_syntax', 'globl', 'local',
                             'type', 'size', 'align', 'ident', 'section']:
                continue
            if directive[0:4] == 'cfi_':
                continue

            raise ValueError("unknown directive %s" % str(directive))

        # label
        match_re = LABEL_RE.match(line)
        if match_re:
            label_name = match_re.group(1)
            label = symbol_pool.getby_name_create(label_name)
            lines.append(label)
            continue

        # code
        if ';' in line:
            line = line[:line.find(';')]
        line = line.strip(' ').strip('\t')
        instr = mnemo.fromstring(line, attrib)

        # replace orphan asm_label with labels from symbol_pool
        replace_orphan_labels(instr, symbol_pool)

        if instr.dstflow():
            instr.dstflow2label(symbol_pool)
        lines.append(instr)

    asmbloc.log_asmbloc.info("___pre asm oki___")
    # make blocks

    cur_block = None
    state = STATE_NO_BLOC
    i = 0
    blocks = asmbloc.AsmCFG()
    block_to_nlink = None
    delayslot = 0
    while i < len(lines):
        if delayslot:
            delayslot -= 1
            if delayslot == 0:
                state = STATE_NO_BLOC
        line = lines[i]
        # no current block
        if state == STATE_NO_BLOC:
            if isinstance(line, DirectiveDontSplit):
                block_to_nlink = cur_block
                i += 1
                continue
            elif isinstance(line, DirectiveSplit):
                block_to_nlink = None
                i += 1
                continue
            elif not isinstance(line, asmbloc.asm_label):
                # First line must be a label. If it's not the case, generate
                # it.
                label = guess_next_new_label(symbol_pool)
                cur_block = asmbloc.asm_bloc(label, alignment=mnemo.alignment)
            else:
                cur_block = asmbloc.asm_bloc(line, alignment=mnemo.alignment)
                i += 1
            # Generate the current bloc
            blocks.add_node(cur_block)
            state = STATE_IN_BLOC
            if block_to_nlink:
                block_to_nlink.addto(
                    asmbloc.asm_constraint(cur_block.label,
                                           C_NEXT))
            block_to_nlink = None
            continue

        # in block
        elif state == STATE_IN_BLOC:
            if isinstance(line, DirectiveSplit):
                state = STATE_NO_BLOC
                block_to_nlink = None
            elif isinstance(line, DirectiveDontSplit):
                state = STATE_NO_BLOC
                block_to_nlink = cur_block
            elif isinstance(line, DirectiveAlign):
                cur_block.alignment = line.alignment
            elif isinstance(line, asmbloc.asm_raw):
                cur_block.addline(line)
                block_to_nlink = cur_block
            elif isinstance(line, asmbloc.asm_label):
                if block_to_nlink:
                    cur_block.addto(
                        asmbloc.asm_constraint(line, C_NEXT))
                    block_to_nlink = None
                state = STATE_NO_BLOC
                continue
            # instruction
            elif isinstance(line, instruction):
                cur_block.addline(line)
                block_to_nlink = cur_block
                if not line.breakflow():
                    i += 1
                    continue
                if delayslot:
                    raise RuntimeError("Cannot have breakflow in delayslot")
                if line.dstflow():
                    for dst in line.getdstflow(symbol_pool):
                        if not isinstance(dst, m2_expr.ExprId):
                            continue
                        if dst in mnemo.regs.all_regs_ids:
                            continue
                        cur_block.addto(asmbloc.asm_constraint(dst.name, C_TO))

                if not line.splitflow():
                    block_to_nlink = None

                delayslot = line.delayslot + 1
            else:
                raise RuntimeError("unknown class %s" % line.__class__)
        i += 1

    for block in blocks:
        # Fix multiple constraints
        block.fix_constraints()

        # Log block
        asmbloc.log_asmbloc.info(block)
    return blocks, symbol_pool
Exemplo n.º 8
0
Arquivo: ir.py Projeto: vardyh/miasm
 def add_instr(self, l, ad=0, gen_pc_updt = False):
     b = asmbloc.asm_bloc(l)
     b.lines = [l]
     self.add_bloc(b, gen_pc_updt)
Exemplo n.º 9
0
def 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

    """

    if symbol_pool is None:
        symbol_pool = asmbloc.asm_symbol_pool()

    C_NEXT = asmbloc.asm_constraint.c_next
    C_TO = asmbloc.asm_constraint.c_to

    lines = []
    # parse each line
    for line in txt.split('\n'):
        # empty
        if EMPTY_RE.match(line):
            continue
        # comment
        if COMMENT_RE.match(line):
            continue
        # labels to forget
        if FORGET_LABEL_RE.match(line):
            continue
        # label beginning with .L
        match_re = LABEL_RE.match(line)
        if match_re:
            label_name = match_re.group(1)
            label = symbol_pool.getby_name_create(label_name)
            lines.append(label)
            continue
        # directive
        if DIRECTIVE_START_RE.match(line):
            match_re = DIRECTIVE_RE.match(line)
            directive = match_re.group(1)
            if directive in ['text', 'data', 'bss']:
                continue
            if directive in ['string', 'ascii']:
                # XXX HACK
                line = line.replace(r'\n', '\n').replace(r'\r', '\r')
                raw = line[line.find(r'"') + 1:line.rfind(r'"')]
                raw = raw.decode('string_escape')
                if directive == 'string':
                    raw += "\x00"
                lines.append(asmbloc.asm_raw(raw))
                continue
            if directive == 'ustring':
                # XXX HACK
                line = line.replace(r'\n', '\n').replace(r'\r', '\r')
                raw = line[line.find(r'"') + 1:line.rfind(r'"')] + "\x00"
                raw = raw.decode('string_escape')
                raw = "".join([string + '\x00' for string in raw])
                lines.append(asmbloc.asm_raw(raw))
                continue
            if directive in declarator:
                data_raw = line[match_re.end():].split(' ', 1)[1]
                data_raw = data_raw.split(',')
                size = declarator[directive]
                expr_list = []

                # parser
                base_expr = gen_base_expr()[2]
                my_var_parser = parse_ast(lambda x: m2_expr.ExprId(x, size),
                                          lambda x: m2_expr.ExprInt(x, size))
                base_expr.setParseAction(my_var_parser)

                for element in data_raw:
                    element = element.strip()
                    element_expr = base_expr.parseString(element)[0]
                    expr_list.append(element_expr.canonize())

                raw_data = asmbloc.asm_raw(expr_list)
                raw_data.element_size = size
                lines.append(raw_data)
                continue
            if directive == 'comm':
                # TODO
                continue
            if directive == 'split':  # custom command
                lines.append(DirectiveSplit())
                continue
            if directive == 'dontsplit':  # custom command
                lines.append(DirectiveDontSplit())
                continue
            if directive == "align":
                align_value = int(line[match_re.end():], 0)
                lines.append(DirectiveAlign(align_value))
                continue
            if directive in [
                    'file', 'intel_syntax', 'globl', 'local', 'type', 'size',
                    'align', 'ident', 'section'
            ]:
                continue
            if directive[0:4] == 'cfi_':
                continue

            raise ValueError("unknown directive %s" % str(directive))

        # label
        match_re = LABEL_RE.match(line)
        if match_re:
            label_name = match_re.group(1)
            label = symbol_pool.getby_name_create(label_name)
            lines.append(label)
            continue

        # code
        if ';' in line:
            line = line[:line.find(';')]
        line = line.strip(' ').strip('\t')
        instr = mnemo.fromstring(line, attrib)

        # replace orphan asm_label with labels from symbol_pool
        replace_orphan_labels(instr, symbol_pool)

        if instr.dstflow():
            instr.dstflow2label(symbol_pool)
        lines.append(instr)

    asmbloc.log_asmbloc.info("___pre asm oki___")
    # make blocks

    cur_block = None
    state = STATE_NO_BLOC
    i = 0
    blocks = []
    block_to_nlink = None
    block_may_link = False
    delayslot = 0
    while i < len(lines):
        if delayslot:
            delayslot -= 1
            if delayslot == 0:
                state = STATE_NO_BLOC
        line = lines[i]
        # no current block
        if state == STATE_NO_BLOC:
            if isinstance(line, DirectiveDontSplit):
                block_to_nlink = cur_block
                i += 1
                continue
            elif isinstance(line, DirectiveSplit):
                block_to_nlink = None
                i += 1
                continue
            elif not isinstance(line, asmbloc.asm_label):
                # First line must be a label. If it's not the case, generate
                # it.
                label = guess_next_new_label(symbol_pool)
                cur_block = asmbloc.asm_bloc(label, alignment=mnemo.alignment)
            else:
                cur_block = asmbloc.asm_bloc(line, alignment=mnemo.alignment)
                i += 1
            # Generate the current bloc
            blocks.append(cur_block)
            state = STATE_IN_BLOC
            if block_to_nlink:
                block_to_nlink.addto(
                    asmbloc.asm_constraint(cur_block.label, C_NEXT))
            block_to_nlink = None
            continue

        # in block
        elif state == STATE_IN_BLOC:
            if isinstance(line, DirectiveSplit):
                state = STATE_NO_BLOC
                block_to_nlink = None
            elif isinstance(line, DirectiveDontSplit):
                state = STATE_NO_BLOC
                block_to_nlink = cur_block
            elif isinstance(line, DirectiveAlign):
                cur_block.alignment = line.alignment
            elif isinstance(line, asmbloc.asm_raw):
                cur_block.addline(line)
                block_to_nlink = cur_block
            elif isinstance(line, asmbloc.asm_label):
                if block_to_nlink:
                    cur_block.addto(asmbloc.asm_constraint(line, C_NEXT))
                    block_to_nlink = None
                state = STATE_NO_BLOC
                continue
            # instruction
            elif isinstance(line, instruction):
                cur_block.addline(line)
                block_to_nlink = cur_block
                if not line.breakflow():
                    i += 1
                    continue
                if delayslot:
                    raise RuntimeError("Cannot have breakflow in delayslot")
                if line.dstflow():
                    for dst in line.getdstflow(symbol_pool):
                        if not isinstance(dst, m2_expr.ExprId):
                            continue
                        if dst in mnemo.regs.all_regs_ids:
                            continue
                        cur_block.addto(asmbloc.asm_constraint(dst.name, C_TO))

                if not line.splitflow():
                    block_to_nlink = None

                delayslot = line.delayslot + 1
            else:
                raise RuntimeError("unknown class %s" % line.__class__)
        i += 1

    for block in blocks:
        # Fix multiple constraints
        block.fix_constraints()

        # Log block
        asmbloc.log_asmbloc.info(block)
    return blocks, symbol_pool
Exemplo n.º 10
0
dg = DiGraphSimplifier()
dg.enable_passes([remove_useless_blocks])
blocks = dg(blocks)

### Only two blocks should remain
assert len(blocks) == 2
assert first_block in blocks
assert last_block in blocks

## Graph the final output
open("graph2.dot", "w").write(blocks.dot())

# Test helper methods
## Label2block should always be updated
assert blocks.label2block(first_block.label) == first_block
my_block = asm_bloc(asm_label("testlabel"))
blocks.add_node(my_block)
assert len(blocks) == 3
assert blocks.label2block(first_block.label) == first_block
assert blocks.label2block(my_block.label) == my_block

## Bad blocks
assert len(list(blocks.get_bad_blocks())) == 0
assert len(list(blocks.get_bad_blocks_predecessors())) == 0
### Add a bad block, not linked
my_bad_block = asm_block_bad(asm_label("testlabel_bad"))
blocks.add_node(my_bad_block)
assert list(blocks.get_bad_blocks()) == [my_bad_block]
assert len(list(blocks.get_bad_blocks_predecessors())) == 0
### Link the bad block and update edges
### Indeed, a sub-element has been modified (bto from a block from blocks)
Exemplo n.º 11
0
def parse_txt(mnemo, attrib, txt, symbol_pool=None, gen_label_index=0):
    if symbol_pool is None:
        symbol_pool = asmbloc.asm_symbol_pool()

    lines_text = []
    lines_data = []
    lines_bss = []

    C_NEXT = asmbloc.asm_constraint.c_next
    C_TO = asmbloc.asm_constraint.c_to

    lines = lines_text
    # parse each line
    for line in txt.split('\n'):
        # empty
        if re.match(r'\s*$', line):
            continue
        # comment
        if re.match(r'\s*;\S*', line):
            continue
        # labels to forget
        r = re.match(r'\s*\.LF[BE]\d\s*:', line)
        if r:
            continue
        # label beginning with .L
        r = re.match(r'\s*(\.L\S+)\s*:', line)
        if r:
            l = r.groups()[0]
            l = symbol_pool.getby_name_create(l)
            lines.append(l)
            continue
        # directive
        if re.match(r'\s*\.', line):
            r = re.match(r'\s*\.(\S+)', line)
            directive = r.groups()[0]
            if directive == 'text':
                lines = lines_text
                continue
            if directive == 'data':
                lines = lines_data
                continue
            if directive == 'bss':
                lines = lines_bss
                continue
            if directive in ['string', 'ascii']:
                # XXX HACK
                line = line.replace(r'\n', '\n').replace(r'\r', '\r')
                raw = line[line.find(r'"') + 1:line.rfind(r"'")]
                raw = raw.decode('string_escape')
                if directive == 'string':
                    raw += "\x00"
                lines.append(asmbloc.asm_raw(raw))
                continue
            if directive == 'ustring':
                # XXX HACK
                line = line.replace(r'\n', '\n').replace(r'\r', '\r')
                raw = line[line.find(r'"') + 1:line.rfind(r"'")] + "\x00"
                raw = raw.decode('string_escape')
                raw = "".join([string + '\x00' for string in raw])
                lines.append(asmbloc.asm_raw(raw))
                continue
            if directive in declarator:
                data_raw = line[r.end():].split(' ', 1)[1]
                data_raw = data_raw.split(',')
                size = declarator[directive]
                data_int = []

                # parser
                base_expr = gen_base_expr()[2]
                my_var_parser = parse_ast(
                    lambda x: m2_expr.ExprId(x, size),
                    lambda x: m2_expr.ExprInt_fromsize(size, x))
                base_expr.setParseAction(my_var_parser)

                for b in data_raw:
                    b = b.strip()
                    x = base_expr.parseString(b)[0]
                    data_int.append(x.canonize())

                raw = data_int
                x = asmbloc.asm_raw(raw)
                x.element_size = size
                lines.append(x)
                continue
            if directive == 'comm':
                # TODO
                continue
            if directive == 'split':  # custom command
                x = asmbloc.asm_raw()
                x.split = True
                lines.append(x)
                continue
            if directive == 'dontsplit':  # custom command
                lines.append(asmbloc.asm_raw())
                continue
            if directive == "align":
                align_value = int(line[r.end():])
                lines.append(DirectiveAlign(align_value))
                continue
            if directive in [
                    'file', 'intel_syntax', 'globl', 'local', 'type', 'size',
                    'align', 'ident', 'section'
            ]:
                continue
            if directive[0:4] == 'cfi_':
                continue

            raise ValueError("unknown directive %s" % str(directive))

        # label
        r = re.match(r'\s*(\S+)\s*:', line)
        if r:
            l = r.groups()[0]
            l = symbol_pool.getby_name_create(l)
            lines.append(l)
            continue

        # code
        if ';' in line:
            line = line[:line.find(';')]
        line = line.strip(' ').strip('\t')
        instr = mnemo.fromstring(line, attrib)

        # replace orphan asm_label with labels from symbol_pool
        replace_orphan_labels(instr, symbol_pool)

        if instr.dstflow():
            instr.dstflow2label(symbol_pool)
        lines.append(instr)

    asmbloc.log_asmbloc.info("___pre asm oki___")
    # make blocs

    blocs_sections = []
    bloc_num = 0
    b = None
    for lines in [lines_text, lines_data, lines_bss]:
        state = 0
        i = 0
        blocs = []
        blocs_sections.append(blocs)
        bloc_to_nlink = None
        block_may_link = False
        while i < len(lines):
            # no current bloc
            if state == 0:
                if not isinstance(lines[i], asmbloc.asm_label):
                    l = guess_next_new_label(symbol_pool)
                    lines[i:i] = [l]
                else:
                    l = lines[i]
                    b = asmbloc.asm_bloc(l, alignment=mnemo.alignment)
                    b.bloc_num = bloc_num
                    bloc_num += 1
                    blocs.append(b)
                    state = 1
                    i += 1
                    if bloc_to_nlink:
                        bloc_to_nlink.addto(
                            asmbloc.asm_constraint(b.label, C_NEXT))
                        bloc_to_nlink = None

            # in bloc
            elif state == 1:
                if isinstance(lines[i], asmbloc.asm_raw):
                    if hasattr(lines[i], 'split'):
                        state = 0
                        block_may_link = False
                        i += 1
                    else:
                        state = 1
                        block_may_link = True
                        b.addline(lines[i])
                        i += 1
                elif isinstance(lines[i], DirectiveAlign):
                    b.alignment = lines[i].alignment
                    i += 1
                # asmbloc.asm_label
                elif isinstance(lines[i], asmbloc.asm_label):
                    if block_may_link:
                        b.addto(asmbloc.asm_constraint(lines[i], C_NEXT))
                        block_may_link = False
                    state = 0
                # instruction
                else:
                    b.addline(lines[i])
                    if lines[i].dstflow():
                        for x in lines[i].getdstflow(symbol_pool):
                            if not isinstance(x, m2_expr.ExprId):
                                continue
                            if x in mnemo.regs.all_regs_ids:
                                continue
                            b.addto(asmbloc.asm_constraint(x, C_TO))

                        # TODO XXX redo this really

                        if not lines[i].breakflow() and i + 1 < len(lines):
                            if isinstance(lines[i + 1], asmbloc.asm_label):
                                l = lines[i + 1]
                            else:
                                l = guess_next_new_label(symbol_pool)
                                lines[i + 1:i + 1] = [l]
                        else:
                            state = 0

                        if lines[i].splitflow():
                            bloc_to_nlink = b
                    if not lines[i].breakflow() or lines[i].splitflow():
                        block_may_link = True
                    else:
                        block_may_link = False

                    i += 1

    for block in blocs_sections[0]:
        asmbloc.log_asmbloc.info(block)

    return blocs_sections, symbol_pool