summaryrefslogtreecommitdiff
path: root/extra/stack_analyzer/stack_analyzer.py
diff options
context:
space:
mode:
Diffstat (limited to 'extra/stack_analyzer/stack_analyzer.py')
-rwxr-xr-xextra/stack_analyzer/stack_analyzer.py42
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: