Skip to content

Commit 4e48f07

Browse files
Add ARM support to tools/grokdump.py
[email protected] Review URL: https://chromiumcodereview.appspot.com/11565014 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@13319 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
1 parent 943c43d commit 4e48f07

File tree

2 files changed

+93
-11
lines changed

2 files changed

+93
-11
lines changed

tools/disasm.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,21 @@
5353
}
5454

5555

56-
def GetDisasmLines(filename, offset, size, arch, inplace):
56+
def GetDisasmLines(filename, offset, size, arch, inplace, arch_flags=""):
5757
tmp_name = None
5858
if not inplace:
5959
# Create a temporary file containing a copy of the code.
6060
assert arch in _ARCH_MAP, "Unsupported architecture '%s'" % arch
61-
arch_flags = _ARCH_MAP[arch]
61+
arch_flags = arch_flags + " " + _ARCH_MAP[arch]
6262
tmp_name = tempfile.mktemp(".v8code")
6363
command = "dd if=%s of=%s bs=1 count=%d skip=%d && " \
6464
"%s %s -D -b binary %s %s" % (
6565
filename, tmp_name, size, offset,
6666
OBJDUMP_BIN, ' '.join(_COMMON_DISASM_OPTIONS), arch_flags,
6767
tmp_name)
6868
else:
69-
command = "%s %s --start-address=%d --stop-address=%d -d %s " % (
70-
OBJDUMP_BIN, ' '.join(_COMMON_DISASM_OPTIONS),
69+
command = "%s %s %s --start-address=%d --stop-address=%d -d %s " % (
70+
OBJDUMP_BIN, ' '.join(_COMMON_DISASM_OPTIONS), arch_flags,
7171
offset,
7272
offset + size,
7373
filename)

tools/grokdump.py

+89-7
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,42 @@ def EnableOnFlag(type, flag):
296296
MD_CONTEXT_X86_EXTENDED_REGISTERS))
297297
])
298298

299+
MD_CONTEXT_ARM = 0x40000000
300+
MD_CONTEXT_ARM_INTEGER = (MD_CONTEXT_ARM | 0x00000002)
301+
MD_CONTEXT_ARM_FLOATING_POINT = (MD_CONTEXT_ARM | 0x00000004)
302+
MD_FLOATINGSAVEAREA_ARM_FPR_COUNT = 32
303+
MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT = 8
304+
305+
MINIDUMP_FLOATING_SAVE_AREA_ARM = Descriptor([
306+
("fpscr", ctypes.c_uint64),
307+
("regs", ctypes.c_uint64 * MD_FLOATINGSAVEAREA_ARM_FPR_COUNT),
308+
("extra", ctypes.c_uint64 * MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT)
309+
])
310+
311+
MINIDUMP_CONTEXT_ARM = Descriptor([
312+
("context_flags", ctypes.c_uint32),
313+
# MD_CONTEXT_ARM_INTEGER.
314+
("r0", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
315+
("r1", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
316+
("r2", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
317+
("r3", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
318+
("r4", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
319+
("r5", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
320+
("r6", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
321+
("r7", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
322+
("r8", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
323+
("r9", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
324+
("r10", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
325+
("r11", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
326+
("r12", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
327+
("sp", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
328+
("lr", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
329+
("pc", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)),
330+
("cpsr", ctypes.c_uint32),
331+
("float_save", EnableOnFlag(MINIDUMP_FLOATING_SAVE_AREA_ARM.ctype,
332+
MD_CONTEXT_ARM_FLOATING_POINT))
333+
])
334+
299335
MD_CONTEXT_AMD64 = 0x00100000
300336
MD_CONTEXT_AMD64_CONTROL = (MD_CONTEXT_AMD64 | 0x00000001)
301337
MD_CONTEXT_AMD64_INTEGER = (MD_CONTEXT_AMD64 | 0x00000002)
@@ -429,6 +465,7 @@ def EnableOnFlag(type, flag):
429465
])
430466

431467
MD_CPU_ARCHITECTURE_X86 = 0
468+
MD_CPU_ARCHITECTURE_ARM = 5
432469
MD_CPU_ARCHITECTURE_AMD64 = 9
433470

434471
class FuncSymbol:
@@ -481,7 +518,9 @@ def __init__(self, options, minidump_name):
481518
system_info = MINIDUMP_RAW_SYSTEM_INFO.Read(
482519
self.minidump, d.location.rva)
483520
self.arch = system_info.processor_architecture
484-
assert self.arch in [MD_CPU_ARCHITECTURE_AMD64, MD_CPU_ARCHITECTURE_X86]
521+
assert self.arch in [MD_CPU_ARCHITECTURE_AMD64,
522+
MD_CPU_ARCHITECTURE_ARM,
523+
MD_CPU_ARCHITECTURE_X86]
485524
assert not self.arch is None
486525

487526
for d in directories:
@@ -496,6 +535,9 @@ def __init__(self, options, minidump_name):
496535
elif self.arch == MD_CPU_ARCHITECTURE_AMD64:
497536
self.exception_context = MINIDUMP_CONTEXT_AMD64.Read(
498537
self.minidump, self.exception.thread_context.rva)
538+
elif self.arch == MD_CPU_ARCHITECTURE_ARM:
539+
self.exception_context = MINIDUMP_CONTEXT_ARM.Read(
540+
self.minidump, self.exception.thread_context.rva)
499541
DebugPrint(self.exception_context)
500542
elif d.stream_type == MD_THREAD_LIST_STREAM:
501543
thread_list = MINIDUMP_THREAD_LIST.Read(self.minidump, d.location.rva)
@@ -541,6 +583,8 @@ def ReadU64(self, address):
541583
def ReadUIntPtr(self, address):
542584
if self.arch == MD_CPU_ARCHITECTURE_AMD64:
543585
return self.ReadU64(address)
586+
elif self.arch == MD_CPU_ARCHITECTURE_ARM:
587+
return self.ReadU32(address)
544588
elif self.arch == MD_CPU_ARCHITECTURE_X86:
545589
return self.ReadU32(address)
546590

@@ -551,6 +595,8 @@ def ReadBytes(self, address, size):
551595
def _ReadWord(self, location):
552596
if self.arch == MD_CPU_ARCHITECTURE_AMD64:
553597
return ctypes.c_uint64.from_buffer(self.minidump, location).value
598+
elif self.arch == MD_CPU_ARCHITECTURE_ARM:
599+
return ctypes.c_uint32.from_buffer(self.minidump, location).value
554600
elif self.arch == MD_CPU_ARCHITECTURE_X86:
555601
return ctypes.c_uint32.from_buffer(self.minidump, location).value
556602

@@ -647,18 +693,29 @@ def FindLocation(self, address):
647693
return None
648694

649695
def GetDisasmLines(self, address, size):
696+
def CountUndefinedInstructions(lines):
697+
pattern = "<UNDEFINED>"
698+
return sum([line.count(pattern) for (ignore, line) in lines])
699+
650700
location = self.FindLocation(address)
651701
if location is None: return []
652702
arch = None
703+
possible_objdump_flags = [""]
653704
if self.arch == MD_CPU_ARCHITECTURE_X86:
654705
arch = "ia32"
706+
elif self.arch == MD_CPU_ARCHITECTURE_ARM:
707+
arch = "arm"
708+
possible_objdump_flags = ["", "--disassembler-options=force-thumb"]
655709
elif self.arch == MD_CPU_ARCHITECTURE_AMD64:
656710
arch = "x64"
657-
return disasm.GetDisasmLines(self.minidump_name,
658-
location,
659-
size,
660-
arch,
661-
False)
711+
results = [ disasm.GetDisasmLines(self.minidump_name,
712+
location,
713+
size,
714+
arch,
715+
False,
716+
objdump_flags)
717+
for objdump_flags in possible_objdump_flags ]
718+
return min(results, key=CountUndefinedInstructions)
662719

663720

664721
def Dispose(self):
@@ -668,24 +725,32 @@ def Dispose(self):
668725
def ExceptionIP(self):
669726
if self.arch == MD_CPU_ARCHITECTURE_AMD64:
670727
return self.exception_context.rip
728+
elif self.arch == MD_CPU_ARCHITECTURE_ARM:
729+
return self.exception_context.pc
671730
elif self.arch == MD_CPU_ARCHITECTURE_X86:
672731
return self.exception_context.eip
673732

674733
def ExceptionSP(self):
675734
if self.arch == MD_CPU_ARCHITECTURE_AMD64:
676735
return self.exception_context.rsp
736+
elif self.arch == MD_CPU_ARCHITECTURE_ARM:
737+
return self.exception_context.sp
677738
elif self.arch == MD_CPU_ARCHITECTURE_X86:
678739
return self.exception_context.esp
679740

680741
def FormatIntPtr(self, value):
681742
if self.arch == MD_CPU_ARCHITECTURE_AMD64:
682743
return "%016x" % value
744+
elif self.arch == MD_CPU_ARCHITECTURE_ARM:
745+
return "%08x" % value
683746
elif self.arch == MD_CPU_ARCHITECTURE_X86:
684747
return "%08x" % value
685748

686749
def PointerSize(self):
687750
if self.arch == MD_CPU_ARCHITECTURE_AMD64:
688751
return 8
752+
elif self.arch == MD_CPU_ARCHITECTURE_ARM:
753+
return 4
689754
elif self.arch == MD_CPU_ARCHITECTURE_X86:
690755
return 4
691756

@@ -1462,6 +1527,8 @@ def ObjectAlignmentMask(self):
14621527
def MapAlignmentMask(self):
14631528
if self.reader.arch == MD_CPU_ARCHITECTURE_AMD64:
14641529
return (1 << 4) - 1
1530+
elif self.reader.arch == MD_CPU_ARCHITECTURE_ARM:
1531+
return (1 << 4) - 1
14651532
elif self.reader.arch == MD_CPU_ARCHITECTURE_X86:
14661533
return (1 << 5) - 1
14671534

@@ -1746,6 +1813,9 @@ def do_u(self, args):
17461813
MD_CPU_ARCHITECTURE_AMD64:
17471814
['rax', 'rbx', 'rcx', 'rdx', 'rdi', 'rsi', 'rbp', 'rsp', 'rip',
17481815
'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15'],
1816+
MD_CPU_ARCHITECTURE_ARM:
1817+
['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9',
1818+
'r10', 'r11', 'r12', 'sp', 'lr', 'pc'],
17491819
MD_CPU_ARCHITECTURE_X86:
17501820
['eax', 'ebx', 'ecx', 'edx', 'edi', 'esi', 'ebp', 'esp', 'eip']
17511821
}
@@ -1771,7 +1841,11 @@ def AnalyzeMinidump(options, minidump_name):
17711841
for r in CONTEXT_FOR_ARCH[reader.arch]:
17721842
print " %s: %s" % (r, reader.FormatIntPtr(reader.Register(r)))
17731843
# TODO(vitalyr): decode eflags.
1774-
print " eflags: %s" % bin(reader.exception_context.eflags)[2:]
1844+
if reader.arch == MD_CPU_ARCHITECTURE_ARM:
1845+
print " cpsr: %s" % bin(reader.exception_context.cpsr)[2:]
1846+
else:
1847+
print " eflags: %s" % bin(reader.exception_context.eflags)[2:]
1848+
17751849
print
17761850
print " modules:"
17771851
for module in reader.module_list.modules:
@@ -1842,7 +1916,15 @@ def AnalyzeMinidump(options, minidump_name):
18421916
help="dump all information contained in the minidump")
18431917
parser.add_option("--symdir", dest="symdir", default=".",
18441918
help="directory containing *.pdb.sym file with symbols")
1919+
parser.add_option("--objdump",
1920+
default="/usr/bin/objdump",
1921+
help="objdump tool to use [default: %default]")
18451922
options, args = parser.parse_args()
1923+
if os.path.exists(options.objdump):
1924+
disasm.OBJDUMP_BIN = options.objdump
1925+
OBJDUMP_BIN = options.objdump
1926+
else:
1927+
print "Cannot find %s, falling back to default objdump" % options.objdump
18461928
if len(args) != 1:
18471929
parser.print_help()
18481930
sys.exit(1)

0 commit comments

Comments
 (0)