Пример #1
0
def getMachineCode(string, bits):
    fil = open("asm.as", "w")
    fil.write(string)
    fil.close()

    if bits == 32:
        s = 'as --32 "asm.as" -o "asm.o"'
    else:
        s = 'as --64 "asm.as" -o "asm.o"'

    p = subprocess.Popen(s, shell=True)
    p.wait()
    if p.returncode != 0:
        raise Exception('Assembly generation failed.')

    # Read generated object code
    obj = objdump.objdump("asm.o", {})
    return obj.bytes
Пример #2
0
    def rewrite_asm(self, asm, bits):
        """This step turns the code of a DSL block into valid AT&T assembler
        syntax and compiles it with the GNU Assembler.
        
        Arguments:
            asm: The source code in our assembler DSL
            
        Returns:
            An objdump for the generated assembly (see objdump.py) 
        """

        variables = {}
        
        raw = ''
        
        # First, let's remove all multiline comments
        # TODO: currently does not work with line numbers
        found = True
        while found:
            start = asm.find('/*')
            end = asm.find('*/', start+2)
            if start == -1 or end == -1:
                found = False
            else:
                print 'Removed comment {%s}' % asm[start:end+2]
                linebreaks = ''.join(lb for lb in asm[start:end+2] if lb in ('\n', '\r'))
                print 'linebreaks = ', len(linebreaks)
                asm = asm[:start] + linebreaks + asm[end+2:]
        
        
        # Rewrite assembly code
        self.macro_instances = []

        #statements = reduce(lambda x,y: x+y, map(lambda x: x.split(";"), asm.split("\n")));
        statements = asm.split("\n");
 	#print statements
        for line_pos, line in enumerate(statements):
            line, _, _ = line.partition('//')

            if len(line.strip()) == 0:
                continue    
        
            # Parse this line
            line = line.strip()
            command, _, args = line.partition(' ')
            command = command.strip()
            args = [a.strip() for a in args.split(',')]

            #print command
            if command in self.macros:
                # We add a label so we can find this instruction later
                # in the machine code
                label = 'macro%d' % len(self.macro_instances)
                macro = self.macros[command](args, label)
                new_line = '\n%s:\n%s\n' % (label, macro.expand())

                line = new_line
                
                self.macro_instances += [macro]

            # Does this line contain a variable?
            pattern = r'\{(.*?)\}'        
            match = re.search(pattern, line)
            while match:
                var_name = match.groups()[0]
                if var_name not in variables:
                    variables[var_name] = self.magic_number
                    self.magic_number += 1
                
                magic = variables[var_name]

                line = line[:match.span()[0]] + ('%s' % magic) + line[match.span()[1]:]
                match = re.search(pattern, line)            
            
            raw += '_I%d:\n' % line_pos
            raw += line + '\n'

        # Compile assembly
        f = tempfile.NamedTemporaryFile('w', suffix='.as', delete=False)
        f.write(raw)
        f.close()
        
        obj_path = os.path.splitext(f.name)[0] + '.out'
        if bits == 32:
            s = 'as --32 "%s" -o "%s"' % (f.name, obj_path)
        else:
            s = 'as --64 "%s" -o "%s"' % (f.name, obj_path),
        p = subprocess.Popen(s, shell=True)
        p.wait()
        
        if p.returncode != 0:
            raise Exception('Assembly generation failed.')

        # Read generated object code
        obj = objdump(obj_path, variables)
        return obj
Пример #3
0
    def rewrite_asm(self, asm):
        """This step turns the code of a DSL block into valid AT&T assembler
        syntax and compiles it with the GNU Assembler.
        
        Arguments:
            asm: The source code in our assembler DSL
            
        Returns:
            An objdump for the generated assembly (see objdump.py) 
        """
        variables = {}
        
        raw = ''
        
        # First, let's remove all multiline comments
        # TODO: currently does not work with line numbers
        found = True
        while found:
            start = asm.find('/*')
            end = asm.find('*/', start+2)
            if start == -1 or end == -1:
                found = False
            else:
                print 'Removed comment {%s}' % asm[start:end+2]
                linebreaks = ''.join(lb for lb in asm[start:end+2] if lb in ('\n', '\r'))
                print 'linebreaks = ', len(linebreaks)
                asm = asm[:start] + linebreaks + asm[end+2:]
        
        
        # Rewrite assembly code
        self.macro_instances = []

        for line_pos, line in enumerate(asm.split('\n')):
            line, _, _ = line.partition('//')

            if len(line.strip()) == 0:
                continue    
        
            # Parse this line
            line = line.strip()
            command, _, args = line.partition(' ')
            command = command.strip()
            args = [a.strip() for a in args.split(',')]

            if command in self.macros:
                # We add a label so we can find this instruction later
                # in the machine code
                label = 'macro%d' % len(self.macro_instances)
                macro = self.macros[command](args, label)
                new_line = '\n%s:\n%s\n' % (label, macro.expand())

                line = new_line
                
                self.macro_instances += [macro]

            # Does this line contain a variable?
            pattern = r'\{(.*?)\}'        
            match = re.search(pattern, line)
            while match:
                var_name = match.groups()[0]
                if var_name not in variables:
                    variables[var_name] = self.magic_number
                    self.magic_number += 1
                
                magic = variables[var_name]

                line = line[:match.span()[0]] + ('%s' % magic) + line[match.span()[1]:]
                match = re.search(pattern, line)            
            
            raw += '_I%d:\n' % line_pos
            raw += line + '\n'

        # Compile assembly
        f = tempfile.NamedTemporaryFile('w', suffix='.as', delete=False)
        f.write(raw)
        f.close()
        
        obj_path = os.path.splitext(f.name)[0] + '.out'
        p = subprocess.Popen(
            'as --32 -march=i386 "%s" -o "%s"' % (f.name, obj_path),
            shell=True
        )
        p.wait()
        
        if p.returncode != 0:
            raise Exception('Assembly generation failed.')

        # Read generated object code
        obj = objdump(obj_path, variables)
        return obj
    print("trace file:", tracefile)
    print("trace decoder:", tracetool)
    print("objdump:", options.objdump)
    print("objfile:", options.objfile)
    print()

r_etm_execute = re.compile(r"^\s*([EN])\(([0-9a-f]{8})\)(?:\s*\+(?P<branch_points>\d+) branch points)?(?:\s*Waited\s*(?P<wait>\d+))?$")
r_etm_branch = re.compile(r"^\s*Branch ([0-9a-f]{8})\s*(.*)$")
r_etm_isync = re.compile(r"^\s*I-sync Context (?P<context>[0-9a-f]{8}), IB (?P<ib>[0-9a-f]{2}), Addr (?P<addr>[0-9a-f]{8})$")


if options.verbose:
    print("Running objdump")
    sys.stdout.flush()

instr = objdump.objdump(options.objdump, options.objfile)

if options.verbose:
    print("objdump done")
    sys.stdout.flush()

addr_offset = 0
branch_target = None
need_branch_target = False
return_stack = []

p = subprocess.Popen(tracetool + " <" + tracefile, stdout=subprocess.PIPE, shell=True)
for lineb in p.stdout:
    line = str(lineb, encoding='utf8')
    m = r_etm_execute.match(line);
    if (m):
    print("objfile:", options.objfile)
    print()

r_etm_execute = re.compile(
    r"^\s*([EN])\(([0-9a-f]{8})\)(?:\s*\+(?P<branch_points>\d+) branch points)?(?:\s*Waited\s*(?P<wait>\d+))?$"
)
r_etm_branch = re.compile(r"^\s*Branch ([0-9a-f]{8})\s*(.*)$")
r_etm_isync = re.compile(
    r"^\s*I-sync Context (?P<context>[0-9a-f]{8}), IB (?P<ib>[0-9a-f]{2}), Addr (?P<addr>[0-9a-f]{8})$"
)

if options.verbose:
    print("Running objdump")
    sys.stdout.flush()

instr = objdump.objdump(options.objdump, options.objfile)

if options.verbose:
    print("objdump done")
    sys.stdout.flush()

addr_offset = 0
branch_target = None
need_branch_target = False
return_stack = []

p = subprocess.Popen(tracetool + " <" + tracefile,
                     stdout=subprocess.PIPE,
                     shell=True)
for lineb in p.stdout:
    line = str(lineb, encoding='utf8')