diff options
Diffstat (limited to 'extra/stack_analyzer/stack_analyzer.py')
-rwxr-xr-x | extra/stack_analyzer/stack_analyzer.py | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/extra/stack_analyzer/stack_analyzer.py b/extra/stack_analyzer/stack_analyzer.py index cf5bd2addc..c7422c3e8f 100755 --- a/extra/stack_analyzer/stack_analyzer.py +++ b/extra/stack_analyzer/stack_analyzer.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # Copyright 2017 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -246,6 +246,9 @@ class Function(object): return True + def __hash__(self): + return id(self) + class AndesAnalyzer(object): """Disassembly analyzer for Andes architecture. @@ -275,8 +278,8 @@ class AndesAnalyzer(object): PUSH_OPCODE_RE = re.compile(r'^push(\d{1,})$') PUSH_OPERAND_RE = re.compile(r'^\$r\d{1,}, \#\d{1,} \! \{([^\]]+)\}') SMW_OPCODE_RE = re.compile(r'^smw(\.\w\w|\.\w\w\w)$') - SMW_OPERAND_RE = re.compile(r'^(\$r\d{1,}|\$\w\p), \[\$\w\p\], ' - r'(\$r\d{1,}|\$\w\p), \#\d\w\d \! \{([^\]]+)\}') + SMW_OPERAND_RE = re.compile(r'^(\$r\d{1,}|\$\wp), \[\$\wp\], ' + r'(\$r\d{1,}|\$\wp), \#\d\w\d \! \{([^\]]+)\}') OPERANDGROUP_RE = re.compile(r'^\$r\d{1,}\~\$r\d{1,}') LWI_OPCODE_RE = re.compile(r'^lwi(\.\w\w)$') @@ -369,8 +372,8 @@ class AndesAnalyzer(object): if self.OPERANDGROUP_RE.match(operandgroup_text) is not None: # capture number & transfer string to integer oprandgrouphead = operandgroup_text.split(',')[0] - rx=int(filter(str.isdigit, oprandgrouphead.split('~')[0])) - ry=int(filter(str.isdigit, oprandgrouphead.split('~')[1])) + rx=int(''.join(filter(str.isdigit, oprandgrouphead.split('~')[0]))) + ry=int(''.join(filter(str.isdigit, oprandgrouphead.split('~')[1]))) stack_frame += ((len(operandgroup_text.split(','))+ry-rx) * self.GENERAL_PURPOSE_REGISTER_SIZE) @@ -387,8 +390,8 @@ class AndesAnalyzer(object): if self.OPERANDGROUP_RE.match(operandgroup_text) is not None: # capture number & transfer string to integer oprandgrouphead = operandgroup_text.split(',')[0] - rx=int(filter(str.isdigit, oprandgrouphead.split('~')[0])) - ry=int(filter(str.isdigit, oprandgrouphead.split('~')[1])) + rx=int(''.join(filter(str.isdigit, oprandgrouphead.split('~')[0]))) + ry=int(''.join(filter(str.isdigit, oprandgrouphead.split('~')[1]))) stack_frame += ((len(operandgroup_text.split(','))+ry-rx) * self.GENERAL_PURPOSE_REGISTER_SIZE) @@ -616,7 +619,7 @@ class StackAnalyzer(object): if resolve_inline: args.append('-i') - line_text = subprocess.check_output(args) + line_text = subprocess.check_output(args, encoding='utf-8') except subprocess.CalledProcessError: raise StackAnalyzerError('addr2line failed to resolve lines.') except OSError: @@ -656,9 +659,9 @@ class StackAnalyzer(object): """ disasm_lines = [line.strip() for line in disasm_text.splitlines()] - if (disasm_lines[1].find("nds") != -1): + if 'nds' in disasm_lines[1]: analyzer = AndesAnalyzer() - elif (disasm_lines[1].find("arm") != -1): + elif 'arm' in disasm_lines[1]: analyzer = ArmAnalyzer() else: raise StackAnalyzerError('Unsupported architecture.') @@ -940,7 +943,7 @@ class StackAnalyzer(object): # to symbol object. for addr in range(begin_address+offset, end_address, stride): # TODO(drinkcat): Not all architectures need to drop the first bit. - val = self.rodata[(addr-self.rodata_offset)/4] & 0xfffffffe + val = self.rodata[(addr-self.rodata_offset) // 4] & 0xfffffffe name = None for symbol in self.symbols: if (symbol.address == val): @@ -1460,7 +1463,8 @@ class StackAnalyzer(object): try: disasm_text = subprocess.check_output([self.options.objdump, '-d', - self.options.elf_path]) + self.options.elf_path], + encoding='utf-8') except subprocess.CalledProcessError: raise StackAnalyzerError('objdump failed to disassemble.') except OSError: @@ -1517,7 +1521,7 @@ class StackAnalyzer(object): text_list.append(order_text) - for _, text in sorted(text_list, key=lambda (k, _): k): + for _, text in sorted(text_list, key=lambda item: item[0]): print(text) print('Unresolved indirect callsites:') @@ -1533,7 +1537,7 @@ class StackAnalyzer(object): for address in indirect_callsites: text_list.append(OutputInlineStack(address, ' ')) - for _, text in sorted(text_list, key=lambda (k, _): k): + for _, text in sorted(text_list, key=lambda item: item[0]): print(text) print('Unresolved annotation signatures:') @@ -1674,7 +1678,9 @@ def LoadTasklist(section, export_taskinfo, symbols): tasklist = [] for index in range(taskinfo_num): taskinfo = taskinfos[index] - tasklist.append(Task(taskinfo.name, taskinfo.routine, taskinfo.stack_size)) + tasklist.append(Task(taskinfo.name.decode('utf-8'), + taskinfo.routine.decode('utf-8'), + taskinfo.stack_size)) # Resolve routine address for each task. It's more efficient to resolve all # routine addresses of tasks together. @@ -1729,11 +1735,13 @@ def main(): try: symbol_text = subprocess.check_output([options.objdump, '-t', - options.elf_path]) + options.elf_path], + encoding='utf-8') rodata_text = subprocess.check_output([options.objdump, '-s', '-j', '.rodata', - options.elf_path]) + options.elf_path], + encoding='utf-8') except subprocess.CalledProcessError: raise StackAnalyzerError('objdump failed to dump symbol table or rodata.') except OSError: |