11cb0ef41Sopenharmony_ci#!/usr/bin/env python3 21cb0ef41Sopenharmony_ci# 31cb0ef41Sopenharmony_ci# Copyright 2012 the V8 project authors. All rights reserved. 41cb0ef41Sopenharmony_ci# Redistribution and use in source and binary forms, with or without 51cb0ef41Sopenharmony_ci# modification, are permitted provided that the following conditions are 61cb0ef41Sopenharmony_ci# met: 71cb0ef41Sopenharmony_ci# 81cb0ef41Sopenharmony_ci# * Redistributions of source code must retain the above copyright 91cb0ef41Sopenharmony_ci# notice, this list of conditions and the following disclaimer. 101cb0ef41Sopenharmony_ci# * Redistributions in binary form must reproduce the above 111cb0ef41Sopenharmony_ci# copyright notice, this list of conditions and the following 121cb0ef41Sopenharmony_ci# disclaimer in the documentation and/or other materials provided 131cb0ef41Sopenharmony_ci# with the distribution. 141cb0ef41Sopenharmony_ci# * Neither the name of Google Inc. nor the names of its 151cb0ef41Sopenharmony_ci# contributors may be used to endorse or promote products derived 161cb0ef41Sopenharmony_ci# from this software without specific prior written permission. 171cb0ef41Sopenharmony_ci# 181cb0ef41Sopenharmony_ci# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 191cb0ef41Sopenharmony_ci# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 201cb0ef41Sopenharmony_ci# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 211cb0ef41Sopenharmony_ci# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 221cb0ef41Sopenharmony_ci# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 231cb0ef41Sopenharmony_ci# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 241cb0ef41Sopenharmony_ci# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 251cb0ef41Sopenharmony_ci# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 261cb0ef41Sopenharmony_ci# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 271cb0ef41Sopenharmony_ci# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 281cb0ef41Sopenharmony_ci# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ci# flake8: noqa # https://bugs.chromium.org/p/v8/issues/detail?id=8784 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ciimport http.server as http_server 341cb0ef41Sopenharmony_ciimport bisect 351cb0ef41Sopenharmony_ciimport html 361cb0ef41Sopenharmony_ciimport cmd 371cb0ef41Sopenharmony_ciimport codecs 381cb0ef41Sopenharmony_ciimport ctypes 391cb0ef41Sopenharmony_ciimport datetime 401cb0ef41Sopenharmony_ciimport disasm 411cb0ef41Sopenharmony_ciimport inspect 421cb0ef41Sopenharmony_ciimport mmap 431cb0ef41Sopenharmony_ciimport optparse 441cb0ef41Sopenharmony_ciimport os 451cb0ef41Sopenharmony_ciimport re 461cb0ef41Sopenharmony_ciimport io 471cb0ef41Sopenharmony_ciimport sys 481cb0ef41Sopenharmony_ciimport types 491cb0ef41Sopenharmony_ciimport urllib.parse 501cb0ef41Sopenharmony_ciimport v8heapconst 511cb0ef41Sopenharmony_ciimport webbrowser 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ciPORT_NUMBER = 8081 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ciUSAGE="""usage: %prog [OPTIONS] [DUMP-FILE] 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ciMinidump analyzer. 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ciShows the processor state at the point of exception including the 611cb0ef41Sopenharmony_cistack of the active thread and the referenced objects in the V8 621cb0ef41Sopenharmony_ciheap. Code objects are disassembled and the addresses linked from the 631cb0ef41Sopenharmony_cistack (e.g. pushed return addresses) are marked with "=>". 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ciExamples: 661cb0ef41Sopenharmony_ci $ %prog 12345678-1234-1234-1234-123456789abcd-full.dmp""" 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ciDEBUG=False 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_cidef DebugPrint(s): 731cb0ef41Sopenharmony_ci if not DEBUG: return 741cb0ef41Sopenharmony_ci print(s) 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ciclass Descriptor(object): 781cb0ef41Sopenharmony_ci """Descriptor of a structure in a memory.""" 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci def __init__(self, fields): 811cb0ef41Sopenharmony_ci self.fields = fields 821cb0ef41Sopenharmony_ci self.is_flexible = False 831cb0ef41Sopenharmony_ci for _, type_or_func in fields: 841cb0ef41Sopenharmony_ci if isinstance(type_or_func, types.FunctionType): 851cb0ef41Sopenharmony_ci self.is_flexible = True 861cb0ef41Sopenharmony_ci break 871cb0ef41Sopenharmony_ci if not self.is_flexible: 881cb0ef41Sopenharmony_ci self.ctype = Descriptor._GetCtype(fields) 891cb0ef41Sopenharmony_ci self.size = ctypes.sizeof(self.ctype) 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci def Read(self, memory, offset): 921cb0ef41Sopenharmony_ci if self.is_flexible: 931cb0ef41Sopenharmony_ci fields_copy = self.fields[:] 941cb0ef41Sopenharmony_ci last = 0 951cb0ef41Sopenharmony_ci for name, type_or_func in fields_copy: 961cb0ef41Sopenharmony_ci if isinstance(type_or_func, types.FunctionType): 971cb0ef41Sopenharmony_ci partial_ctype = Descriptor._GetCtype(fields_copy[:last]) 981cb0ef41Sopenharmony_ci partial_object = partial_ctype.from_buffer(memory, offset) 991cb0ef41Sopenharmony_ci type = type_or_func(partial_object) 1001cb0ef41Sopenharmony_ci if type is not None: 1011cb0ef41Sopenharmony_ci fields_copy[last] = (name, type) 1021cb0ef41Sopenharmony_ci last += 1 1031cb0ef41Sopenharmony_ci else: 1041cb0ef41Sopenharmony_ci last += 1 1051cb0ef41Sopenharmony_ci complete_ctype = Descriptor._GetCtype(fields_copy[:last]) 1061cb0ef41Sopenharmony_ci else: 1071cb0ef41Sopenharmony_ci complete_ctype = self.ctype 1081cb0ef41Sopenharmony_ci return complete_ctype.from_buffer(memory, offset) 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci @staticmethod 1111cb0ef41Sopenharmony_ci def _GetCtype(fields): 1121cb0ef41Sopenharmony_ci class Raw(ctypes.Structure): 1131cb0ef41Sopenharmony_ci _fields_ = fields 1141cb0ef41Sopenharmony_ci _pack_ = 1 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci def __str__(self): 1171cb0ef41Sopenharmony_ci return "{" + ", ".join("%s: %s" % (field, self.__getattribute__(field)) 1181cb0ef41Sopenharmony_ci for field, _ in Raw._fields_) + "}" 1191cb0ef41Sopenharmony_ci return Raw 1201cb0ef41Sopenharmony_ci 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_cidef FullDump(reader, heap): 1231cb0ef41Sopenharmony_ci """Dump all available memory regions.""" 1241cb0ef41Sopenharmony_ci def dump_region(reader, start, size, location): 1251cb0ef41Sopenharmony_ci print() 1261cb0ef41Sopenharmony_ci while start & 3 != 0: 1271cb0ef41Sopenharmony_ci start += 1 1281cb0ef41Sopenharmony_ci size -= 1 1291cb0ef41Sopenharmony_ci location += 1 1301cb0ef41Sopenharmony_ci is_executable = reader.IsProbableExecutableRegion(location, size) 1311cb0ef41Sopenharmony_ci is_ascii = reader.IsProbableASCIIRegion(location, size) 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci if is_executable is not False: 1341cb0ef41Sopenharmony_ci lines = reader.GetDisasmLines(start, size) 1351cb0ef41Sopenharmony_ci for line in lines: 1361cb0ef41Sopenharmony_ci print(FormatDisasmLine(start, heap, line)) 1371cb0ef41Sopenharmony_ci print() 1381cb0ef41Sopenharmony_ci 1391cb0ef41Sopenharmony_ci if is_ascii is not False: 1401cb0ef41Sopenharmony_ci # Output in the same format as the Unix hd command 1411cb0ef41Sopenharmony_ci addr = start 1421cb0ef41Sopenharmony_ci for i in range(0, size, 16): 1431cb0ef41Sopenharmony_ci slot = i + location 1441cb0ef41Sopenharmony_ci hex_line = "" 1451cb0ef41Sopenharmony_ci asc_line = "" 1461cb0ef41Sopenharmony_ci for i in range(16): 1471cb0ef41Sopenharmony_ci if slot + i < location + size: 1481cb0ef41Sopenharmony_ci byte = ctypes.c_uint8.from_buffer(reader.minidump, slot + i).value 1491cb0ef41Sopenharmony_ci if byte >= 0x20 and byte < 0x7f: 1501cb0ef41Sopenharmony_ci asc_line += chr(byte) 1511cb0ef41Sopenharmony_ci else: 1521cb0ef41Sopenharmony_ci asc_line += "." 1531cb0ef41Sopenharmony_ci hex_line += " %02x" % (byte) 1541cb0ef41Sopenharmony_ci else: 1551cb0ef41Sopenharmony_ci hex_line += " " 1561cb0ef41Sopenharmony_ci if i == 7: 1571cb0ef41Sopenharmony_ci hex_line += " " 1581cb0ef41Sopenharmony_ci print("%s %s |%s|" % (reader.FormatIntPtr(addr), 1591cb0ef41Sopenharmony_ci hex_line, 1601cb0ef41Sopenharmony_ci asc_line)) 1611cb0ef41Sopenharmony_ci addr += 16 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_ci if is_executable is not True and is_ascii is not True: 1641cb0ef41Sopenharmony_ci print("%s - %s" % (reader.FormatIntPtr(start), 1651cb0ef41Sopenharmony_ci reader.FormatIntPtr(start + size))) 1661cb0ef41Sopenharmony_ci print(start + size + 1); 1671cb0ef41Sopenharmony_ci for i in range(0, size, reader.MachinePointerSize()): 1681cb0ef41Sopenharmony_ci slot = start + i 1691cb0ef41Sopenharmony_ci maybe_address = reader.ReadUIntPtr(slot) 1701cb0ef41Sopenharmony_ci heap_object = heap.FindObject(maybe_address) 1711cb0ef41Sopenharmony_ci print("%s: %s" % (reader.FormatIntPtr(slot), 1721cb0ef41Sopenharmony_ci reader.FormatIntPtr(maybe_address))) 1731cb0ef41Sopenharmony_ci if heap_object: 1741cb0ef41Sopenharmony_ci heap_object.Print(Printer()) 1751cb0ef41Sopenharmony_ci print() 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_ci reader.ForEachMemoryRegion(dump_region) 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_ci# Heap constants generated by 'make grokdump' in v8heapconst module. 1801cb0ef41Sopenharmony_ciINSTANCE_TYPES = v8heapconst.INSTANCE_TYPES 1811cb0ef41Sopenharmony_ciKNOWN_MAPS = v8heapconst.KNOWN_MAPS 1821cb0ef41Sopenharmony_ciKNOWN_OBJECTS = v8heapconst.KNOWN_OBJECTS 1831cb0ef41Sopenharmony_ciFRAME_MARKERS = v8heapconst.FRAME_MARKERS 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_ci# Markers pushed on the stack by PushStackTraceAndDie 1861cb0ef41Sopenharmony_ciMAGIC_MARKER_PAIRS = ( 1871cb0ef41Sopenharmony_ci (0xbbbbbbbb, 0xbbbbbbbb), 1881cb0ef41Sopenharmony_ci (0xfefefefe, 0xfefefeff), 1891cb0ef41Sopenharmony_ci) 1901cb0ef41Sopenharmony_ci# See StackTraceFailureMessage in isolate.h 1911cb0ef41Sopenharmony_ciSTACK_TRACE_MARKER = 0xdecade30 1921cb0ef41Sopenharmony_ci# See FailureMessage in logging.cc 1931cb0ef41Sopenharmony_ciERROR_MESSAGE_MARKER = 0xdecade10 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ci# Set of structures and constants that describe the layout of minidump 1961cb0ef41Sopenharmony_ci# files. Based on MSDN and Google Breakpad. 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_ciMINIDUMP_HEADER = Descriptor([ 1991cb0ef41Sopenharmony_ci ("signature", ctypes.c_uint32), 2001cb0ef41Sopenharmony_ci ("version", ctypes.c_uint32), 2011cb0ef41Sopenharmony_ci ("stream_count", ctypes.c_uint32), 2021cb0ef41Sopenharmony_ci ("stream_directories_rva", ctypes.c_uint32), 2031cb0ef41Sopenharmony_ci ("checksum", ctypes.c_uint32), 2041cb0ef41Sopenharmony_ci ("time_date_stampt", ctypes.c_uint32), 2051cb0ef41Sopenharmony_ci ("flags", ctypes.c_uint64) 2061cb0ef41Sopenharmony_ci]) 2071cb0ef41Sopenharmony_ci 2081cb0ef41Sopenharmony_ciMINIDUMP_LOCATION_DESCRIPTOR = Descriptor([ 2091cb0ef41Sopenharmony_ci ("data_size", ctypes.c_uint32), 2101cb0ef41Sopenharmony_ci ("rva", ctypes.c_uint32) 2111cb0ef41Sopenharmony_ci]) 2121cb0ef41Sopenharmony_ci 2131cb0ef41Sopenharmony_ciMINIDUMP_STRING = Descriptor([ 2141cb0ef41Sopenharmony_ci ("length", ctypes.c_uint32), 2151cb0ef41Sopenharmony_ci ("buffer", lambda t: ctypes.c_uint8 * (t.length + 2)) 2161cb0ef41Sopenharmony_ci]) 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ciMINIDUMP_DIRECTORY = Descriptor([ 2191cb0ef41Sopenharmony_ci ("stream_type", ctypes.c_uint32), 2201cb0ef41Sopenharmony_ci ("location", MINIDUMP_LOCATION_DESCRIPTOR.ctype) 2211cb0ef41Sopenharmony_ci]) 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_ciMD_EXCEPTION_MAXIMUM_PARAMETERS = 15 2241cb0ef41Sopenharmony_ci 2251cb0ef41Sopenharmony_ciMINIDUMP_EXCEPTION = Descriptor([ 2261cb0ef41Sopenharmony_ci ("code", ctypes.c_uint32), 2271cb0ef41Sopenharmony_ci ("flags", ctypes.c_uint32), 2281cb0ef41Sopenharmony_ci ("record", ctypes.c_uint64), 2291cb0ef41Sopenharmony_ci ("address", ctypes.c_uint64), 2301cb0ef41Sopenharmony_ci ("parameter_count", ctypes.c_uint32), 2311cb0ef41Sopenharmony_ci ("unused_alignment", ctypes.c_uint32), 2321cb0ef41Sopenharmony_ci ("information", ctypes.c_uint64 * MD_EXCEPTION_MAXIMUM_PARAMETERS) 2331cb0ef41Sopenharmony_ci]) 2341cb0ef41Sopenharmony_ci 2351cb0ef41Sopenharmony_ciMINIDUMP_EXCEPTION_STREAM = Descriptor([ 2361cb0ef41Sopenharmony_ci ("thread_id", ctypes.c_uint32), 2371cb0ef41Sopenharmony_ci ("unused_alignment", ctypes.c_uint32), 2381cb0ef41Sopenharmony_ci ("exception", MINIDUMP_EXCEPTION.ctype), 2391cb0ef41Sopenharmony_ci ("thread_context", MINIDUMP_LOCATION_DESCRIPTOR.ctype) 2401cb0ef41Sopenharmony_ci]) 2411cb0ef41Sopenharmony_ci 2421cb0ef41Sopenharmony_ci# Stream types. 2431cb0ef41Sopenharmony_ciMD_UNUSED_STREAM = 0 2441cb0ef41Sopenharmony_ciMD_RESERVED_STREAM_0 = 1 2451cb0ef41Sopenharmony_ciMD_RESERVED_STREAM_1 = 2 2461cb0ef41Sopenharmony_ciMD_THREAD_LIST_STREAM = 3 2471cb0ef41Sopenharmony_ciMD_MODULE_LIST_STREAM = 4 2481cb0ef41Sopenharmony_ciMD_MEMORY_LIST_STREAM = 5 2491cb0ef41Sopenharmony_ciMD_EXCEPTION_STREAM = 6 2501cb0ef41Sopenharmony_ciMD_SYSTEM_INFO_STREAM = 7 2511cb0ef41Sopenharmony_ciMD_THREAD_EX_LIST_STREAM = 8 2521cb0ef41Sopenharmony_ciMD_MEMORY_64_LIST_STREAM = 9 2531cb0ef41Sopenharmony_ciMD_COMMENT_STREAM_A = 10 2541cb0ef41Sopenharmony_ciMD_COMMENT_STREAM_W = 11 2551cb0ef41Sopenharmony_ciMD_HANDLE_DATA_STREAM = 12 2561cb0ef41Sopenharmony_ciMD_FUNCTION_TABLE_STREAM = 13 2571cb0ef41Sopenharmony_ciMD_UNLOADED_MODULE_LIST_STREAM = 14 2581cb0ef41Sopenharmony_ciMD_MISC_INFO_STREAM = 15 2591cb0ef41Sopenharmony_ciMD_MEMORY_INFO_LIST_STREAM = 16 2601cb0ef41Sopenharmony_ciMD_THREAD_INFO_LIST_STREAM = 17 2611cb0ef41Sopenharmony_ciMD_HANDLE_OPERATION_LIST_STREAM = 18 2621cb0ef41Sopenharmony_ci 2631cb0ef41Sopenharmony_ciMD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE = 80 2641cb0ef41Sopenharmony_ci 2651cb0ef41Sopenharmony_ciMINIDUMP_FLOATING_SAVE_AREA_X86 = Descriptor([ 2661cb0ef41Sopenharmony_ci ("control_word", ctypes.c_uint32), 2671cb0ef41Sopenharmony_ci ("status_word", ctypes.c_uint32), 2681cb0ef41Sopenharmony_ci ("tag_word", ctypes.c_uint32), 2691cb0ef41Sopenharmony_ci ("error_offset", ctypes.c_uint32), 2701cb0ef41Sopenharmony_ci ("error_selector", ctypes.c_uint32), 2711cb0ef41Sopenharmony_ci ("data_offset", ctypes.c_uint32), 2721cb0ef41Sopenharmony_ci ("data_selector", ctypes.c_uint32), 2731cb0ef41Sopenharmony_ci ("register_area", ctypes.c_uint8 * MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE), 2741cb0ef41Sopenharmony_ci ("cr0_npx_state", ctypes.c_uint32) 2751cb0ef41Sopenharmony_ci]) 2761cb0ef41Sopenharmony_ci 2771cb0ef41Sopenharmony_ciMD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE = 512 2781cb0ef41Sopenharmony_ci 2791cb0ef41Sopenharmony_ci# Context flags. 2801cb0ef41Sopenharmony_ciMD_CONTEXT_X86 = 0x00010000 2811cb0ef41Sopenharmony_ciMD_CONTEXT_X86_CONTROL = (MD_CONTEXT_X86 | 0x00000001) 2821cb0ef41Sopenharmony_ciMD_CONTEXT_X86_INTEGER = (MD_CONTEXT_X86 | 0x00000002) 2831cb0ef41Sopenharmony_ciMD_CONTEXT_X86_SEGMENTS = (MD_CONTEXT_X86 | 0x00000004) 2841cb0ef41Sopenharmony_ciMD_CONTEXT_X86_FLOATING_POINT = (MD_CONTEXT_X86 | 0x00000008) 2851cb0ef41Sopenharmony_ciMD_CONTEXT_X86_DEBUG_REGISTERS = (MD_CONTEXT_X86 | 0x00000010) 2861cb0ef41Sopenharmony_ciMD_CONTEXT_X86_EXTENDED_REGISTERS = (MD_CONTEXT_X86 | 0x00000020) 2871cb0ef41Sopenharmony_ci 2881cb0ef41Sopenharmony_cidef EnableOnFlag(type, flag): 2891cb0ef41Sopenharmony_ci return lambda o: [None, type][int((o.context_flags & flag) != 0)] 2901cb0ef41Sopenharmony_ci 2911cb0ef41Sopenharmony_ciMINIDUMP_CONTEXT_X86 = Descriptor([ 2921cb0ef41Sopenharmony_ci ("context_flags", ctypes.c_uint32), 2931cb0ef41Sopenharmony_ci # MD_CONTEXT_X86_DEBUG_REGISTERS. 2941cb0ef41Sopenharmony_ci ("dr0", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), 2951cb0ef41Sopenharmony_ci ("dr1", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), 2961cb0ef41Sopenharmony_ci ("dr2", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), 2971cb0ef41Sopenharmony_ci ("dr3", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), 2981cb0ef41Sopenharmony_ci ("dr6", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), 2991cb0ef41Sopenharmony_ci ("dr7", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), 3001cb0ef41Sopenharmony_ci # MD_CONTEXT_X86_FLOATING_POINT. 3011cb0ef41Sopenharmony_ci ("float_save", EnableOnFlag(MINIDUMP_FLOATING_SAVE_AREA_X86.ctype, 3021cb0ef41Sopenharmony_ci MD_CONTEXT_X86_FLOATING_POINT)), 3031cb0ef41Sopenharmony_ci # MD_CONTEXT_X86_SEGMENTS. 3041cb0ef41Sopenharmony_ci ("gs", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_SEGMENTS)), 3051cb0ef41Sopenharmony_ci ("fs", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_SEGMENTS)), 3061cb0ef41Sopenharmony_ci ("es", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_SEGMENTS)), 3071cb0ef41Sopenharmony_ci ("ds", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_SEGMENTS)), 3081cb0ef41Sopenharmony_ci # MD_CONTEXT_X86_INTEGER. 3091cb0ef41Sopenharmony_ci ("edi", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), 3101cb0ef41Sopenharmony_ci ("esi", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), 3111cb0ef41Sopenharmony_ci ("ebx", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), 3121cb0ef41Sopenharmony_ci ("edx", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), 3131cb0ef41Sopenharmony_ci ("ecx", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), 3141cb0ef41Sopenharmony_ci ("eax", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), 3151cb0ef41Sopenharmony_ci # MD_CONTEXT_X86_CONTROL. 3161cb0ef41Sopenharmony_ci ("ebp", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), 3171cb0ef41Sopenharmony_ci ("eip", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), 3181cb0ef41Sopenharmony_ci ("cs", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), 3191cb0ef41Sopenharmony_ci ("eflags", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), 3201cb0ef41Sopenharmony_ci ("esp", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), 3211cb0ef41Sopenharmony_ci ("ss", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), 3221cb0ef41Sopenharmony_ci # MD_CONTEXT_X86_EXTENDED_REGISTERS. 3231cb0ef41Sopenharmony_ci ("extended_registers", 3241cb0ef41Sopenharmony_ci EnableOnFlag(ctypes.c_uint8 * MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE, 3251cb0ef41Sopenharmony_ci MD_CONTEXT_X86_EXTENDED_REGISTERS)) 3261cb0ef41Sopenharmony_ci]) 3271cb0ef41Sopenharmony_ci 3281cb0ef41Sopenharmony_ciMD_CONTEXT_ARM = 0x40000000 3291cb0ef41Sopenharmony_ciMD_CONTEXT_ARM_INTEGER = (MD_CONTEXT_ARM | 0x00000002) 3301cb0ef41Sopenharmony_ciMD_CONTEXT_ARM_FLOATING_POINT = (MD_CONTEXT_ARM | 0x00000004) 3311cb0ef41Sopenharmony_ciMD_FLOATINGSAVEAREA_ARM_FPR_COUNT = 32 3321cb0ef41Sopenharmony_ciMD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT = 8 3331cb0ef41Sopenharmony_ci 3341cb0ef41Sopenharmony_ciMINIDUMP_FLOATING_SAVE_AREA_ARM = Descriptor([ 3351cb0ef41Sopenharmony_ci ("fpscr", ctypes.c_uint64), 3361cb0ef41Sopenharmony_ci ("regs", ctypes.c_uint64 * MD_FLOATINGSAVEAREA_ARM_FPR_COUNT), 3371cb0ef41Sopenharmony_ci ("extra", ctypes.c_uint64 * MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT) 3381cb0ef41Sopenharmony_ci]) 3391cb0ef41Sopenharmony_ci 3401cb0ef41Sopenharmony_ciMINIDUMP_CONTEXT_ARM = Descriptor([ 3411cb0ef41Sopenharmony_ci ("context_flags", ctypes.c_uint32), 3421cb0ef41Sopenharmony_ci # MD_CONTEXT_ARM_INTEGER. 3431cb0ef41Sopenharmony_ci ("r0", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), 3441cb0ef41Sopenharmony_ci ("r1", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), 3451cb0ef41Sopenharmony_ci ("r2", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), 3461cb0ef41Sopenharmony_ci ("r3", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), 3471cb0ef41Sopenharmony_ci ("r4", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), 3481cb0ef41Sopenharmony_ci ("r5", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), 3491cb0ef41Sopenharmony_ci ("r6", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), 3501cb0ef41Sopenharmony_ci ("r7", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), 3511cb0ef41Sopenharmony_ci ("r8", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), 3521cb0ef41Sopenharmony_ci ("r9", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), 3531cb0ef41Sopenharmony_ci ("r10", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), 3541cb0ef41Sopenharmony_ci ("r11", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), 3551cb0ef41Sopenharmony_ci ("r12", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), 3561cb0ef41Sopenharmony_ci ("sp", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), 3571cb0ef41Sopenharmony_ci ("lr", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), 3581cb0ef41Sopenharmony_ci ("pc", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), 3591cb0ef41Sopenharmony_ci ("cpsr", ctypes.c_uint32), 3601cb0ef41Sopenharmony_ci ("float_save", EnableOnFlag(MINIDUMP_FLOATING_SAVE_AREA_ARM.ctype, 3611cb0ef41Sopenharmony_ci MD_CONTEXT_ARM_FLOATING_POINT)) 3621cb0ef41Sopenharmony_ci]) 3631cb0ef41Sopenharmony_ci 3641cb0ef41Sopenharmony_ci 3651cb0ef41Sopenharmony_ciMD_CONTEXT_ARM64 = 0x80000000 3661cb0ef41Sopenharmony_ciMD_CONTEXT_ARM64_INTEGER = (MD_CONTEXT_ARM64 | 0x00000002) 3671cb0ef41Sopenharmony_ciMD_CONTEXT_ARM64_FLOATING_POINT = (MD_CONTEXT_ARM64 | 0x00000004) 3681cb0ef41Sopenharmony_ciMD_FLOATINGSAVEAREA_ARM64_FPR_COUNT = 64 3691cb0ef41Sopenharmony_ci 3701cb0ef41Sopenharmony_ciMINIDUMP_FLOATING_SAVE_AREA_ARM = Descriptor([ 3711cb0ef41Sopenharmony_ci ("fpscr", ctypes.c_uint64), 3721cb0ef41Sopenharmony_ci ("regs", ctypes.c_uint64 * MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT), 3731cb0ef41Sopenharmony_ci]) 3741cb0ef41Sopenharmony_ci 3751cb0ef41Sopenharmony_ciMINIDUMP_CONTEXT_ARM64 = Descriptor([ 3761cb0ef41Sopenharmony_ci ("context_flags", ctypes.c_uint64), 3771cb0ef41Sopenharmony_ci # MD_CONTEXT_ARM64_INTEGER. 3781cb0ef41Sopenharmony_ci ("r0", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3791cb0ef41Sopenharmony_ci ("r1", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3801cb0ef41Sopenharmony_ci ("r2", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3811cb0ef41Sopenharmony_ci ("r3", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3821cb0ef41Sopenharmony_ci ("r4", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3831cb0ef41Sopenharmony_ci ("r5", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3841cb0ef41Sopenharmony_ci ("r6", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3851cb0ef41Sopenharmony_ci ("r7", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3861cb0ef41Sopenharmony_ci ("r8", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3871cb0ef41Sopenharmony_ci ("r9", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3881cb0ef41Sopenharmony_ci ("r10", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3891cb0ef41Sopenharmony_ci ("r11", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3901cb0ef41Sopenharmony_ci ("r12", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3911cb0ef41Sopenharmony_ci ("r13", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3921cb0ef41Sopenharmony_ci ("r14", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3931cb0ef41Sopenharmony_ci ("r15", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3941cb0ef41Sopenharmony_ci ("r16", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3951cb0ef41Sopenharmony_ci ("r17", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3961cb0ef41Sopenharmony_ci ("r18", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3971cb0ef41Sopenharmony_ci ("r19", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3981cb0ef41Sopenharmony_ci ("r20", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 3991cb0ef41Sopenharmony_ci ("r21", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 4001cb0ef41Sopenharmony_ci ("r22", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 4011cb0ef41Sopenharmony_ci ("r23", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 4021cb0ef41Sopenharmony_ci ("r24", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 4031cb0ef41Sopenharmony_ci ("r25", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 4041cb0ef41Sopenharmony_ci ("r26", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 4051cb0ef41Sopenharmony_ci ("r27", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 4061cb0ef41Sopenharmony_ci ("r28", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 4071cb0ef41Sopenharmony_ci ("fp", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 4081cb0ef41Sopenharmony_ci ("lr", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 4091cb0ef41Sopenharmony_ci ("sp", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 4101cb0ef41Sopenharmony_ci ("pc", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), 4111cb0ef41Sopenharmony_ci ("cpsr", ctypes.c_uint32), 4121cb0ef41Sopenharmony_ci ("float_save", EnableOnFlag(MINIDUMP_FLOATING_SAVE_AREA_ARM.ctype, 4131cb0ef41Sopenharmony_ci MD_CONTEXT_ARM64_FLOATING_POINT)) 4141cb0ef41Sopenharmony_ci]) 4151cb0ef41Sopenharmony_ci 4161cb0ef41Sopenharmony_ci 4171cb0ef41Sopenharmony_ciMD_CONTEXT_AMD64 = 0x00100000 4181cb0ef41Sopenharmony_ciMD_CONTEXT_AMD64_CONTROL = (MD_CONTEXT_AMD64 | 0x00000001) 4191cb0ef41Sopenharmony_ciMD_CONTEXT_AMD64_INTEGER = (MD_CONTEXT_AMD64 | 0x00000002) 4201cb0ef41Sopenharmony_ciMD_CONTEXT_AMD64_SEGMENTS = (MD_CONTEXT_AMD64 | 0x00000004) 4211cb0ef41Sopenharmony_ciMD_CONTEXT_AMD64_FLOATING_POINT = (MD_CONTEXT_AMD64 | 0x00000008) 4221cb0ef41Sopenharmony_ciMD_CONTEXT_AMD64_DEBUG_REGISTERS = (MD_CONTEXT_AMD64 | 0x00000010) 4231cb0ef41Sopenharmony_ci 4241cb0ef41Sopenharmony_ciMINIDUMP_CONTEXT_AMD64 = Descriptor([ 4251cb0ef41Sopenharmony_ci ("p1_home", ctypes.c_uint64), 4261cb0ef41Sopenharmony_ci ("p2_home", ctypes.c_uint64), 4271cb0ef41Sopenharmony_ci ("p3_home", ctypes.c_uint64), 4281cb0ef41Sopenharmony_ci ("p4_home", ctypes.c_uint64), 4291cb0ef41Sopenharmony_ci ("p5_home", ctypes.c_uint64), 4301cb0ef41Sopenharmony_ci ("p6_home", ctypes.c_uint64), 4311cb0ef41Sopenharmony_ci ("context_flags", ctypes.c_uint32), 4321cb0ef41Sopenharmony_ci ("mx_csr", ctypes.c_uint32), 4331cb0ef41Sopenharmony_ci # MD_CONTEXT_AMD64_CONTROL. 4341cb0ef41Sopenharmony_ci ("cs", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_CONTROL)), 4351cb0ef41Sopenharmony_ci # MD_CONTEXT_AMD64_SEGMENTS 4361cb0ef41Sopenharmony_ci ("ds", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_SEGMENTS)), 4371cb0ef41Sopenharmony_ci ("es", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_SEGMENTS)), 4381cb0ef41Sopenharmony_ci ("fs", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_SEGMENTS)), 4391cb0ef41Sopenharmony_ci ("gs", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_SEGMENTS)), 4401cb0ef41Sopenharmony_ci # MD_CONTEXT_AMD64_CONTROL. 4411cb0ef41Sopenharmony_ci ("ss", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_CONTROL)), 4421cb0ef41Sopenharmony_ci ("eflags", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_AMD64_CONTROL)), 4431cb0ef41Sopenharmony_ci # MD_CONTEXT_AMD64_DEBUG_REGISTERS. 4441cb0ef41Sopenharmony_ci ("dr0", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 4451cb0ef41Sopenharmony_ci ("dr1", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 4461cb0ef41Sopenharmony_ci ("dr2", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 4471cb0ef41Sopenharmony_ci ("dr3", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 4481cb0ef41Sopenharmony_ci ("dr6", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 4491cb0ef41Sopenharmony_ci ("dr7", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 4501cb0ef41Sopenharmony_ci # MD_CONTEXT_AMD64_INTEGER. 4511cb0ef41Sopenharmony_ci ("rax", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 4521cb0ef41Sopenharmony_ci ("rcx", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 4531cb0ef41Sopenharmony_ci ("rdx", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 4541cb0ef41Sopenharmony_ci ("rbx", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 4551cb0ef41Sopenharmony_ci # MD_CONTEXT_AMD64_CONTROL. 4561cb0ef41Sopenharmony_ci ("rsp", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_CONTROL)), 4571cb0ef41Sopenharmony_ci # MD_CONTEXT_AMD64_INTEGER. 4581cb0ef41Sopenharmony_ci ("rbp", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 4591cb0ef41Sopenharmony_ci ("rsi", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 4601cb0ef41Sopenharmony_ci ("rdi", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 4611cb0ef41Sopenharmony_ci ("r8", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 4621cb0ef41Sopenharmony_ci ("r9", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 4631cb0ef41Sopenharmony_ci ("r10", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 4641cb0ef41Sopenharmony_ci ("r11", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 4651cb0ef41Sopenharmony_ci ("r12", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 4661cb0ef41Sopenharmony_ci ("r13", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 4671cb0ef41Sopenharmony_ci ("r14", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 4681cb0ef41Sopenharmony_ci ("r15", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), 4691cb0ef41Sopenharmony_ci # MD_CONTEXT_AMD64_CONTROL. 4701cb0ef41Sopenharmony_ci ("rip", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_CONTROL)), 4711cb0ef41Sopenharmony_ci # MD_CONTEXT_AMD64_FLOATING_POINT 4721cb0ef41Sopenharmony_ci ("sse_registers", EnableOnFlag(ctypes.c_uint8 * (16 * 26), 4731cb0ef41Sopenharmony_ci MD_CONTEXT_AMD64_FLOATING_POINT)), 4741cb0ef41Sopenharmony_ci ("vector_registers", EnableOnFlag(ctypes.c_uint8 * (16 * 26), 4751cb0ef41Sopenharmony_ci MD_CONTEXT_AMD64_FLOATING_POINT)), 4761cb0ef41Sopenharmony_ci ("vector_control", EnableOnFlag(ctypes.c_uint64, 4771cb0ef41Sopenharmony_ci MD_CONTEXT_AMD64_FLOATING_POINT)), 4781cb0ef41Sopenharmony_ci # MD_CONTEXT_AMD64_DEBUG_REGISTERS. 4791cb0ef41Sopenharmony_ci ("debug_control", EnableOnFlag(ctypes.c_uint64, 4801cb0ef41Sopenharmony_ci MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 4811cb0ef41Sopenharmony_ci ("last_branch_to_rip", EnableOnFlag(ctypes.c_uint64, 4821cb0ef41Sopenharmony_ci MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 4831cb0ef41Sopenharmony_ci ("last_branch_from_rip", EnableOnFlag(ctypes.c_uint64, 4841cb0ef41Sopenharmony_ci MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 4851cb0ef41Sopenharmony_ci ("last_exception_to_rip", EnableOnFlag(ctypes.c_uint64, 4861cb0ef41Sopenharmony_ci MD_CONTEXT_AMD64_DEBUG_REGISTERS)), 4871cb0ef41Sopenharmony_ci ("last_exception_from_rip", EnableOnFlag(ctypes.c_uint64, 4881cb0ef41Sopenharmony_ci MD_CONTEXT_AMD64_DEBUG_REGISTERS)) 4891cb0ef41Sopenharmony_ci]) 4901cb0ef41Sopenharmony_ci 4911cb0ef41Sopenharmony_ciMINIDUMP_MEMORY_DESCRIPTOR = Descriptor([ 4921cb0ef41Sopenharmony_ci ("start", ctypes.c_uint64), 4931cb0ef41Sopenharmony_ci ("memory", MINIDUMP_LOCATION_DESCRIPTOR.ctype) 4941cb0ef41Sopenharmony_ci]) 4951cb0ef41Sopenharmony_ci 4961cb0ef41Sopenharmony_ciMINIDUMP_MEMORY_DESCRIPTOR64 = Descriptor([ 4971cb0ef41Sopenharmony_ci ("start", ctypes.c_uint64), 4981cb0ef41Sopenharmony_ci ("size", ctypes.c_uint64) 4991cb0ef41Sopenharmony_ci]) 5001cb0ef41Sopenharmony_ci 5011cb0ef41Sopenharmony_ciMINIDUMP_MEMORY_LIST = Descriptor([ 5021cb0ef41Sopenharmony_ci ("range_count", ctypes.c_uint32), 5031cb0ef41Sopenharmony_ci ("ranges", lambda m: MINIDUMP_MEMORY_DESCRIPTOR.ctype * m.range_count) 5041cb0ef41Sopenharmony_ci]) 5051cb0ef41Sopenharmony_ci 5061cb0ef41Sopenharmony_ciMINIDUMP_MEMORY_LIST_Mac = Descriptor([ 5071cb0ef41Sopenharmony_ci ("range_count", ctypes.c_uint32), 5081cb0ef41Sopenharmony_ci ("junk", ctypes.c_uint32), 5091cb0ef41Sopenharmony_ci ("ranges", lambda m: MINIDUMP_MEMORY_DESCRIPTOR.ctype * m.range_count) 5101cb0ef41Sopenharmony_ci]) 5111cb0ef41Sopenharmony_ci 5121cb0ef41Sopenharmony_ciMINIDUMP_MEMORY_LIST64 = Descriptor([ 5131cb0ef41Sopenharmony_ci ("range_count", ctypes.c_uint64), 5141cb0ef41Sopenharmony_ci ("base_rva", ctypes.c_uint64), 5151cb0ef41Sopenharmony_ci ("ranges", lambda m: MINIDUMP_MEMORY_DESCRIPTOR64.ctype * m.range_count) 5161cb0ef41Sopenharmony_ci]) 5171cb0ef41Sopenharmony_ci 5181cb0ef41Sopenharmony_ciMINIDUMP_THREAD = Descriptor([ 5191cb0ef41Sopenharmony_ci ("id", ctypes.c_uint32), 5201cb0ef41Sopenharmony_ci ("suspend_count", ctypes.c_uint32), 5211cb0ef41Sopenharmony_ci ("priority_class", ctypes.c_uint32), 5221cb0ef41Sopenharmony_ci ("priority", ctypes.c_uint32), 5231cb0ef41Sopenharmony_ci ("ted", ctypes.c_uint64), 5241cb0ef41Sopenharmony_ci ("stack", MINIDUMP_MEMORY_DESCRIPTOR.ctype), 5251cb0ef41Sopenharmony_ci ("context", MINIDUMP_LOCATION_DESCRIPTOR.ctype) 5261cb0ef41Sopenharmony_ci]) 5271cb0ef41Sopenharmony_ci 5281cb0ef41Sopenharmony_ciMINIDUMP_THREAD_LIST = Descriptor([ 5291cb0ef41Sopenharmony_ci ("thread_count", ctypes.c_uint32), 5301cb0ef41Sopenharmony_ci ("threads", lambda t: MINIDUMP_THREAD.ctype * t.thread_count) 5311cb0ef41Sopenharmony_ci]) 5321cb0ef41Sopenharmony_ci 5331cb0ef41Sopenharmony_ciMINIDUMP_THREAD_LIST_Mac = Descriptor([ 5341cb0ef41Sopenharmony_ci ("thread_count", ctypes.c_uint32), 5351cb0ef41Sopenharmony_ci ("junk", ctypes.c_uint32), 5361cb0ef41Sopenharmony_ci ("threads", lambda t: MINIDUMP_THREAD.ctype * t.thread_count) 5371cb0ef41Sopenharmony_ci]) 5381cb0ef41Sopenharmony_ci 5391cb0ef41Sopenharmony_ciMINIDUMP_VS_FIXEDFILEINFO = Descriptor([ 5401cb0ef41Sopenharmony_ci ("dwSignature", ctypes.c_uint32), 5411cb0ef41Sopenharmony_ci ("dwStrucVersion", ctypes.c_uint32), 5421cb0ef41Sopenharmony_ci ("dwFileVersionMS", ctypes.c_uint32), 5431cb0ef41Sopenharmony_ci ("dwFileVersionLS", ctypes.c_uint32), 5441cb0ef41Sopenharmony_ci ("dwProductVersionMS", ctypes.c_uint32), 5451cb0ef41Sopenharmony_ci ("dwProductVersionLS", ctypes.c_uint32), 5461cb0ef41Sopenharmony_ci ("dwFileFlagsMask", ctypes.c_uint32), 5471cb0ef41Sopenharmony_ci ("dwFileFlags", ctypes.c_uint32), 5481cb0ef41Sopenharmony_ci ("dwFileOS", ctypes.c_uint32), 5491cb0ef41Sopenharmony_ci ("dwFileType", ctypes.c_uint32), 5501cb0ef41Sopenharmony_ci ("dwFileSubtype", ctypes.c_uint32), 5511cb0ef41Sopenharmony_ci ("dwFileDateMS", ctypes.c_uint32), 5521cb0ef41Sopenharmony_ci ("dwFileDateLS", ctypes.c_uint32) 5531cb0ef41Sopenharmony_ci]) 5541cb0ef41Sopenharmony_ci 5551cb0ef41Sopenharmony_ciMINIDUMP_RAW_MODULE = Descriptor([ 5561cb0ef41Sopenharmony_ci ("base_of_image", ctypes.c_uint64), 5571cb0ef41Sopenharmony_ci ("size_of_image", ctypes.c_uint32), 5581cb0ef41Sopenharmony_ci ("checksum", ctypes.c_uint32), 5591cb0ef41Sopenharmony_ci ("time_date_stamp", ctypes.c_uint32), 5601cb0ef41Sopenharmony_ci ("module_name_rva", ctypes.c_uint32), 5611cb0ef41Sopenharmony_ci ("version_info", MINIDUMP_VS_FIXEDFILEINFO.ctype), 5621cb0ef41Sopenharmony_ci ("cv_record", MINIDUMP_LOCATION_DESCRIPTOR.ctype), 5631cb0ef41Sopenharmony_ci ("misc_record", MINIDUMP_LOCATION_DESCRIPTOR.ctype), 5641cb0ef41Sopenharmony_ci ("reserved0", ctypes.c_uint32 * 2), 5651cb0ef41Sopenharmony_ci ("reserved1", ctypes.c_uint32 * 2) 5661cb0ef41Sopenharmony_ci]) 5671cb0ef41Sopenharmony_ci 5681cb0ef41Sopenharmony_ciMINIDUMP_MODULE_LIST = Descriptor([ 5691cb0ef41Sopenharmony_ci ("number_of_modules", ctypes.c_uint32), 5701cb0ef41Sopenharmony_ci ("modules", lambda t: MINIDUMP_RAW_MODULE.ctype * t.number_of_modules) 5711cb0ef41Sopenharmony_ci]) 5721cb0ef41Sopenharmony_ci 5731cb0ef41Sopenharmony_ciMINIDUMP_MODULE_LIST_Mac = Descriptor([ 5741cb0ef41Sopenharmony_ci ("number_of_modules", ctypes.c_uint32), 5751cb0ef41Sopenharmony_ci ("junk", ctypes.c_uint32), 5761cb0ef41Sopenharmony_ci ("modules", lambda t: MINIDUMP_RAW_MODULE.ctype * t.number_of_modules) 5771cb0ef41Sopenharmony_ci]) 5781cb0ef41Sopenharmony_ci 5791cb0ef41Sopenharmony_ciMINIDUMP_RAW_SYSTEM_INFO = Descriptor([ 5801cb0ef41Sopenharmony_ci ("processor_architecture", ctypes.c_uint16) 5811cb0ef41Sopenharmony_ci]) 5821cb0ef41Sopenharmony_ci 5831cb0ef41Sopenharmony_ciMD_CPU_ARCHITECTURE_X86 = 0 5841cb0ef41Sopenharmony_ciMD_CPU_ARCHITECTURE_ARM = 5 5851cb0ef41Sopenharmony_ci# Breakpad used a custom value of 0x8003 here; Crashpad uses the new 5861cb0ef41Sopenharmony_ci# standardized value 12. 5871cb0ef41Sopenharmony_ciMD_CPU_ARCHITECTURE_ARM64 = 12 5881cb0ef41Sopenharmony_ciMD_CPU_ARCHITECTURE_ARM64_BREAKPAD_LEGACY = 0x8003 5891cb0ef41Sopenharmony_ciMD_CPU_ARCHITECTURE_AMD64 = 9 5901cb0ef41Sopenharmony_ci 5911cb0ef41Sopenharmony_ciOBJDUMP_BIN = None 5921cb0ef41Sopenharmony_ciDEFAULT_OBJDUMP_BIN = '/usr/bin/objdump' 5931cb0ef41Sopenharmony_ci 5941cb0ef41Sopenharmony_ciclass FuncSymbol: 5951cb0ef41Sopenharmony_ci def __init__(self, start, size, name): 5961cb0ef41Sopenharmony_ci self.start = start 5971cb0ef41Sopenharmony_ci self.end = self.start + size 5981cb0ef41Sopenharmony_ci self.name = name 5991cb0ef41Sopenharmony_ci 6001cb0ef41Sopenharmony_ci def __cmp__(self, other): 6011cb0ef41Sopenharmony_ci if isinstance(other, FuncSymbol): 6021cb0ef41Sopenharmony_ci return self.start - other.start 6031cb0ef41Sopenharmony_ci return self.start - other 6041cb0ef41Sopenharmony_ci 6051cb0ef41Sopenharmony_ci def Covers(self, addr): 6061cb0ef41Sopenharmony_ci return (self.start <= addr) and (addr < self.end) 6071cb0ef41Sopenharmony_ci 6081cb0ef41Sopenharmony_ci 6091cb0ef41Sopenharmony_ciclass MinidumpReader(object): 6101cb0ef41Sopenharmony_ci """Minidump (.dmp) reader.""" 6111cb0ef41Sopenharmony_ci 6121cb0ef41Sopenharmony_ci _HEADER_MAGIC = 0x504d444d 6131cb0ef41Sopenharmony_ci 6141cb0ef41Sopenharmony_ci def __init__(self, options, minidump_name): 6151cb0ef41Sopenharmony_ci self._reset() 6161cb0ef41Sopenharmony_ci self.minidump_name = minidump_name 6171cb0ef41Sopenharmony_ci if sys.platform == 'win32': 6181cb0ef41Sopenharmony_ci self.minidump_file = open(minidump_name, "a+") 6191cb0ef41Sopenharmony_ci self.minidump = mmap.mmap(self.minidump_file.fileno(), 0) 6201cb0ef41Sopenharmony_ci else: 6211cb0ef41Sopenharmony_ci self.minidump_file = open(minidump_name, "r") 6221cb0ef41Sopenharmony_ci self.minidump = mmap.mmap(self.minidump_file.fileno(), 0, mmap.MAP_PRIVATE) 6231cb0ef41Sopenharmony_ci self.header = MINIDUMP_HEADER.Read(self.minidump, 0) 6241cb0ef41Sopenharmony_ci if self.header.signature != MinidumpReader._HEADER_MAGIC: 6251cb0ef41Sopenharmony_ci print("Warning: Unsupported minidump header magic!", file=sys.stderr) 6261cb0ef41Sopenharmony_ci DebugPrint(self.header) 6271cb0ef41Sopenharmony_ci offset = self.header.stream_directories_rva 6281cb0ef41Sopenharmony_ci directories = [] 6291cb0ef41Sopenharmony_ci for _ in range(self.header.stream_count): 6301cb0ef41Sopenharmony_ci directories.append(MINIDUMP_DIRECTORY.Read(self.minidump, offset)) 6311cb0ef41Sopenharmony_ci offset += MINIDUMP_DIRECTORY.size 6321cb0ef41Sopenharmony_ci 6331cb0ef41Sopenharmony_ci self.symdir = options.symdir 6341cb0ef41Sopenharmony_ci self._ReadArchitecture(directories) 6351cb0ef41Sopenharmony_ci self._ReadDirectories(directories) 6361cb0ef41Sopenharmony_ci self._FindObjdump(options) 6371cb0ef41Sopenharmony_ci 6381cb0ef41Sopenharmony_ci def _reset(self): 6391cb0ef41Sopenharmony_ci self.header = None 6401cb0ef41Sopenharmony_ci self.arch = None 6411cb0ef41Sopenharmony_ci self.exception = None 6421cb0ef41Sopenharmony_ci self.exception_context = None 6431cb0ef41Sopenharmony_ci self.memory_list = None 6441cb0ef41Sopenharmony_ci self.memory_list64 = None 6451cb0ef41Sopenharmony_ci self.module_list = None 6461cb0ef41Sopenharmony_ci self.thread_map = {} 6471cb0ef41Sopenharmony_ci 6481cb0ef41Sopenharmony_ci self.modules_with_symbols = [] 6491cb0ef41Sopenharmony_ci self.symbols = [] 6501cb0ef41Sopenharmony_ci 6511cb0ef41Sopenharmony_ci 6521cb0ef41Sopenharmony_ci def _ReadArchitecture(self, directories): 6531cb0ef41Sopenharmony_ci # Find MDRawSystemInfo stream and determine arch. 6541cb0ef41Sopenharmony_ci for d in directories: 6551cb0ef41Sopenharmony_ci if d.stream_type == MD_SYSTEM_INFO_STREAM: 6561cb0ef41Sopenharmony_ci system_info = MINIDUMP_RAW_SYSTEM_INFO.Read( 6571cb0ef41Sopenharmony_ci self.minidump, d.location.rva) 6581cb0ef41Sopenharmony_ci self.arch = system_info.processor_architecture 6591cb0ef41Sopenharmony_ci if self.arch == MD_CPU_ARCHITECTURE_ARM64_BREAKPAD_LEGACY: 6601cb0ef41Sopenharmony_ci self.arch = MD_CPU_ARCHITECTURE_ARM64 6611cb0ef41Sopenharmony_ci assert self.arch in [MD_CPU_ARCHITECTURE_AMD64, 6621cb0ef41Sopenharmony_ci MD_CPU_ARCHITECTURE_ARM, 6631cb0ef41Sopenharmony_ci MD_CPU_ARCHITECTURE_ARM64, 6641cb0ef41Sopenharmony_ci MD_CPU_ARCHITECTURE_X86] 6651cb0ef41Sopenharmony_ci assert not self.arch is None 6661cb0ef41Sopenharmony_ci 6671cb0ef41Sopenharmony_ci def _ReadDirectories(self, directories): 6681cb0ef41Sopenharmony_ci for d in directories: 6691cb0ef41Sopenharmony_ci DebugPrint(d) 6701cb0ef41Sopenharmony_ci if d.stream_type == MD_EXCEPTION_STREAM: 6711cb0ef41Sopenharmony_ci self.exception = MINIDUMP_EXCEPTION_STREAM.Read( 6721cb0ef41Sopenharmony_ci self.minidump, d.location.rva) 6731cb0ef41Sopenharmony_ci DebugPrint(self.exception) 6741cb0ef41Sopenharmony_ci self.exception_context = self.ContextDescriptor().Read( 6751cb0ef41Sopenharmony_ci self.minidump, self.exception.thread_context.rva) 6761cb0ef41Sopenharmony_ci DebugPrint(self.exception_context) 6771cb0ef41Sopenharmony_ci elif d.stream_type == MD_THREAD_LIST_STREAM: 6781cb0ef41Sopenharmony_ci thread_list = MINIDUMP_THREAD_LIST.Read(self.minidump, d.location.rva) 6791cb0ef41Sopenharmony_ci if ctypes.sizeof(thread_list) + 4 == d.location.data_size: 6801cb0ef41Sopenharmony_ci thread_list = MINIDUMP_THREAD_LIST_Mac.Read( 6811cb0ef41Sopenharmony_ci self.minidump, d.location.rva) 6821cb0ef41Sopenharmony_ci assert ctypes.sizeof(thread_list) == d.location.data_size 6831cb0ef41Sopenharmony_ci DebugPrint(thread_list) 6841cb0ef41Sopenharmony_ci for thread in thread_list.threads: 6851cb0ef41Sopenharmony_ci DebugPrint(thread) 6861cb0ef41Sopenharmony_ci self.thread_map[thread.id] = thread 6871cb0ef41Sopenharmony_ci elif d.stream_type == MD_MODULE_LIST_STREAM: 6881cb0ef41Sopenharmony_ci assert self.module_list is None 6891cb0ef41Sopenharmony_ci self.module_list = MINIDUMP_MODULE_LIST.Read( 6901cb0ef41Sopenharmony_ci self.minidump, d.location.rva) 6911cb0ef41Sopenharmony_ci if ctypes.sizeof(self.module_list) + 4 == d.location.data_size: 6921cb0ef41Sopenharmony_ci self.module_list = MINIDUMP_MODULE_LIST_Mac.Read( 6931cb0ef41Sopenharmony_ci self.minidump, d.location.rva) 6941cb0ef41Sopenharmony_ci assert ctypes.sizeof(self.module_list) == d.location.data_size 6951cb0ef41Sopenharmony_ci DebugPrint(self.module_list) 6961cb0ef41Sopenharmony_ci elif d.stream_type == MD_MEMORY_LIST_STREAM: 6971cb0ef41Sopenharmony_ci print("Warning: This is not a full minidump!", file=sys.stderr) 6981cb0ef41Sopenharmony_ci assert self.memory_list is None 6991cb0ef41Sopenharmony_ci self.memory_list = MINIDUMP_MEMORY_LIST.Read( 7001cb0ef41Sopenharmony_ci self.minidump, d.location.rva) 7011cb0ef41Sopenharmony_ci if ctypes.sizeof(self.memory_list) + 4 == d.location.data_size: 7021cb0ef41Sopenharmony_ci self.memory_list = MINIDUMP_MEMORY_LIST_Mac.Read( 7031cb0ef41Sopenharmony_ci self.minidump, d.location.rva) 7041cb0ef41Sopenharmony_ci assert ctypes.sizeof(self.memory_list) == d.location.data_size 7051cb0ef41Sopenharmony_ci DebugPrint(self.memory_list) 7061cb0ef41Sopenharmony_ci elif d.stream_type == MD_MEMORY_64_LIST_STREAM: 7071cb0ef41Sopenharmony_ci assert self.memory_list64 is None 7081cb0ef41Sopenharmony_ci self.memory_list64 = MINIDUMP_MEMORY_LIST64.Read( 7091cb0ef41Sopenharmony_ci self.minidump, d.location.rva) 7101cb0ef41Sopenharmony_ci assert ctypes.sizeof(self.memory_list64) == d.location.data_size 7111cb0ef41Sopenharmony_ci DebugPrint(self.memory_list64) 7121cb0ef41Sopenharmony_ci 7131cb0ef41Sopenharmony_ci def _FindObjdump(self, options): 7141cb0ef41Sopenharmony_ci if options.objdump: 7151cb0ef41Sopenharmony_ci objdump_bin = options.objdump 7161cb0ef41Sopenharmony_ci else: 7171cb0ef41Sopenharmony_ci objdump_bin = self._FindThirdPartyObjdump() 7181cb0ef41Sopenharmony_ci if not objdump_bin or not os.path.exists(objdump_bin): 7191cb0ef41Sopenharmony_ci print("# Cannot find '%s', falling back to default objdump '%s'" % ( 7201cb0ef41Sopenharmony_ci objdump_bin, DEFAULT_OBJDUMP_BIN)) 7211cb0ef41Sopenharmony_ci objdump_bin = DEFAULT_OBJDUMP_BIN 7221cb0ef41Sopenharmony_ci global OBJDUMP_BIN 7231cb0ef41Sopenharmony_ci OBJDUMP_BIN = objdump_bin 7241cb0ef41Sopenharmony_ci disasm.OBJDUMP_BIN = objdump_bin 7251cb0ef41Sopenharmony_ci 7261cb0ef41Sopenharmony_ci def _FindThirdPartyObjdump(self): 7271cb0ef41Sopenharmony_ci # Try to find the platform specific objdump 7281cb0ef41Sopenharmony_ci third_party_dir = os.path.join( 7291cb0ef41Sopenharmony_ci os.path.dirname(os.path.dirname(__file__)), 'third_party') 7301cb0ef41Sopenharmony_ci objdumps = [] 7311cb0ef41Sopenharmony_ci for root, dirs, files in os.walk(third_party_dir): 7321cb0ef41Sopenharmony_ci for file in files: 7331cb0ef41Sopenharmony_ci if file.endswith("objdump"): 7341cb0ef41Sopenharmony_ci objdumps.append(os.path.join(root, file)) 7351cb0ef41Sopenharmony_ci if self.arch == MD_CPU_ARCHITECTURE_ARM: 7361cb0ef41Sopenharmony_ci platform_filter = 'arm-linux' 7371cb0ef41Sopenharmony_ci elif self.arch == MD_CPU_ARCHITECTURE_ARM64: 7381cb0ef41Sopenharmony_ci platform_filter = 'aarch64' 7391cb0ef41Sopenharmony_ci else: 7401cb0ef41Sopenharmony_ci # use default otherwise 7411cb0ef41Sopenharmony_ci return None 7421cb0ef41Sopenharmony_ci print(("# Looking for platform specific (%s) objdump in " 7431cb0ef41Sopenharmony_ci "third_party directory.") % platform_filter) 7441cb0ef41Sopenharmony_ci objdumps = list(filter(lambda file: platform_filter in file >= 0, objdumps)) 7451cb0ef41Sopenharmony_ci if len(objdumps) == 0: 7461cb0ef41Sopenharmony_ci print("# Could not find platform specific objdump in third_party.") 7471cb0ef41Sopenharmony_ci print("# Make sure you installed the correct SDK.") 7481cb0ef41Sopenharmony_ci return None 7491cb0ef41Sopenharmony_ci return objdumps[0] 7501cb0ef41Sopenharmony_ci 7511cb0ef41Sopenharmony_ci def ContextDescriptor(self): 7521cb0ef41Sopenharmony_ci if self.arch == MD_CPU_ARCHITECTURE_X86: 7531cb0ef41Sopenharmony_ci return MINIDUMP_CONTEXT_X86 7541cb0ef41Sopenharmony_ci elif self.arch == MD_CPU_ARCHITECTURE_AMD64: 7551cb0ef41Sopenharmony_ci return MINIDUMP_CONTEXT_AMD64 7561cb0ef41Sopenharmony_ci elif self.arch == MD_CPU_ARCHITECTURE_ARM: 7571cb0ef41Sopenharmony_ci return MINIDUMP_CONTEXT_ARM 7581cb0ef41Sopenharmony_ci elif self.arch == MD_CPU_ARCHITECTURE_ARM64: 7591cb0ef41Sopenharmony_ci return MINIDUMP_CONTEXT_ARM64 7601cb0ef41Sopenharmony_ci else: 7611cb0ef41Sopenharmony_ci return None 7621cb0ef41Sopenharmony_ci 7631cb0ef41Sopenharmony_ci def IsValidAlignedAddress(self, address): 7641cb0ef41Sopenharmony_ci return self.IsAlignedAddress(address) and self.IsValidAddress(address) 7651cb0ef41Sopenharmony_ci 7661cb0ef41Sopenharmony_ci def IsValidAddress(self, address): 7671cb0ef41Sopenharmony_ci return self.FindLocation(address) is not None 7681cb0ef41Sopenharmony_ci 7691cb0ef41Sopenharmony_ci def IsAlignedAddress(self, address): 7701cb0ef41Sopenharmony_ci return (address % self.MachinePointerSize()) == 0 7711cb0ef41Sopenharmony_ci 7721cb0ef41Sopenharmony_ci def IsExceptionStackAddress(self, address): 7731cb0ef41Sopenharmony_ci if not self.IsAlignedAddress(address): return False 7741cb0ef41Sopenharmony_ci return self.IsAnyExceptionStackAddress(address) 7751cb0ef41Sopenharmony_ci 7761cb0ef41Sopenharmony_ci def IsAnyExceptionStackAddress(self, address): 7771cb0ef41Sopenharmony_ci return self.StackTop() <= address <= self.StackBottom() 7781cb0ef41Sopenharmony_ci 7791cb0ef41Sopenharmony_ci def IsValidExceptionStackAddress(self, address): 7801cb0ef41Sopenharmony_ci if not self.IsValidAddress(address): return False 7811cb0ef41Sopenharmony_ci return self.IsExceptionStackAddress(address) 7821cb0ef41Sopenharmony_ci 7831cb0ef41Sopenharmony_ci def IsModuleAddress(self, address): 7841cb0ef41Sopenharmony_ci return self.GetModuleForAddress(address) != None 7851cb0ef41Sopenharmony_ci 7861cb0ef41Sopenharmony_ci def GetModuleForAddress(self, address): 7871cb0ef41Sopenharmony_ci for module in self.module_list.modules: 7881cb0ef41Sopenharmony_ci start = module.base_of_image 7891cb0ef41Sopenharmony_ci end = start + module.size_of_image 7901cb0ef41Sopenharmony_ci if start <= address < end: return module 7911cb0ef41Sopenharmony_ci return None 7921cb0ef41Sopenharmony_ci 7931cb0ef41Sopenharmony_ci def ReadU8(self, address): 7941cb0ef41Sopenharmony_ci location = self.FindLocation(address) 7951cb0ef41Sopenharmony_ci return ctypes.c_uint8.from_buffer(self.minidump, location).value 7961cb0ef41Sopenharmony_ci 7971cb0ef41Sopenharmony_ci def ReadU32(self, address): 7981cb0ef41Sopenharmony_ci location = self.FindLocation(address) 7991cb0ef41Sopenharmony_ci return ctypes.c_uint32.from_buffer(self.minidump, location).value 8001cb0ef41Sopenharmony_ci 8011cb0ef41Sopenharmony_ci def ReadU64(self, address): 8021cb0ef41Sopenharmony_ci location = self.FindLocation(address) 8031cb0ef41Sopenharmony_ci return ctypes.c_uint64.from_buffer(self.minidump, location).value 8041cb0ef41Sopenharmony_ci 8051cb0ef41Sopenharmony_ci def Is64(self): 8061cb0ef41Sopenharmony_ci return (self.arch == MD_CPU_ARCHITECTURE_ARM64 or 8071cb0ef41Sopenharmony_ci self.arch == MD_CPU_ARCHITECTURE_AMD64) 8081cb0ef41Sopenharmony_ci 8091cb0ef41Sopenharmony_ci def IsPointerCompressed(self): 8101cb0ef41Sopenharmony_ci # Assume all 64-bit builds are pointer compressed. 8111cb0ef41Sopenharmony_ci return self.Is64() 8121cb0ef41Sopenharmony_ci 8131cb0ef41Sopenharmony_ci def Is32BitTagged(self): 8141cb0ef41Sopenharmony_ci return not self.Is64() or self.IsPointerCompressed() 8151cb0ef41Sopenharmony_ci 8161cb0ef41Sopenharmony_ci def ReadTagged(self, address): 8171cb0ef41Sopenharmony_ci if self.Is32BitTagged(): 8181cb0ef41Sopenharmony_ci return self.ReadU32(address) 8191cb0ef41Sopenharmony_ci return self.ReadU64(address) 8201cb0ef41Sopenharmony_ci 8211cb0ef41Sopenharmony_ci def ReadUIntPtr(self, address): 8221cb0ef41Sopenharmony_ci if self.Is64(): 8231cb0ef41Sopenharmony_ci return self.ReadU64(address) 8241cb0ef41Sopenharmony_ci return self.ReadU32(address) 8251cb0ef41Sopenharmony_ci 8261cb0ef41Sopenharmony_ci def ReadSized(self, address, size): 8271cb0ef41Sopenharmony_ci if size == 8: 8281cb0ef41Sopenharmony_ci return self.ReadU64(address) 8291cb0ef41Sopenharmony_ci assert (size == 4) 8301cb0ef41Sopenharmony_ci return self.ReadU32(address) 8311cb0ef41Sopenharmony_ci 8321cb0ef41Sopenharmony_ci def ReadBytes(self, address, size): 8331cb0ef41Sopenharmony_ci location = self.FindLocation(address) 8341cb0ef41Sopenharmony_ci return self.minidump[location:location + size] 8351cb0ef41Sopenharmony_ci 8361cb0ef41Sopenharmony_ci def _ReadWord(self, location): 8371cb0ef41Sopenharmony_ci if self.Is64(): 8381cb0ef41Sopenharmony_ci return ctypes.c_uint64.from_buffer(self.minidump, location).value 8391cb0ef41Sopenharmony_ci return ctypes.c_uint32.from_buffer(self.minidump, location).value 8401cb0ef41Sopenharmony_ci 8411cb0ef41Sopenharmony_ci def ReadAsciiPtr(self, address): 8421cb0ef41Sopenharmony_ci ascii_content = [ 8431cb0ef41Sopenharmony_ci chr(c) if c >= 0x20 and c < 0x7f else '.' 8441cb0ef41Sopenharmony_ci for c in self.ReadBytes(address, self.MachinePointerSize()) 8451cb0ef41Sopenharmony_ci ] 8461cb0ef41Sopenharmony_ci return ''.join(ascii_content) 8471cb0ef41Sopenharmony_ci 8481cb0ef41Sopenharmony_ci def ReadAsciiString(self, address): 8491cb0ef41Sopenharmony_ci string = "" 8501cb0ef41Sopenharmony_ci while self.IsValidAddress(address): 8511cb0ef41Sopenharmony_ci code = self.ReadU8(address) 8521cb0ef41Sopenharmony_ci if 0 < code < 128: 8531cb0ef41Sopenharmony_ci string += chr(code) 8541cb0ef41Sopenharmony_ci else: 8551cb0ef41Sopenharmony_ci break 8561cb0ef41Sopenharmony_ci address += 1 8571cb0ef41Sopenharmony_ci return string 8581cb0ef41Sopenharmony_ci 8591cb0ef41Sopenharmony_ci def IsProbableASCIIRegion(self, location, length): 8601cb0ef41Sopenharmony_ci ascii_bytes = 0 8611cb0ef41Sopenharmony_ci non_ascii_bytes = 0 8621cb0ef41Sopenharmony_ci for i in range(length): 8631cb0ef41Sopenharmony_ci loc = location + i 8641cb0ef41Sopenharmony_ci byte = ctypes.c_uint8.from_buffer(self.minidump, loc).value 8651cb0ef41Sopenharmony_ci if byte >= 0x7f: 8661cb0ef41Sopenharmony_ci non_ascii_bytes += 1 8671cb0ef41Sopenharmony_ci if byte < 0x20 and byte != 0: 8681cb0ef41Sopenharmony_ci non_ascii_bytes += 1 8691cb0ef41Sopenharmony_ci if byte < 0x7f and byte >= 0x20: 8701cb0ef41Sopenharmony_ci ascii_bytes += 1 8711cb0ef41Sopenharmony_ci if byte == 0xa: # newline 8721cb0ef41Sopenharmony_ci ascii_bytes += 1 8731cb0ef41Sopenharmony_ci if ascii_bytes * 10 <= length: 8741cb0ef41Sopenharmony_ci return False 8751cb0ef41Sopenharmony_ci if length > 0 and ascii_bytes > non_ascii_bytes * 7: 8761cb0ef41Sopenharmony_ci return True 8771cb0ef41Sopenharmony_ci if ascii_bytes > non_ascii_bytes * 3: 8781cb0ef41Sopenharmony_ci return None # Maybe 8791cb0ef41Sopenharmony_ci return False 8801cb0ef41Sopenharmony_ci 8811cb0ef41Sopenharmony_ci def IsProbableExecutableRegion(self, location, length): 8821cb0ef41Sopenharmony_ci opcode_bytes = 0 8831cb0ef41Sopenharmony_ci sixty_four = self.Is64() 8841cb0ef41Sopenharmony_ci for i in range(length): 8851cb0ef41Sopenharmony_ci loc = location + i 8861cb0ef41Sopenharmony_ci byte = ctypes.c_uint8.from_buffer(self.minidump, loc).value 8871cb0ef41Sopenharmony_ci if (byte == 0x8b or # mov 8881cb0ef41Sopenharmony_ci byte == 0x89 or # mov reg-reg 8891cb0ef41Sopenharmony_ci (byte & 0xf0) == 0x50 or # push/pop 8901cb0ef41Sopenharmony_ci (sixty_four and (byte & 0xf0) == 0x40) or # rex prefix 8911cb0ef41Sopenharmony_ci byte == 0xc3 or # return 8921cb0ef41Sopenharmony_ci byte == 0x74 or # jeq 8931cb0ef41Sopenharmony_ci byte == 0x84 or # jeq far 8941cb0ef41Sopenharmony_ci byte == 0x75 or # jne 8951cb0ef41Sopenharmony_ci byte == 0x85 or # jne far 8961cb0ef41Sopenharmony_ci byte == 0xe8 or # call 8971cb0ef41Sopenharmony_ci byte == 0xe9 or # jmp far 8981cb0ef41Sopenharmony_ci byte == 0xeb): # jmp near 8991cb0ef41Sopenharmony_ci opcode_bytes += 1 9001cb0ef41Sopenharmony_ci opcode_percent = (opcode_bytes * 100) / length 9011cb0ef41Sopenharmony_ci threshold = 20 9021cb0ef41Sopenharmony_ci if opcode_percent > threshold + 2: 9031cb0ef41Sopenharmony_ci return True 9041cb0ef41Sopenharmony_ci if opcode_percent > threshold - 2: 9051cb0ef41Sopenharmony_ci return None # Maybe 9061cb0ef41Sopenharmony_ci return False 9071cb0ef41Sopenharmony_ci 9081cb0ef41Sopenharmony_ci def FindRegion(self, addr): 9091cb0ef41Sopenharmony_ci answer = [-1, -1] 9101cb0ef41Sopenharmony_ci def is_in(reader, start, size, location): 9111cb0ef41Sopenharmony_ci if addr >= start and addr < start + size: 9121cb0ef41Sopenharmony_ci answer[0] = start 9131cb0ef41Sopenharmony_ci answer[1] = size 9141cb0ef41Sopenharmony_ci self.ForEachMemoryRegion(is_in) 9151cb0ef41Sopenharmony_ci if answer[0] == -1: 9161cb0ef41Sopenharmony_ci return None 9171cb0ef41Sopenharmony_ci return answer 9181cb0ef41Sopenharmony_ci 9191cb0ef41Sopenharmony_ci def ForEachMemoryRegion(self, cb): 9201cb0ef41Sopenharmony_ci if self.memory_list64 is not None: 9211cb0ef41Sopenharmony_ci for r in self.memory_list64.ranges: 9221cb0ef41Sopenharmony_ci location = self.memory_list64.base_rva + offset 9231cb0ef41Sopenharmony_ci cb(self, r.start, r.size, location) 9241cb0ef41Sopenharmony_ci offset += r.size 9251cb0ef41Sopenharmony_ci 9261cb0ef41Sopenharmony_ci if self.memory_list is not None: 9271cb0ef41Sopenharmony_ci for r in self.memory_list.ranges: 9281cb0ef41Sopenharmony_ci cb(self, r.start, r.memory.data_size, r.memory.rva) 9291cb0ef41Sopenharmony_ci 9301cb0ef41Sopenharmony_ci def FindWord(self, word, alignment=0): 9311cb0ef41Sopenharmony_ci def search_inside_region(reader, start, size, location): 9321cb0ef41Sopenharmony_ci location = (location + alignment) & ~alignment 9331cb0ef41Sopenharmony_ci for i in range(size - self.MachinePointerSize()): 9341cb0ef41Sopenharmony_ci loc = location + i 9351cb0ef41Sopenharmony_ci if reader._ReadWord(loc) == word: 9361cb0ef41Sopenharmony_ci slot = start + (loc - location) 9371cb0ef41Sopenharmony_ci print("%s: %s" % (reader.FormatIntPtr(slot), 9381cb0ef41Sopenharmony_ci reader.FormatIntPtr(word))) 9391cb0ef41Sopenharmony_ci self.ForEachMemoryRegion(search_inside_region) 9401cb0ef41Sopenharmony_ci 9411cb0ef41Sopenharmony_ci def FindWordList(self, word): 9421cb0ef41Sopenharmony_ci aligned_res = [] 9431cb0ef41Sopenharmony_ci unaligned_res = [] 9441cb0ef41Sopenharmony_ci def search_inside_region(reader, start, size, location): 9451cb0ef41Sopenharmony_ci for i in range(size - self.MachinePointerSize()): 9461cb0ef41Sopenharmony_ci loc = location + i 9471cb0ef41Sopenharmony_ci if reader._ReadWord(loc) == word: 9481cb0ef41Sopenharmony_ci slot = start + (loc - location) 9491cb0ef41Sopenharmony_ci if self.IsAlignedAddress(slot): 9501cb0ef41Sopenharmony_ci aligned_res.append(slot) 9511cb0ef41Sopenharmony_ci else: 9521cb0ef41Sopenharmony_ci unaligned_res.append(slot) 9531cb0ef41Sopenharmony_ci self.ForEachMemoryRegion(search_inside_region) 9541cb0ef41Sopenharmony_ci return (aligned_res, unaligned_res) 9551cb0ef41Sopenharmony_ci 9561cb0ef41Sopenharmony_ci def FindLocation(self, address): 9571cb0ef41Sopenharmony_ci offset = 0 9581cb0ef41Sopenharmony_ci if self.memory_list64 is not None: 9591cb0ef41Sopenharmony_ci for r in self.memory_list64.ranges: 9601cb0ef41Sopenharmony_ci if r.start <= address < r.start + r.size: 9611cb0ef41Sopenharmony_ci return self.memory_list64.base_rva + offset + address - r.start 9621cb0ef41Sopenharmony_ci offset += r.size 9631cb0ef41Sopenharmony_ci if self.memory_list is not None: 9641cb0ef41Sopenharmony_ci for r in self.memory_list.ranges: 9651cb0ef41Sopenharmony_ci if r.start <= address < r.start + r.memory.data_size: 9661cb0ef41Sopenharmony_ci return r.memory.rva + address - r.start 9671cb0ef41Sopenharmony_ci return None 9681cb0ef41Sopenharmony_ci 9691cb0ef41Sopenharmony_ci def GetDisasmLines(self, address, size): 9701cb0ef41Sopenharmony_ci def CountUndefinedInstructions(lines): 9711cb0ef41Sopenharmony_ci pattern = "<UNDEFINED>" 9721cb0ef41Sopenharmony_ci return sum([line.count(pattern) for (ignore, line) in lines]) 9731cb0ef41Sopenharmony_ci 9741cb0ef41Sopenharmony_ci location = self.FindLocation(address) 9751cb0ef41Sopenharmony_ci if location is None: return [] 9761cb0ef41Sopenharmony_ci arch = None 9771cb0ef41Sopenharmony_ci possible_objdump_flags = [""] 9781cb0ef41Sopenharmony_ci if self.arch == MD_CPU_ARCHITECTURE_X86: 9791cb0ef41Sopenharmony_ci arch = "ia32" 9801cb0ef41Sopenharmony_ci elif self.arch == MD_CPU_ARCHITECTURE_ARM: 9811cb0ef41Sopenharmony_ci arch = "arm" 9821cb0ef41Sopenharmony_ci possible_objdump_flags = ["", "--disassembler-options=force-thumb"] 9831cb0ef41Sopenharmony_ci elif self.arch == MD_CPU_ARCHITECTURE_ARM64: 9841cb0ef41Sopenharmony_ci arch = "arm64" 9851cb0ef41Sopenharmony_ci possible_objdump_flags = ["", "--disassembler-options=force-thumb"] 9861cb0ef41Sopenharmony_ci elif self.arch == MD_CPU_ARCHITECTURE_AMD64: 9871cb0ef41Sopenharmony_ci arch = "x64" 9881cb0ef41Sopenharmony_ci results = [ disasm.GetDisasmLines(self.minidump_name, 9891cb0ef41Sopenharmony_ci location, 9901cb0ef41Sopenharmony_ci size, 9911cb0ef41Sopenharmony_ci arch, 9921cb0ef41Sopenharmony_ci False, 9931cb0ef41Sopenharmony_ci objdump_flags) 9941cb0ef41Sopenharmony_ci for objdump_flags in possible_objdump_flags ] 9951cb0ef41Sopenharmony_ci return min(results, key=CountUndefinedInstructions) 9961cb0ef41Sopenharmony_ci 9971cb0ef41Sopenharmony_ci 9981cb0ef41Sopenharmony_ci def Dispose(self): 9991cb0ef41Sopenharmony_ci self._reset() 10001cb0ef41Sopenharmony_ci self.minidump.close() 10011cb0ef41Sopenharmony_ci self.minidump_file.close() 10021cb0ef41Sopenharmony_ci 10031cb0ef41Sopenharmony_ci def ExceptionIP(self): 10041cb0ef41Sopenharmony_ci if self.arch == MD_CPU_ARCHITECTURE_AMD64: 10051cb0ef41Sopenharmony_ci return self.exception_context.rip 10061cb0ef41Sopenharmony_ci elif self.arch == MD_CPU_ARCHITECTURE_ARM: 10071cb0ef41Sopenharmony_ci return self.exception_context.pc 10081cb0ef41Sopenharmony_ci elif self.arch == MD_CPU_ARCHITECTURE_ARM64: 10091cb0ef41Sopenharmony_ci return self.exception_context.pc 10101cb0ef41Sopenharmony_ci elif self.arch == MD_CPU_ARCHITECTURE_X86: 10111cb0ef41Sopenharmony_ci return self.exception_context.eip 10121cb0ef41Sopenharmony_ci 10131cb0ef41Sopenharmony_ci def ExceptionSP(self): 10141cb0ef41Sopenharmony_ci if self.arch == MD_CPU_ARCHITECTURE_AMD64: 10151cb0ef41Sopenharmony_ci return self.exception_context.rsp 10161cb0ef41Sopenharmony_ci elif self.arch == MD_CPU_ARCHITECTURE_ARM: 10171cb0ef41Sopenharmony_ci return self.exception_context.sp 10181cb0ef41Sopenharmony_ci elif self.arch == MD_CPU_ARCHITECTURE_ARM64: 10191cb0ef41Sopenharmony_ci return self.exception_context.sp 10201cb0ef41Sopenharmony_ci elif self.arch == MD_CPU_ARCHITECTURE_X86: 10211cb0ef41Sopenharmony_ci return self.exception_context.esp 10221cb0ef41Sopenharmony_ci 10231cb0ef41Sopenharmony_ci def ExceptionFP(self): 10241cb0ef41Sopenharmony_ci if self.arch == MD_CPU_ARCHITECTURE_AMD64: 10251cb0ef41Sopenharmony_ci return self.exception_context.rbp 10261cb0ef41Sopenharmony_ci elif self.arch == MD_CPU_ARCHITECTURE_ARM: 10271cb0ef41Sopenharmony_ci return None 10281cb0ef41Sopenharmony_ci elif self.arch == MD_CPU_ARCHITECTURE_ARM64: 10291cb0ef41Sopenharmony_ci return self.exception_context.fp 10301cb0ef41Sopenharmony_ci elif self.arch == MD_CPU_ARCHITECTURE_X86: 10311cb0ef41Sopenharmony_ci return self.exception_context.ebp 10321cb0ef41Sopenharmony_ci 10331cb0ef41Sopenharmony_ci def ExceptionThread(self): 10341cb0ef41Sopenharmony_ci return self.thread_map[self.exception.thread_id] 10351cb0ef41Sopenharmony_ci 10361cb0ef41Sopenharmony_ci def StackTop(self): 10371cb0ef41Sopenharmony_ci return self.ExceptionSP() 10381cb0ef41Sopenharmony_ci 10391cb0ef41Sopenharmony_ci def StackBottom(self): 10401cb0ef41Sopenharmony_ci exception_thread = self.ExceptionThread() 10411cb0ef41Sopenharmony_ci return exception_thread.stack.start + \ 10421cb0ef41Sopenharmony_ci exception_thread.stack.memory.data_size 10431cb0ef41Sopenharmony_ci 10441cb0ef41Sopenharmony_ci def FormatIntPtr(self, value): 10451cb0ef41Sopenharmony_ci if self.Is64(): 10461cb0ef41Sopenharmony_ci return "%016x" % value 10471cb0ef41Sopenharmony_ci return "%08x" % value 10481cb0ef41Sopenharmony_ci 10491cb0ef41Sopenharmony_ci def FormatTagged(self, value): 10501cb0ef41Sopenharmony_ci if self.Is64() and not self.IsPointerCompressed(): 10511cb0ef41Sopenharmony_ci return "%016x" % value 10521cb0ef41Sopenharmony_ci return "%08x" % value 10531cb0ef41Sopenharmony_ci 10541cb0ef41Sopenharmony_ci def MachinePointerSize(self): 10551cb0ef41Sopenharmony_ci if self.Is64(): 10561cb0ef41Sopenharmony_ci return 8 10571cb0ef41Sopenharmony_ci return 4 10581cb0ef41Sopenharmony_ci 10591cb0ef41Sopenharmony_ci def TaggedPointerSize(self): 10601cb0ef41Sopenharmony_ci if self.IsPointerCompressed(): 10611cb0ef41Sopenharmony_ci return 4 10621cb0ef41Sopenharmony_ci return self.MachinePointerSize() 10631cb0ef41Sopenharmony_ci 10641cb0ef41Sopenharmony_ci def Register(self, name): 10651cb0ef41Sopenharmony_ci return self.exception_context.__getattribute__(name) 10661cb0ef41Sopenharmony_ci 10671cb0ef41Sopenharmony_ci def ReadMinidumpString(self, rva): 10681cb0ef41Sopenharmony_ci string = bytearray(MINIDUMP_STRING.Read(self.minidump, rva).buffer) 10691cb0ef41Sopenharmony_ci string = string.decode("utf16") 10701cb0ef41Sopenharmony_ci return string[0:len(string) - 1] 10711cb0ef41Sopenharmony_ci 10721cb0ef41Sopenharmony_ci # Load FUNC records from a BreakPad symbol file 10731cb0ef41Sopenharmony_ci # 10741cb0ef41Sopenharmony_ci # http://code.google.com/p/google-breakpad/wiki/SymbolFiles 10751cb0ef41Sopenharmony_ci # 10761cb0ef41Sopenharmony_ci def _LoadSymbolsFrom(self, symfile, baseaddr): 10771cb0ef41Sopenharmony_ci print("Loading symbols from %s" % (symfile)) 10781cb0ef41Sopenharmony_ci funcs = [] 10791cb0ef41Sopenharmony_ci with open(symfile) as f: 10801cb0ef41Sopenharmony_ci for line in f: 10811cb0ef41Sopenharmony_ci result = re.match( 10821cb0ef41Sopenharmony_ci r"^FUNC ([a-f0-9]+) ([a-f0-9]+) ([a-f0-9]+) (.*)$", line) 10831cb0ef41Sopenharmony_ci if result is not None: 10841cb0ef41Sopenharmony_ci start = int(result.group(1), 16) 10851cb0ef41Sopenharmony_ci size = int(result.group(2), 16) 10861cb0ef41Sopenharmony_ci name = result.group(4).rstrip() 10871cb0ef41Sopenharmony_ci bisect.insort_left(self.symbols, 10881cb0ef41Sopenharmony_ci FuncSymbol(baseaddr + start, size, name)) 10891cb0ef41Sopenharmony_ci print(" ... done") 10901cb0ef41Sopenharmony_ci 10911cb0ef41Sopenharmony_ci def TryLoadSymbolsFor(self, modulename, module): 10921cb0ef41Sopenharmony_ci try: 10931cb0ef41Sopenharmony_ci symfile = os.path.join(self.symdir, 10941cb0ef41Sopenharmony_ci modulename.replace('.', '_') + ".pdb.sym") 10951cb0ef41Sopenharmony_ci if os.path.isfile(symfile): 10961cb0ef41Sopenharmony_ci self._LoadSymbolsFrom(symfile, module.base_of_image) 10971cb0ef41Sopenharmony_ci self.modules_with_symbols.append(module) 10981cb0ef41Sopenharmony_ci except Exception as e: 10991cb0ef41Sopenharmony_ci print(" ... failure (%s)" % (e)) 11001cb0ef41Sopenharmony_ci 11011cb0ef41Sopenharmony_ci # Returns true if address is covered by some module that has loaded symbols. 11021cb0ef41Sopenharmony_ci def _IsInModuleWithSymbols(self, addr): 11031cb0ef41Sopenharmony_ci for module in self.modules_with_symbols: 11041cb0ef41Sopenharmony_ci start = module.base_of_image 11051cb0ef41Sopenharmony_ci end = start + module.size_of_image 11061cb0ef41Sopenharmony_ci if (start <= addr) and (addr < end): 11071cb0ef41Sopenharmony_ci return True 11081cb0ef41Sopenharmony_ci return False 11091cb0ef41Sopenharmony_ci 11101cb0ef41Sopenharmony_ci # Find symbol covering the given address and return its name in format 11111cb0ef41Sopenharmony_ci # <symbol name>+<offset from the start> 11121cb0ef41Sopenharmony_ci def FindSymbol(self, addr): 11131cb0ef41Sopenharmony_ci if not self._IsInModuleWithSymbols(addr): 11141cb0ef41Sopenharmony_ci return None 11151cb0ef41Sopenharmony_ci 11161cb0ef41Sopenharmony_ci i = bisect.bisect_left(self.symbols, addr) 11171cb0ef41Sopenharmony_ci symbol = None 11181cb0ef41Sopenharmony_ci if (0 < i) and self.symbols[i - 1].Covers(addr): 11191cb0ef41Sopenharmony_ci symbol = self.symbols[i - 1] 11201cb0ef41Sopenharmony_ci elif (i < len(self.symbols)) and self.symbols[i].Covers(addr): 11211cb0ef41Sopenharmony_ci symbol = self.symbols[i] 11221cb0ef41Sopenharmony_ci else: 11231cb0ef41Sopenharmony_ci return None 11241cb0ef41Sopenharmony_ci diff = addr - symbol.start 11251cb0ef41Sopenharmony_ci return "%s+0x%x" % (symbol.name, diff) 11261cb0ef41Sopenharmony_ci 11271cb0ef41Sopenharmony_ci 11281cb0ef41Sopenharmony_ciclass Printer(object): 11291cb0ef41Sopenharmony_ci """Printer with indentation support.""" 11301cb0ef41Sopenharmony_ci 11311cb0ef41Sopenharmony_ci def __init__(self): 11321cb0ef41Sopenharmony_ci self.indent = 0 11331cb0ef41Sopenharmony_ci 11341cb0ef41Sopenharmony_ci def Indent(self): 11351cb0ef41Sopenharmony_ci self.indent += 2 11361cb0ef41Sopenharmony_ci 11371cb0ef41Sopenharmony_ci def Dedent(self): 11381cb0ef41Sopenharmony_ci self.indent -= 2 11391cb0ef41Sopenharmony_ci 11401cb0ef41Sopenharmony_ci def Print(self, string): 11411cb0ef41Sopenharmony_ci print("%s%s" % (self._IndentString(), string)) 11421cb0ef41Sopenharmony_ci 11431cb0ef41Sopenharmony_ci def PrintLines(self, lines): 11441cb0ef41Sopenharmony_ci indent = self._IndentString() 11451cb0ef41Sopenharmony_ci print("\n".join("%s%s" % (indent, line) for line in lines)) 11461cb0ef41Sopenharmony_ci 11471cb0ef41Sopenharmony_ci def _IndentString(self): 11481cb0ef41Sopenharmony_ci return self.indent * " " 11491cb0ef41Sopenharmony_ci 11501cb0ef41Sopenharmony_ci 11511cb0ef41Sopenharmony_ciADDRESS_RE = re.compile(r"0x[0-9a-fA-F]+") 11521cb0ef41Sopenharmony_ci 11531cb0ef41Sopenharmony_ci 11541cb0ef41Sopenharmony_cidef FormatDisasmLine(start, heap, line): 11551cb0ef41Sopenharmony_ci line_address = start + line[0] 11561cb0ef41Sopenharmony_ci stack_slot = heap.stack_map.get(line_address) 11571cb0ef41Sopenharmony_ci marker = " " 11581cb0ef41Sopenharmony_ci if stack_slot: 11591cb0ef41Sopenharmony_ci marker = "=>" 11601cb0ef41Sopenharmony_ci code = AnnotateAddresses(heap, line[1]) 11611cb0ef41Sopenharmony_ci 11621cb0ef41Sopenharmony_ci # Compute the actual call target which the disassembler is too stupid 11631cb0ef41Sopenharmony_ci # to figure out (it adds the call offset to the disassembly offset rather 11641cb0ef41Sopenharmony_ci # than the absolute instruction address). 11651cb0ef41Sopenharmony_ci if heap.reader.arch == MD_CPU_ARCHITECTURE_X86: 11661cb0ef41Sopenharmony_ci if code.startswith("e8"): 11671cb0ef41Sopenharmony_ci words = code.split() 11681cb0ef41Sopenharmony_ci if len(words) > 6 and words[5] == "call": 11691cb0ef41Sopenharmony_ci offset = int(words[4] + words[3] + words[2] + words[1], 16) 11701cb0ef41Sopenharmony_ci target = (line_address + offset + 5) & 0xFFFFFFFF 11711cb0ef41Sopenharmony_ci code = code.replace(words[6], "0x%08x" % target) 11721cb0ef41Sopenharmony_ci # TODO(jkummerow): port this hack to ARM and x64. 11731cb0ef41Sopenharmony_ci 11741cb0ef41Sopenharmony_ci return "%s%08x %08x: %s" % (marker, line_address, line[0], code) 11751cb0ef41Sopenharmony_ci 11761cb0ef41Sopenharmony_ci 11771cb0ef41Sopenharmony_cidef AnnotateAddresses(heap, line): 11781cb0ef41Sopenharmony_ci extra = [] 11791cb0ef41Sopenharmony_ci for m in ADDRESS_RE.finditer(line): 11801cb0ef41Sopenharmony_ci maybe_address = int(m.group(0), 16) 11811cb0ef41Sopenharmony_ci object = heap.FindObject(maybe_address) 11821cb0ef41Sopenharmony_ci if not object: continue 11831cb0ef41Sopenharmony_ci extra.append(str(object)) 11841cb0ef41Sopenharmony_ci if len(extra) == 0: return line 11851cb0ef41Sopenharmony_ci return "%s ;; %s" % (line, ", ".join(extra)) 11861cb0ef41Sopenharmony_ci 11871cb0ef41Sopenharmony_ci 11881cb0ef41Sopenharmony_ciclass HeapObject(object): 11891cb0ef41Sopenharmony_ci def __init__(self, heap, map, address): 11901cb0ef41Sopenharmony_ci self.heap = heap 11911cb0ef41Sopenharmony_ci self.map = map 11921cb0ef41Sopenharmony_ci self.address = address 11931cb0ef41Sopenharmony_ci 11941cb0ef41Sopenharmony_ci def Is(self, cls): 11951cb0ef41Sopenharmony_ci return isinstance(self, cls) 11961cb0ef41Sopenharmony_ci 11971cb0ef41Sopenharmony_ci def Print(self, p): 11981cb0ef41Sopenharmony_ci p.Print(str(self)) 11991cb0ef41Sopenharmony_ci 12001cb0ef41Sopenharmony_ci def __str__(self): 12011cb0ef41Sopenharmony_ci instance_type = "???" 12021cb0ef41Sopenharmony_ci if self.map is not None: 12031cb0ef41Sopenharmony_ci instance_type = INSTANCE_TYPES[self.map.instance_type] 12041cb0ef41Sopenharmony_ci return "%s(%s, %s)" % (self.__class__.__name__, 12051cb0ef41Sopenharmony_ci self.heap.reader.FormatIntPtr(self.address), 12061cb0ef41Sopenharmony_ci instance_type) 12071cb0ef41Sopenharmony_ci 12081cb0ef41Sopenharmony_ci def ObjectField(self, offset): 12091cb0ef41Sopenharmony_ci field_value = self.heap.reader.ReadTagged(self.address + offset) 12101cb0ef41Sopenharmony_ci return self.heap.FindObjectOrSmi(field_value) 12111cb0ef41Sopenharmony_ci 12121cb0ef41Sopenharmony_ci def SmiField(self, offset): 12131cb0ef41Sopenharmony_ci field_value = self.heap.reader.ReadTagged(self.address + offset) 12141cb0ef41Sopenharmony_ci if self.heap.IsSmi(field_value): 12151cb0ef41Sopenharmony_ci return self.heap.SmiUntag(field_value) 12161cb0ef41Sopenharmony_ci return None 12171cb0ef41Sopenharmony_ci 12181cb0ef41Sopenharmony_ci 12191cb0ef41Sopenharmony_ciclass Map(HeapObject): 12201cb0ef41Sopenharmony_ci def Decode(self, offset, size, value): 12211cb0ef41Sopenharmony_ci return (value >> offset) & ((1 << size) - 1) 12221cb0ef41Sopenharmony_ci 12231cb0ef41Sopenharmony_ci # Instance Sizes 12241cb0ef41Sopenharmony_ci def InstanceSizesOffset(self): 12251cb0ef41Sopenharmony_ci return self.heap.TaggedPointerSize() 12261cb0ef41Sopenharmony_ci 12271cb0ef41Sopenharmony_ci def InstanceSizeOffset(self): 12281cb0ef41Sopenharmony_ci return self.InstanceSizesOffset() 12291cb0ef41Sopenharmony_ci 12301cb0ef41Sopenharmony_ci def InObjectProperties(self): 12311cb0ef41Sopenharmony_ci return self.InstanceSizeOffset() + 1 12321cb0ef41Sopenharmony_ci 12331cb0ef41Sopenharmony_ci def UnusedByte(self): 12341cb0ef41Sopenharmony_ci return self.InObjectProperties() + 1 12351cb0ef41Sopenharmony_ci 12361cb0ef41Sopenharmony_ci def VisitorId(self): 12371cb0ef41Sopenharmony_ci return self.UnusedByte() + 1 12381cb0ef41Sopenharmony_ci 12391cb0ef41Sopenharmony_ci # Instance Attributes 12401cb0ef41Sopenharmony_ci def InstanceAttributesOffset(self): 12411cb0ef41Sopenharmony_ci return self.InstanceSizesOffset() + self.heap.IntSize() 12421cb0ef41Sopenharmony_ci 12431cb0ef41Sopenharmony_ci def InstanceTypeOffset(self): 12441cb0ef41Sopenharmony_ci return self.InstanceAttributesOffset() 12451cb0ef41Sopenharmony_ci 12461cb0ef41Sopenharmony_ci def BitFieldOffset(self): 12471cb0ef41Sopenharmony_ci return self.InstanceTypeOffset() + 1 12481cb0ef41Sopenharmony_ci 12491cb0ef41Sopenharmony_ci def BitField2Offset(self): 12501cb0ef41Sopenharmony_ci return self.BitFieldOffset() + 1 12511cb0ef41Sopenharmony_ci 12521cb0ef41Sopenharmony_ci def UnusedPropertyFieldsOffset(self): 12531cb0ef41Sopenharmony_ci return self.BitField2Offset() + 1 12541cb0ef41Sopenharmony_ci 12551cb0ef41Sopenharmony_ci # Other fields 12561cb0ef41Sopenharmony_ci def BitField3Offset(self): 12571cb0ef41Sopenharmony_ci return self.InstanceAttributesOffset() + self.heap.IntSize() 12581cb0ef41Sopenharmony_ci 12591cb0ef41Sopenharmony_ci def PrototypeOffset(self): 12601cb0ef41Sopenharmony_ci return self.BitField3Offset() + self.heap.TaggedPointerSize() 12611cb0ef41Sopenharmony_ci 12621cb0ef41Sopenharmony_ci def ConstructorOrBackPointerOffset(self): 12631cb0ef41Sopenharmony_ci return self.PrototypeOffset() + self.heap.TaggedPointerSize() 12641cb0ef41Sopenharmony_ci 12651cb0ef41Sopenharmony_ci def TransitionsOrPrototypeInfoOffset(self): 12661cb0ef41Sopenharmony_ci return self.ConstructorOrBackPointerOffset() + self.heap.TaggedPointerSize() 12671cb0ef41Sopenharmony_ci 12681cb0ef41Sopenharmony_ci def DescriptorsOffset(self): 12691cb0ef41Sopenharmony_ci return (self.TransitionsOrPrototypeInfoOffset() + 12701cb0ef41Sopenharmony_ci self.heap.TaggedPointerSize()) 12711cb0ef41Sopenharmony_ci 12721cb0ef41Sopenharmony_ci def CodeCacheOffset(self): 12731cb0ef41Sopenharmony_ci return self.DescriptorsOffset() + self.heap.TaggedPointerSize() 12741cb0ef41Sopenharmony_ci 12751cb0ef41Sopenharmony_ci def DependentCodeOffset(self): 12761cb0ef41Sopenharmony_ci return self.CodeCacheOffset() + self.heap.TaggedPointerSize() 12771cb0ef41Sopenharmony_ci 12781cb0ef41Sopenharmony_ci def ReadByte(self, offset): 12791cb0ef41Sopenharmony_ci return self.heap.reader.ReadU8(self.address + offset) 12801cb0ef41Sopenharmony_ci 12811cb0ef41Sopenharmony_ci def ReadSlot(self, offset): 12821cb0ef41Sopenharmony_ci return self.heap.reader.ReadTagged(self.address + offset) 12831cb0ef41Sopenharmony_ci 12841cb0ef41Sopenharmony_ci def Print(self, p): 12851cb0ef41Sopenharmony_ci p.Print("Map(%08x)" % (self.address)) 12861cb0ef41Sopenharmony_ci p.Print(" - size: %d, inobject: %d, (unused: %d), visitor: %d" % ( 12871cb0ef41Sopenharmony_ci self.ReadByte(self.InstanceSizeOffset()), 12881cb0ef41Sopenharmony_ci self.ReadByte(self.InObjectProperties()), 12891cb0ef41Sopenharmony_ci self.ReadByte(self.UnusedByte()), 12901cb0ef41Sopenharmony_ci self.VisitorId())) 12911cb0ef41Sopenharmony_ci 12921cb0ef41Sopenharmony_ci instance_type = INSTANCE_TYPES[self.ReadByte(self.InstanceTypeOffset())] 12931cb0ef41Sopenharmony_ci bitfield = self.ReadByte(self.BitFieldOffset()) 12941cb0ef41Sopenharmony_ci bitfield2 = self.ReadByte(self.BitField2Offset()) 12951cb0ef41Sopenharmony_ci unused = self.ReadByte(self.UnusedPropertyFieldsOffset()) 12961cb0ef41Sopenharmony_ci p.Print(" - %s, bf: %d, bf2: %d, unused: %d" % ( 12971cb0ef41Sopenharmony_ci instance_type, bitfield, bitfield2, unused)) 12981cb0ef41Sopenharmony_ci 12991cb0ef41Sopenharmony_ci p.Print(" - kind: %s" % (self.Decode(3, 5, bitfield2))) 13001cb0ef41Sopenharmony_ci 13011cb0ef41Sopenharmony_ci bitfield3 = self.ReadSlot(self.BitField3Offset()) 13021cb0ef41Sopenharmony_ci 13031cb0ef41Sopenharmony_ci p.Print( 13041cb0ef41Sopenharmony_ci " - EnumLength: %d NumberOfOwnDescriptors: %d OwnsDescriptors: %s" % ( 13051cb0ef41Sopenharmony_ci self.Decode(0, 10, bitfield3), 13061cb0ef41Sopenharmony_ci self.Decode(10, 10, bitfield3), 13071cb0ef41Sopenharmony_ci self.Decode(21, 1, bitfield3))) 13081cb0ef41Sopenharmony_ci p.Print(" - DictionaryMap: %s" % (self.Decode(20, 1, bitfield3))) 13091cb0ef41Sopenharmony_ci p.Print(" - Deprecated: %s" % (self.Decode(23, 1, bitfield3))) 13101cb0ef41Sopenharmony_ci p.Print(" - IsUnstable: %s" % (self.Decode(24, 1, bitfield3))) 13111cb0ef41Sopenharmony_ci p.Print(" - NewTargetIsBase: %s" % (self.Decode(27, 1, bitfield3))) 13121cb0ef41Sopenharmony_ci 13131cb0ef41Sopenharmony_ci descriptors = self.ObjectField(self.DescriptorsOffset()) 13141cb0ef41Sopenharmony_ci if descriptors.__class__ == FixedArray: 13151cb0ef41Sopenharmony_ci DescriptorArray(descriptors).Print(p) 13161cb0ef41Sopenharmony_ci else: 13171cb0ef41Sopenharmony_ci p.Print(" - Descriptors: %s" % (descriptors)) 13181cb0ef41Sopenharmony_ci 13191cb0ef41Sopenharmony_ci transitions = self.ObjectField(self.TransitionsOrPrototypeInfoOffset()) 13201cb0ef41Sopenharmony_ci if transitions.__class__ == FixedArray: 13211cb0ef41Sopenharmony_ci TransitionArray(transitions).Print(p) 13221cb0ef41Sopenharmony_ci else: 13231cb0ef41Sopenharmony_ci p.Print(" - TransitionsOrPrototypeInfo: %s" % (transitions)) 13241cb0ef41Sopenharmony_ci 13251cb0ef41Sopenharmony_ci p.Print(" - Prototype: %s" % self.ObjectField(self.PrototypeOffset())) 13261cb0ef41Sopenharmony_ci 13271cb0ef41Sopenharmony_ci def __init__(self, heap, map, address): 13281cb0ef41Sopenharmony_ci HeapObject.__init__(self, heap, map, address) 13291cb0ef41Sopenharmony_ci self.instance_type = \ 13301cb0ef41Sopenharmony_ci heap.reader.ReadU8(self.address + self.InstanceTypeOffset()) 13311cb0ef41Sopenharmony_ci 13321cb0ef41Sopenharmony_ci 13331cb0ef41Sopenharmony_ciclass String(HeapObject): 13341cb0ef41Sopenharmony_ci def LengthOffset(self): 13351cb0ef41Sopenharmony_ci # First word after the map is the hash, the second is the length. 13361cb0ef41Sopenharmony_ci return self.heap.TaggedPointerSize() * 2 13371cb0ef41Sopenharmony_ci 13381cb0ef41Sopenharmony_ci def __init__(self, heap, map, address): 13391cb0ef41Sopenharmony_ci HeapObject.__init__(self, heap, map, address) 13401cb0ef41Sopenharmony_ci self.length = self.SmiField(self.LengthOffset()) 13411cb0ef41Sopenharmony_ci 13421cb0ef41Sopenharmony_ci def GetChars(self): 13431cb0ef41Sopenharmony_ci return "?string?" 13441cb0ef41Sopenharmony_ci 13451cb0ef41Sopenharmony_ci def Print(self, p): 13461cb0ef41Sopenharmony_ci p.Print(str(self)) 13471cb0ef41Sopenharmony_ci 13481cb0ef41Sopenharmony_ci def __str__(self): 13491cb0ef41Sopenharmony_ci return "\"%s\"" % self.GetChars() 13501cb0ef41Sopenharmony_ci 13511cb0ef41Sopenharmony_ci 13521cb0ef41Sopenharmony_ciclass SeqString(String): 13531cb0ef41Sopenharmony_ci def CharsOffset(self): 13541cb0ef41Sopenharmony_ci return self.heap.TaggedPointerSize() * 3 13551cb0ef41Sopenharmony_ci 13561cb0ef41Sopenharmony_ci def __init__(self, heap, map, address): 13571cb0ef41Sopenharmony_ci String.__init__(self, heap, map, address) 13581cb0ef41Sopenharmony_ci self.chars = heap.reader.ReadBytes(self.address + self.CharsOffset(), 13591cb0ef41Sopenharmony_ci self.length) 13601cb0ef41Sopenharmony_ci 13611cb0ef41Sopenharmony_ci def GetChars(self): 13621cb0ef41Sopenharmony_ci return self.chars 13631cb0ef41Sopenharmony_ci 13641cb0ef41Sopenharmony_ci 13651cb0ef41Sopenharmony_ciclass ExternalString(String): 13661cb0ef41Sopenharmony_ci # TODO(vegorov) fix ExternalString for X64 architecture 13671cb0ef41Sopenharmony_ci RESOURCE_OFFSET = 12 13681cb0ef41Sopenharmony_ci 13691cb0ef41Sopenharmony_ci WEBKIT_RESOUCE_STRING_IMPL_OFFSET = 4 13701cb0ef41Sopenharmony_ci WEBKIT_STRING_IMPL_CHARS_OFFSET = 8 13711cb0ef41Sopenharmony_ci 13721cb0ef41Sopenharmony_ci def __init__(self, heap, map, address): 13731cb0ef41Sopenharmony_ci String.__init__(self, heap, map, address) 13741cb0ef41Sopenharmony_ci reader = heap.reader 13751cb0ef41Sopenharmony_ci self.resource = \ 13761cb0ef41Sopenharmony_ci reader.ReadU32(self.address + ExternalString.RESOURCE_OFFSET) 13771cb0ef41Sopenharmony_ci self.chars = "?external string?" 13781cb0ef41Sopenharmony_ci if not reader.IsValidAddress(self.resource): return 13791cb0ef41Sopenharmony_ci string_impl_address = self.resource + \ 13801cb0ef41Sopenharmony_ci ExternalString.WEBKIT_RESOUCE_STRING_IMPL_OFFSET 13811cb0ef41Sopenharmony_ci if not reader.IsValidAddress(string_impl_address): return 13821cb0ef41Sopenharmony_ci string_impl = reader.ReadU32(string_impl_address) 13831cb0ef41Sopenharmony_ci chars_ptr_address = string_impl + \ 13841cb0ef41Sopenharmony_ci ExternalString.WEBKIT_STRING_IMPL_CHARS_OFFSET 13851cb0ef41Sopenharmony_ci if not reader.IsValidAddress(chars_ptr_address): return 13861cb0ef41Sopenharmony_ci chars_ptr = reader.ReadU32(chars_ptr_address) 13871cb0ef41Sopenharmony_ci if not reader.IsValidAddress(chars_ptr): return 13881cb0ef41Sopenharmony_ci raw_chars = reader.ReadBytes(chars_ptr, 2 * self.length) 13891cb0ef41Sopenharmony_ci self.chars = codecs.getdecoder("utf16")(raw_chars)[0] 13901cb0ef41Sopenharmony_ci 13911cb0ef41Sopenharmony_ci def GetChars(self): 13921cb0ef41Sopenharmony_ci return self.chars 13931cb0ef41Sopenharmony_ci 13941cb0ef41Sopenharmony_ci 13951cb0ef41Sopenharmony_ciclass ConsString(String): 13961cb0ef41Sopenharmony_ci def LeftOffset(self): 13971cb0ef41Sopenharmony_ci return self.heap.TaggedPointerSize() * 3 13981cb0ef41Sopenharmony_ci 13991cb0ef41Sopenharmony_ci def RightOffset(self): 14001cb0ef41Sopenharmony_ci return self.heap.TaggedPointerSize() * 4 14011cb0ef41Sopenharmony_ci 14021cb0ef41Sopenharmony_ci def __init__(self, heap, map, address): 14031cb0ef41Sopenharmony_ci String.__init__(self, heap, map, address) 14041cb0ef41Sopenharmony_ci self.left = self.ObjectField(self.LeftOffset()) 14051cb0ef41Sopenharmony_ci self.right = self.ObjectField(self.RightOffset()) 14061cb0ef41Sopenharmony_ci 14071cb0ef41Sopenharmony_ci def GetChars(self): 14081cb0ef41Sopenharmony_ci try: 14091cb0ef41Sopenharmony_ci return self.left.GetChars() + self.right.GetChars() 14101cb0ef41Sopenharmony_ci except: 14111cb0ef41Sopenharmony_ci return "***CAUGHT EXCEPTION IN GROKDUMP***" 14121cb0ef41Sopenharmony_ci 14131cb0ef41Sopenharmony_ci 14141cb0ef41Sopenharmony_ciclass Oddball(HeapObject): 14151cb0ef41Sopenharmony_ci #Should match declarations in objects.h 14161cb0ef41Sopenharmony_ci KINDS = [ 14171cb0ef41Sopenharmony_ci "False", 14181cb0ef41Sopenharmony_ci "True", 14191cb0ef41Sopenharmony_ci "TheHole", 14201cb0ef41Sopenharmony_ci "Null", 14211cb0ef41Sopenharmony_ci "ArgumentMarker", 14221cb0ef41Sopenharmony_ci "Undefined", 14231cb0ef41Sopenharmony_ci "Other" 14241cb0ef41Sopenharmony_ci ] 14251cb0ef41Sopenharmony_ci 14261cb0ef41Sopenharmony_ci def ToStringOffset(self): 14271cb0ef41Sopenharmony_ci return self.heap.TaggedPointerSize() 14281cb0ef41Sopenharmony_ci 14291cb0ef41Sopenharmony_ci def ToNumberOffset(self): 14301cb0ef41Sopenharmony_ci return self.ToStringOffset() + self.heap.TaggedPointerSize() 14311cb0ef41Sopenharmony_ci 14321cb0ef41Sopenharmony_ci def KindOffset(self): 14331cb0ef41Sopenharmony_ci return self.ToNumberOffset() + self.heap.TaggedPointerSize() 14341cb0ef41Sopenharmony_ci 14351cb0ef41Sopenharmony_ci def __init__(self, heap, map, address): 14361cb0ef41Sopenharmony_ci HeapObject.__init__(self, heap, map, address) 14371cb0ef41Sopenharmony_ci self.to_string = self.ObjectField(self.ToStringOffset()) 14381cb0ef41Sopenharmony_ci self.kind = self.SmiField(self.KindOffset()) 14391cb0ef41Sopenharmony_ci 14401cb0ef41Sopenharmony_ci def Print(self, p): 14411cb0ef41Sopenharmony_ci p.Print(str(self)) 14421cb0ef41Sopenharmony_ci 14431cb0ef41Sopenharmony_ci def __str__(self): 14441cb0ef41Sopenharmony_ci if self.to_string: 14451cb0ef41Sopenharmony_ci return "Oddball(%08x, <%s>)" % (self.address, str(self.to_string)) 14461cb0ef41Sopenharmony_ci else: 14471cb0ef41Sopenharmony_ci kind = "???" 14481cb0ef41Sopenharmony_ci if 0 <= self.kind < len(Oddball.KINDS): 14491cb0ef41Sopenharmony_ci kind = Oddball.KINDS[self.kind] 14501cb0ef41Sopenharmony_ci return "Oddball(%08x, kind=%s)" % (self.address, kind) 14511cb0ef41Sopenharmony_ci 14521cb0ef41Sopenharmony_ci 14531cb0ef41Sopenharmony_ciclass FixedArray(HeapObject): 14541cb0ef41Sopenharmony_ci def LengthOffset(self): 14551cb0ef41Sopenharmony_ci return self.heap.TaggedPointerSize() 14561cb0ef41Sopenharmony_ci 14571cb0ef41Sopenharmony_ci def ElementsOffset(self): 14581cb0ef41Sopenharmony_ci return self.heap.TaggedPointerSize() * 2 14591cb0ef41Sopenharmony_ci 14601cb0ef41Sopenharmony_ci def MemberOffset(self, i): 14611cb0ef41Sopenharmony_ci return self.ElementsOffset() + self.heap.TaggedPointerSize() * i 14621cb0ef41Sopenharmony_ci 14631cb0ef41Sopenharmony_ci def Get(self, i): 14641cb0ef41Sopenharmony_ci return self.ObjectField(self.MemberOffset(i)) 14651cb0ef41Sopenharmony_ci 14661cb0ef41Sopenharmony_ci def __init__(self, heap, map, address): 14671cb0ef41Sopenharmony_ci HeapObject.__init__(self, heap, map, address) 14681cb0ef41Sopenharmony_ci self.length = self.SmiField(self.LengthOffset()) 14691cb0ef41Sopenharmony_ci 14701cb0ef41Sopenharmony_ci def Print(self, p): 14711cb0ef41Sopenharmony_ci p.Print("FixedArray(%s) {" % self.heap.reader.FormatIntPtr(self.address)) 14721cb0ef41Sopenharmony_ci p.Indent() 14731cb0ef41Sopenharmony_ci p.Print("length: %d" % self.length) 14741cb0ef41Sopenharmony_ci base_offset = self.ElementsOffset() 14751cb0ef41Sopenharmony_ci for i in range(self.length): 14761cb0ef41Sopenharmony_ci offset = base_offset + 4 * i 14771cb0ef41Sopenharmony_ci try: 14781cb0ef41Sopenharmony_ci p.Print("[%08d] = %s" % (i, self.ObjectField(offset))) 14791cb0ef41Sopenharmony_ci except TypeError: 14801cb0ef41Sopenharmony_ci p.Dedent() 14811cb0ef41Sopenharmony_ci p.Print("...") 14821cb0ef41Sopenharmony_ci p.Print("}") 14831cb0ef41Sopenharmony_ci return 14841cb0ef41Sopenharmony_ci p.Dedent() 14851cb0ef41Sopenharmony_ci p.Print("}") 14861cb0ef41Sopenharmony_ci 14871cb0ef41Sopenharmony_ci def __str__(self): 14881cb0ef41Sopenharmony_ci return "FixedArray(%08x, length=%d)" % (self.address, self.length) 14891cb0ef41Sopenharmony_ci 14901cb0ef41Sopenharmony_ci 14911cb0ef41Sopenharmony_ciclass DescriptorArray(object): 14921cb0ef41Sopenharmony_ci def __init__(self, array): 14931cb0ef41Sopenharmony_ci self.array = array 14941cb0ef41Sopenharmony_ci 14951cb0ef41Sopenharmony_ci def Length(self): 14961cb0ef41Sopenharmony_ci return self.array.Get(0) 14971cb0ef41Sopenharmony_ci 14981cb0ef41Sopenharmony_ci def Decode(self, offset, size, value): 14991cb0ef41Sopenharmony_ci return (value >> offset) & ((1 << size) - 1) 15001cb0ef41Sopenharmony_ci 15011cb0ef41Sopenharmony_ci TYPES = [ 15021cb0ef41Sopenharmony_ci "normal", 15031cb0ef41Sopenharmony_ci "field", 15041cb0ef41Sopenharmony_ci "function", 15051cb0ef41Sopenharmony_ci "callbacks" 15061cb0ef41Sopenharmony_ci ] 15071cb0ef41Sopenharmony_ci 15081cb0ef41Sopenharmony_ci def Type(self, value): 15091cb0ef41Sopenharmony_ci return DescriptorArray.TYPES[self.Decode(0, 3, value)] 15101cb0ef41Sopenharmony_ci 15111cb0ef41Sopenharmony_ci def Attributes(self, value): 15121cb0ef41Sopenharmony_ci attributes = self.Decode(3, 3, value) 15131cb0ef41Sopenharmony_ci result = [] 15141cb0ef41Sopenharmony_ci if (attributes & 0): result += ["ReadOnly"] 15151cb0ef41Sopenharmony_ci if (attributes & 1): result += ["DontEnum"] 15161cb0ef41Sopenharmony_ci if (attributes & 2): result += ["DontDelete"] 15171cb0ef41Sopenharmony_ci return "[" + (",".join(result)) + "]" 15181cb0ef41Sopenharmony_ci 15191cb0ef41Sopenharmony_ci def Deleted(self, value): 15201cb0ef41Sopenharmony_ci return self.Decode(6, 1, value) == 1 15211cb0ef41Sopenharmony_ci 15221cb0ef41Sopenharmony_ci def FieldIndex(self, value): 15231cb0ef41Sopenharmony_ci return self.Decode(20, 11, value) 15241cb0ef41Sopenharmony_ci 15251cb0ef41Sopenharmony_ci def Pointer(self, value): 15261cb0ef41Sopenharmony_ci return self.Decode(6, 11, value) 15271cb0ef41Sopenharmony_ci 15281cb0ef41Sopenharmony_ci def Details(self, di, value): 15291cb0ef41Sopenharmony_ci return ( 15301cb0ef41Sopenharmony_ci di, 15311cb0ef41Sopenharmony_ci self.Type(value), 15321cb0ef41Sopenharmony_ci self.Attributes(value), 15331cb0ef41Sopenharmony_ci self.FieldIndex(value), 15341cb0ef41Sopenharmony_ci self.Pointer(value) 15351cb0ef41Sopenharmony_ci ) 15361cb0ef41Sopenharmony_ci 15371cb0ef41Sopenharmony_ci 15381cb0ef41Sopenharmony_ci def Print(self, p): 15391cb0ef41Sopenharmony_ci length = self.Length() 15401cb0ef41Sopenharmony_ci array = self.array 15411cb0ef41Sopenharmony_ci 15421cb0ef41Sopenharmony_ci p.Print("Descriptors(%08x, length=%d)" % (array.address, length)) 15431cb0ef41Sopenharmony_ci p.Print("[et] %s" % (array.Get(1))) 15441cb0ef41Sopenharmony_ci 15451cb0ef41Sopenharmony_ci for di in range(length): 15461cb0ef41Sopenharmony_ci i = 2 + di * 3 15471cb0ef41Sopenharmony_ci p.Print("0x%x" % (array.address + array.MemberOffset(i))) 15481cb0ef41Sopenharmony_ci p.Print("[%i] name: %s" % (di, array.Get(i + 0))) 15491cb0ef41Sopenharmony_ci p.Print("[%i] details: %s %s field-index %i pointer %i" % \ 15501cb0ef41Sopenharmony_ci self.Details(di, array.Get(i + 1))) 15511cb0ef41Sopenharmony_ci p.Print("[%i] value: %s" % (di, array.Get(i + 2))) 15521cb0ef41Sopenharmony_ci 15531cb0ef41Sopenharmony_ci end = self.array.length // 3 15541cb0ef41Sopenharmony_ci if length != end: 15551cb0ef41Sopenharmony_ci p.Print("[%i-%i] slack descriptors" % (length, end)) 15561cb0ef41Sopenharmony_ci 15571cb0ef41Sopenharmony_ci 15581cb0ef41Sopenharmony_ciclass TransitionArray(object): 15591cb0ef41Sopenharmony_ci def __init__(self, array): 15601cb0ef41Sopenharmony_ci self.array = array 15611cb0ef41Sopenharmony_ci 15621cb0ef41Sopenharmony_ci def IsSimpleTransition(self): 15631cb0ef41Sopenharmony_ci return self.array.length <= 2 15641cb0ef41Sopenharmony_ci 15651cb0ef41Sopenharmony_ci def Length(self): 15661cb0ef41Sopenharmony_ci # SimpleTransition cases 15671cb0ef41Sopenharmony_ci if self.IsSimpleTransition(): 15681cb0ef41Sopenharmony_ci return self.array.length - 1 15691cb0ef41Sopenharmony_ci return (self.array.length - 3) // 2 15701cb0ef41Sopenharmony_ci 15711cb0ef41Sopenharmony_ci def Print(self, p): 15721cb0ef41Sopenharmony_ci length = self.Length() 15731cb0ef41Sopenharmony_ci array = self.array 15741cb0ef41Sopenharmony_ci 15751cb0ef41Sopenharmony_ci p.Print("Transitions(%08x, length=%d)" % (array.address, length)) 15761cb0ef41Sopenharmony_ci p.Print("[backpointer] %s" % (array.Get(0))) 15771cb0ef41Sopenharmony_ci if self.IsSimpleTransition(): 15781cb0ef41Sopenharmony_ci if length == 1: 15791cb0ef41Sopenharmony_ci p.Print("[simple target] %s" % (array.Get(1))) 15801cb0ef41Sopenharmony_ci return 15811cb0ef41Sopenharmony_ci 15821cb0ef41Sopenharmony_ci elements = array.Get(1) 15831cb0ef41Sopenharmony_ci if elements is not None: 15841cb0ef41Sopenharmony_ci p.Print("[elements ] %s" % (elements)) 15851cb0ef41Sopenharmony_ci 15861cb0ef41Sopenharmony_ci prototype = array.Get(2) 15871cb0ef41Sopenharmony_ci if prototype is not None: 15881cb0ef41Sopenharmony_ci p.Print("[prototype ] %s" % (prototype)) 15891cb0ef41Sopenharmony_ci 15901cb0ef41Sopenharmony_ci for di in range(length): 15911cb0ef41Sopenharmony_ci i = 3 + di * 2 15921cb0ef41Sopenharmony_ci p.Print("[%i] symbol: %s" % (di, array.Get(i + 0))) 15931cb0ef41Sopenharmony_ci p.Print("[%i] target: %s" % (di, array.Get(i + 1))) 15941cb0ef41Sopenharmony_ci 15951cb0ef41Sopenharmony_ci 15961cb0ef41Sopenharmony_ciclass JSFunction(HeapObject): 15971cb0ef41Sopenharmony_ci def CodeEntryOffset(self): 15981cb0ef41Sopenharmony_ci return 3 * self.heap.TaggedPointerSize() 15991cb0ef41Sopenharmony_ci 16001cb0ef41Sopenharmony_ci def SharedOffset(self): 16011cb0ef41Sopenharmony_ci return 5 * self.heap.TaggedPointerSize() 16021cb0ef41Sopenharmony_ci 16031cb0ef41Sopenharmony_ci def __init__(self, heap, map, address): 16041cb0ef41Sopenharmony_ci HeapObject.__init__(self, heap, map, address) 16051cb0ef41Sopenharmony_ci code_entry = \ 16061cb0ef41Sopenharmony_ci heap.reader.ReadU32(self.address + self.CodeEntryOffset()) 16071cb0ef41Sopenharmony_ci self.code = heap.FindObject(code_entry - Code.HeaderSize(heap) + 1) 16081cb0ef41Sopenharmony_ci self.shared = self.ObjectField(self.SharedOffset()) 16091cb0ef41Sopenharmony_ci 16101cb0ef41Sopenharmony_ci def Print(self, p): 16111cb0ef41Sopenharmony_ci source = "\n".join(" %s" % line for line in self._GetSource().split("\n")) 16121cb0ef41Sopenharmony_ci p.Print("JSFunction(%s) {" % self.heap.reader.FormatIntPtr(self.address)) 16131cb0ef41Sopenharmony_ci p.Indent() 16141cb0ef41Sopenharmony_ci p.Print("inferred name: %s" % self.shared.inferred_name) 16151cb0ef41Sopenharmony_ci if self.shared.script.Is(Script) and self.shared.script.name.Is(String): 16161cb0ef41Sopenharmony_ci p.Print("script name: %s" % self.shared.script.name) 16171cb0ef41Sopenharmony_ci p.Print("source:") 16181cb0ef41Sopenharmony_ci p.PrintLines(self._GetSource().split("\n")) 16191cb0ef41Sopenharmony_ci p.Print("code:") 16201cb0ef41Sopenharmony_ci self.code.Print(p) 16211cb0ef41Sopenharmony_ci if self.code != self.shared.code: 16221cb0ef41Sopenharmony_ci p.Print("unoptimized code:") 16231cb0ef41Sopenharmony_ci self.shared.code.Print(p) 16241cb0ef41Sopenharmony_ci p.Dedent() 16251cb0ef41Sopenharmony_ci p.Print("}") 16261cb0ef41Sopenharmony_ci 16271cb0ef41Sopenharmony_ci def __str__(self): 16281cb0ef41Sopenharmony_ci inferred_name = "" 16291cb0ef41Sopenharmony_ci if self.shared is not None and self.shared.Is(SharedFunctionInfo): 16301cb0ef41Sopenharmony_ci inferred_name = self.shared.inferred_name 16311cb0ef41Sopenharmony_ci return "JSFunction(%s, %s) " % \ 16321cb0ef41Sopenharmony_ci (self.heap.reader.FormatIntPtr(self.address), inferred_name) 16331cb0ef41Sopenharmony_ci 16341cb0ef41Sopenharmony_ci def _GetSource(self): 16351cb0ef41Sopenharmony_ci source = "?source?" 16361cb0ef41Sopenharmony_ci start = self.shared.start_position 16371cb0ef41Sopenharmony_ci end = self.shared.end_position 16381cb0ef41Sopenharmony_ci if not self.shared.script.Is(Script): return source 16391cb0ef41Sopenharmony_ci script_source = self.shared.script.source 16401cb0ef41Sopenharmony_ci if not script_source.Is(String): return source 16411cb0ef41Sopenharmony_ci if start and end: 16421cb0ef41Sopenharmony_ci source = script_source.GetChars()[start:end] 16431cb0ef41Sopenharmony_ci return source 16441cb0ef41Sopenharmony_ci 16451cb0ef41Sopenharmony_ci 16461cb0ef41Sopenharmony_ciclass SharedFunctionInfo(HeapObject): 16471cb0ef41Sopenharmony_ci def CodeOffset(self): 16481cb0ef41Sopenharmony_ci return 2 * self.heap.TaggedPointerSize() 16491cb0ef41Sopenharmony_ci 16501cb0ef41Sopenharmony_ci def ScriptOffset(self): 16511cb0ef41Sopenharmony_ci return 7 * self.heap.TaggedPointerSize() 16521cb0ef41Sopenharmony_ci 16531cb0ef41Sopenharmony_ci def InferredNameOffset(self): 16541cb0ef41Sopenharmony_ci return 9 * self.heap.TaggedPointerSize() 16551cb0ef41Sopenharmony_ci 16561cb0ef41Sopenharmony_ci def EndPositionOffset(self): 16571cb0ef41Sopenharmony_ci return 12 * self.heap.TaggedPointerSize() + 4 * self.heap.IntSize() 16581cb0ef41Sopenharmony_ci 16591cb0ef41Sopenharmony_ci def StartPositionAndTypeOffset(self): 16601cb0ef41Sopenharmony_ci return 12 * self.heap.TaggedPointerSize() + 5 * self.heap.IntSize() 16611cb0ef41Sopenharmony_ci 16621cb0ef41Sopenharmony_ci def __init__(self, heap, map, address): 16631cb0ef41Sopenharmony_ci HeapObject.__init__(self, heap, map, address) 16641cb0ef41Sopenharmony_ci try: 16651cb0ef41Sopenharmony_ci self.code = self.ObjectField(self.CodeOffset()) 16661cb0ef41Sopenharmony_ci self.script = self.ObjectField(self.ScriptOffset()) 16671cb0ef41Sopenharmony_ci self.inferred_name = self.ObjectField(self.InferredNameOffset()) 16681cb0ef41Sopenharmony_ci if heap.TaggedPointerSize() == 8: 16691cb0ef41Sopenharmony_ci start_position_and_type = \ 16701cb0ef41Sopenharmony_ci heap.reader.ReadU32(self.StartPositionAndTypeOffset()) 16711cb0ef41Sopenharmony_ci self.start_position = start_position_and_type >> 2 16721cb0ef41Sopenharmony_ci pseudo_smi_end_position = \ 16731cb0ef41Sopenharmony_ci heap.reader.ReadU32(self.EndPositionOffset()) 16741cb0ef41Sopenharmony_ci self.end_position = pseudo_smi_end_position >> 2 16751cb0ef41Sopenharmony_ci else: 16761cb0ef41Sopenharmony_ci start_position_and_type = \ 16771cb0ef41Sopenharmony_ci self.SmiField(self.StartPositionAndTypeOffset()) 16781cb0ef41Sopenharmony_ci if start_position_and_type: 16791cb0ef41Sopenharmony_ci self.start_position = start_position_and_type >> 2 16801cb0ef41Sopenharmony_ci else: 16811cb0ef41Sopenharmony_ci self.start_position = None 16821cb0ef41Sopenharmony_ci self.end_position = \ 16831cb0ef41Sopenharmony_ci self.SmiField(self.EndPositionOffset()) 16841cb0ef41Sopenharmony_ci except: 16851cb0ef41Sopenharmony_ci print("*** Error while reading SharedFunctionInfo") 16861cb0ef41Sopenharmony_ci 16871cb0ef41Sopenharmony_ci 16881cb0ef41Sopenharmony_ciclass Script(HeapObject): 16891cb0ef41Sopenharmony_ci def SourceOffset(self): 16901cb0ef41Sopenharmony_ci return self.heap.TaggedPointerSize() 16911cb0ef41Sopenharmony_ci 16921cb0ef41Sopenharmony_ci def NameOffset(self): 16931cb0ef41Sopenharmony_ci return self.SourceOffset() + self.heap.TaggedPointerSize() 16941cb0ef41Sopenharmony_ci 16951cb0ef41Sopenharmony_ci def __init__(self, heap, map, address): 16961cb0ef41Sopenharmony_ci HeapObject.__init__(self, heap, map, address) 16971cb0ef41Sopenharmony_ci self.source = self.ObjectField(self.SourceOffset()) 16981cb0ef41Sopenharmony_ci self.name = self.ObjectField(self.NameOffset()) 16991cb0ef41Sopenharmony_ci 17001cb0ef41Sopenharmony_ci 17011cb0ef41Sopenharmony_ciclass CodeCache(HeapObject): 17021cb0ef41Sopenharmony_ci def DefaultCacheOffset(self): 17031cb0ef41Sopenharmony_ci return self.heap.TaggedPointerSize() 17041cb0ef41Sopenharmony_ci 17051cb0ef41Sopenharmony_ci def NormalTypeCacheOffset(self): 17061cb0ef41Sopenharmony_ci return self.DefaultCacheOffset() + self.heap.TaggedPointerSize() 17071cb0ef41Sopenharmony_ci 17081cb0ef41Sopenharmony_ci def __init__(self, heap, map, address): 17091cb0ef41Sopenharmony_ci HeapObject.__init__(self, heap, map, address) 17101cb0ef41Sopenharmony_ci self.default_cache = self.ObjectField(self.DefaultCacheOffset()) 17111cb0ef41Sopenharmony_ci self.normal_type_cache = self.ObjectField(self.NormalTypeCacheOffset()) 17121cb0ef41Sopenharmony_ci 17131cb0ef41Sopenharmony_ci def Print(self, p): 17141cb0ef41Sopenharmony_ci p.Print("CodeCache(%s) {" % self.heap.reader.FormatIntPtr(self.address)) 17151cb0ef41Sopenharmony_ci p.Indent() 17161cb0ef41Sopenharmony_ci p.Print("default cache: %s" % self.default_cache) 17171cb0ef41Sopenharmony_ci p.Print("normal type cache: %s" % self.normal_type_cache) 17181cb0ef41Sopenharmony_ci p.Dedent() 17191cb0ef41Sopenharmony_ci p.Print("}") 17201cb0ef41Sopenharmony_ci 17211cb0ef41Sopenharmony_ci 17221cb0ef41Sopenharmony_ciclass Code(HeapObject): 17231cb0ef41Sopenharmony_ci CODE_ALIGNMENT_MASK = (1 << 5) - 1 17241cb0ef41Sopenharmony_ci 17251cb0ef41Sopenharmony_ci def InstructionSizeOffset(self): 17261cb0ef41Sopenharmony_ci return self.heap.TaggedPointerSize() 17271cb0ef41Sopenharmony_ci 17281cb0ef41Sopenharmony_ci @staticmethod 17291cb0ef41Sopenharmony_ci def HeaderSize(heap): 17301cb0ef41Sopenharmony_ci return (heap.TaggedPointerSize() + heap.IntSize() + \ 17311cb0ef41Sopenharmony_ci 4 * heap.TaggedPointerSize() + 3 * heap.IntSize() + \ 17321cb0ef41Sopenharmony_ci Code.CODE_ALIGNMENT_MASK) & ~Code.CODE_ALIGNMENT_MASK 17331cb0ef41Sopenharmony_ci 17341cb0ef41Sopenharmony_ci def __init__(self, heap, map, address): 17351cb0ef41Sopenharmony_ci HeapObject.__init__(self, heap, map, address) 17361cb0ef41Sopenharmony_ci self.entry = self.address + Code.HeaderSize(heap) 17371cb0ef41Sopenharmony_ci self.instruction_size = \ 17381cb0ef41Sopenharmony_ci heap.reader.ReadU32(self.address + self.InstructionSizeOffset()) 17391cb0ef41Sopenharmony_ci 17401cb0ef41Sopenharmony_ci def Print(self, p): 17411cb0ef41Sopenharmony_ci lines = self.heap.reader.GetDisasmLines(self.entry, self.instruction_size) 17421cb0ef41Sopenharmony_ci p.Print("Code(%s) {" % self.heap.reader.FormatIntPtr(self.address)) 17431cb0ef41Sopenharmony_ci p.Indent() 17441cb0ef41Sopenharmony_ci p.Print("instruction_size: %d" % self.instruction_size) 17451cb0ef41Sopenharmony_ci p.PrintLines(self._FormatLine(line) for line in lines) 17461cb0ef41Sopenharmony_ci p.Dedent() 17471cb0ef41Sopenharmony_ci p.Print("}") 17481cb0ef41Sopenharmony_ci 17491cb0ef41Sopenharmony_ci def _FormatLine(self, line): 17501cb0ef41Sopenharmony_ci return FormatDisasmLine(self.entry, self.heap, line) 17511cb0ef41Sopenharmony_ci 17521cb0ef41Sopenharmony_ci 17531cb0ef41Sopenharmony_ciclass V8Heap(object): 17541cb0ef41Sopenharmony_ci CLASS_MAP = { 17551cb0ef41Sopenharmony_ci "SYMBOL_TYPE": SeqString, 17561cb0ef41Sopenharmony_ci "ONE_BYTE_SYMBOL_TYPE": SeqString, 17571cb0ef41Sopenharmony_ci "CONS_SYMBOL_TYPE": ConsString, 17581cb0ef41Sopenharmony_ci "CONS_ONE_BYTE_SYMBOL_TYPE": ConsString, 17591cb0ef41Sopenharmony_ci "EXTERNAL_SYMBOL_TYPE": ExternalString, 17601cb0ef41Sopenharmony_ci "EXTERNAL_SYMBOL_WITH_ONE_BYTE_DATA_TYPE": ExternalString, 17611cb0ef41Sopenharmony_ci "EXTERNAL_ONE_BYTE_SYMBOL_TYPE": ExternalString, 17621cb0ef41Sopenharmony_ci "UNCACHED_EXTERNAL_SYMBOL_TYPE": ExternalString, 17631cb0ef41Sopenharmony_ci "UNCACHED_EXTERNAL_SYMBOL_WITH_ONE_BYTE_DATA_TYPE": ExternalString, 17641cb0ef41Sopenharmony_ci "UNCACHED_EXTERNAL_ONE_BYTE_SYMBOL_TYPE": ExternalString, 17651cb0ef41Sopenharmony_ci "STRING_TYPE": SeqString, 17661cb0ef41Sopenharmony_ci "ONE_BYTE_STRING_TYPE": SeqString, 17671cb0ef41Sopenharmony_ci "CONS_STRING_TYPE": ConsString, 17681cb0ef41Sopenharmony_ci "CONS_ONE_BYTE_STRING_TYPE": ConsString, 17691cb0ef41Sopenharmony_ci "EXTERNAL_STRING_TYPE": ExternalString, 17701cb0ef41Sopenharmony_ci "EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE": ExternalString, 17711cb0ef41Sopenharmony_ci "EXTERNAL_ONE_BYTE_STRING_TYPE": ExternalString, 17721cb0ef41Sopenharmony_ci "MAP_TYPE": Map, 17731cb0ef41Sopenharmony_ci "ODDBALL_TYPE": Oddball, 17741cb0ef41Sopenharmony_ci "FIXED_ARRAY_TYPE": FixedArray, 17751cb0ef41Sopenharmony_ci "HASH_TABLE_TYPE": FixedArray, 17761cb0ef41Sopenharmony_ci "OBJECT_BOILERPLATE_DESCRIPTION_TYPE": FixedArray, 17771cb0ef41Sopenharmony_ci "SCOPE_INFO_TYPE": FixedArray, 17781cb0ef41Sopenharmony_ci "JS_FUNCTION_TYPE": JSFunction, 17791cb0ef41Sopenharmony_ci "SHARED_FUNCTION_INFO_TYPE": SharedFunctionInfo, 17801cb0ef41Sopenharmony_ci "SCRIPT_TYPE": Script, 17811cb0ef41Sopenharmony_ci "CODE_CACHE_TYPE": CodeCache, 17821cb0ef41Sopenharmony_ci "CODE_TYPE": Code, 17831cb0ef41Sopenharmony_ci } 17841cb0ef41Sopenharmony_ci 17851cb0ef41Sopenharmony_ci def __init__(self, reader, stack_map): 17861cb0ef41Sopenharmony_ci self.reader = reader 17871cb0ef41Sopenharmony_ci self.stack_map = stack_map 17881cb0ef41Sopenharmony_ci self.objects = {} 17891cb0ef41Sopenharmony_ci 17901cb0ef41Sopenharmony_ci def FindObjectOrSmi(self, tagged_address): 17911cb0ef41Sopenharmony_ci if self.IsSmi(tagged_address): return self.SmiUntag(tagged_address) 17921cb0ef41Sopenharmony_ci return self.FindObject(tagged_address) 17931cb0ef41Sopenharmony_ci 17941cb0ef41Sopenharmony_ci def FindObject(self, tagged_address): 17951cb0ef41Sopenharmony_ci if tagged_address in self.objects: 17961cb0ef41Sopenharmony_ci return self.objects[tagged_address] 17971cb0ef41Sopenharmony_ci if not self.IsTaggedObjectAddress(tagged_address): return None 17981cb0ef41Sopenharmony_ci address = tagged_address - 1 17991cb0ef41Sopenharmony_ci if not self.reader.IsValidAddress(address): return None 18001cb0ef41Sopenharmony_ci map_tagged_address = self.reader.ReadTagged(address) 18011cb0ef41Sopenharmony_ci if tagged_address == map_tagged_address: 18021cb0ef41Sopenharmony_ci # Meta map? 18031cb0ef41Sopenharmony_ci meta_map = Map(self, None, address) 18041cb0ef41Sopenharmony_ci instance_type_name = INSTANCE_TYPES.get(meta_map.instance_type) 18051cb0ef41Sopenharmony_ci if instance_type_name != "MAP_TYPE": return None 18061cb0ef41Sopenharmony_ci meta_map.map = meta_map 18071cb0ef41Sopenharmony_ci object = meta_map 18081cb0ef41Sopenharmony_ci else: 18091cb0ef41Sopenharmony_ci map = self.FindMap(map_tagged_address) 18101cb0ef41Sopenharmony_ci if map is None: return None 18111cb0ef41Sopenharmony_ci instance_type_name = INSTANCE_TYPES.get(map.instance_type) 18121cb0ef41Sopenharmony_ci if instance_type_name is None: return None 18131cb0ef41Sopenharmony_ci cls = V8Heap.CLASS_MAP.get(instance_type_name, HeapObject) 18141cb0ef41Sopenharmony_ci object = cls(self, map, address) 18151cb0ef41Sopenharmony_ci self.objects[tagged_address] = object 18161cb0ef41Sopenharmony_ci return object 18171cb0ef41Sopenharmony_ci 18181cb0ef41Sopenharmony_ci def FindMap(self, tagged_address): 18191cb0ef41Sopenharmony_ci address = self.FindMapAddress(tagged_address) 18201cb0ef41Sopenharmony_ci if not address: return None 18211cb0ef41Sopenharmony_ci object = Map(self, None, address) 18221cb0ef41Sopenharmony_ci return object 18231cb0ef41Sopenharmony_ci 18241cb0ef41Sopenharmony_ci def FindMapAddress(self, tagged_address): 18251cb0ef41Sopenharmony_ci if not self.IsTaggedMapAddress(tagged_address): return None 18261cb0ef41Sopenharmony_ci address = tagged_address - 1 18271cb0ef41Sopenharmony_ci if not self.reader.IsValidAddress(address): return None 18281cb0ef41Sopenharmony_ci return address 18291cb0ef41Sopenharmony_ci 18301cb0ef41Sopenharmony_ci def IntSize(self): 18311cb0ef41Sopenharmony_ci return 4 18321cb0ef41Sopenharmony_ci 18331cb0ef41Sopenharmony_ci def MachinePointerSize(self): 18341cb0ef41Sopenharmony_ci return self.reader.MachinePointerSize() 18351cb0ef41Sopenharmony_ci 18361cb0ef41Sopenharmony_ci def TaggedPointerSize(self): 18371cb0ef41Sopenharmony_ci return self.reader.TaggedPointerSize() 18381cb0ef41Sopenharmony_ci 18391cb0ef41Sopenharmony_ci def IsPointerCompressed(self): 18401cb0ef41Sopenharmony_ci return self.reader.IsPointerCompressed() 18411cb0ef41Sopenharmony_ci 18421cb0ef41Sopenharmony_ci def ObjectAlignmentMask(self): 18431cb0ef41Sopenharmony_ci return self.TaggedPointerSize() - 1 18441cb0ef41Sopenharmony_ci 18451cb0ef41Sopenharmony_ci def IsTaggedObjectAddress(self, address): 18461cb0ef41Sopenharmony_ci return (address & self.ObjectAlignmentMask()) == 1 18471cb0ef41Sopenharmony_ci 18481cb0ef41Sopenharmony_ci def IsValidTaggedObjectAddress(self, address): 18491cb0ef41Sopenharmony_ci if not self.IsTaggedObjectAddress(address): return False 18501cb0ef41Sopenharmony_ci return self.reader.IsValidAddress(address) 18511cb0ef41Sopenharmony_ci 18521cb0ef41Sopenharmony_ci def IsTaggedMapAddress(self, address): 18531cb0ef41Sopenharmony_ci return (address & self.MapAlignmentMask()) == 1 18541cb0ef41Sopenharmony_ci 18551cb0ef41Sopenharmony_ci def MapAlignmentMask(self): 18561cb0ef41Sopenharmony_ci if self.reader.arch == MD_CPU_ARCHITECTURE_AMD64: 18571cb0ef41Sopenharmony_ci return (1 << 4) - 1 18581cb0ef41Sopenharmony_ci elif self.reader.arch == MD_CPU_ARCHITECTURE_ARM: 18591cb0ef41Sopenharmony_ci return (1 << 4) - 1 18601cb0ef41Sopenharmony_ci elif self.reader.arch == MD_CPU_ARCHITECTURE_ARM64: 18611cb0ef41Sopenharmony_ci return (1 << 4) - 1 18621cb0ef41Sopenharmony_ci elif self.reader.arch == MD_CPU_ARCHITECTURE_X86: 18631cb0ef41Sopenharmony_ci return (1 << 5) - 1 18641cb0ef41Sopenharmony_ci 18651cb0ef41Sopenharmony_ci def PageAlignmentMask(self): 18661cb0ef41Sopenharmony_ci return (1 << 19) - 1 18671cb0ef41Sopenharmony_ci 18681cb0ef41Sopenharmony_ci def IsTaggedAddress(self, address): 18691cb0ef41Sopenharmony_ci return (address & self.ObjectAlignmentMask()) == 1 18701cb0ef41Sopenharmony_ci 18711cb0ef41Sopenharmony_ci def IsSmi(self, tagged_address): 18721cb0ef41Sopenharmony_ci if self.reader.Is64() and not self.reader.IsPointerCompressed(): 18731cb0ef41Sopenharmony_ci return (tagged_address & 0xFFFFFFFF) == 0 18741cb0ef41Sopenharmony_ci return not self.IsTaggedAddress(tagged_address) 18751cb0ef41Sopenharmony_ci 18761cb0ef41Sopenharmony_ci def SmiUntag(self, tagged_address): 18771cb0ef41Sopenharmony_ci if self.reader.Is64() and not self.reader.IsPointerCompressed(): 18781cb0ef41Sopenharmony_ci return tagged_address >> 32 18791cb0ef41Sopenharmony_ci return (tagged_address >> 1) & 0xFFFFFFFF 18801cb0ef41Sopenharmony_ci 18811cb0ef41Sopenharmony_ci def AddressTypeMarker(self, address): 18821cb0ef41Sopenharmony_ci if not self.reader.IsValidAddress(address): return " " 18831cb0ef41Sopenharmony_ci if self.reader.IsExceptionStackAddress(address): return "S" 18841cb0ef41Sopenharmony_ci if self.reader.IsModuleAddress(address): return "C" 18851cb0ef41Sopenharmony_ci if self.IsTaggedAddress(address): 18861cb0ef41Sopenharmony_ci # Cannot have an tagged pointer into the stack 18871cb0ef41Sopenharmony_ci if self.reader.IsAnyExceptionStackAddress(address): return "s" 18881cb0ef41Sopenharmony_ci return "T" 18891cb0ef41Sopenharmony_ci return "*" 18901cb0ef41Sopenharmony_ci 18911cb0ef41Sopenharmony_ci def FormatIntPtr(self, address): 18921cb0ef41Sopenharmony_ci marker = self.AddressTypeMarker(address) 18931cb0ef41Sopenharmony_ci address = self.reader.FormatIntPtr(address) 18941cb0ef41Sopenharmony_ci if marker == " ": return address 18951cb0ef41Sopenharmony_ci return "%s %s" % (address, marker) 18961cb0ef41Sopenharmony_ci 18971cb0ef41Sopenharmony_ci def RelativeOffset(self, slot, address): 18981cb0ef41Sopenharmony_ci if not self.reader.IsValidAlignedAddress(slot): return None 18991cb0ef41Sopenharmony_ci if self.IsTaggedObjectAddress(address): 19001cb0ef41Sopenharmony_ci address -= 1 19011cb0ef41Sopenharmony_ci if not self.reader.IsValidAlignedAddress(address): return None 19021cb0ef41Sopenharmony_ci offset = (address - slot) / self.MachinePointerSize() 19031cb0ef41Sopenharmony_ci 19041cb0ef41Sopenharmony_ci lower_limit = -32 19051cb0ef41Sopenharmony_ci upper_limit = 128 19061cb0ef41Sopenharmony_ci if self.reader.IsExceptionStackAddress(address): 19071cb0ef41Sopenharmony_ci upper_limit = 0xFFFFFF 19081cb0ef41Sopenharmony_ci 19091cb0ef41Sopenharmony_ci if offset < lower_limit or upper_limit < offset: return None 19101cb0ef41Sopenharmony_ci target_address = self.reader.ReadUIntPtr(address) 19111cb0ef41Sopenharmony_ci return "[%+02d]=%s %s" % (offset, self.reader.FormatIntPtr(target_address), 19121cb0ef41Sopenharmony_ci self.AddressTypeMarker(target_address)) 19131cb0ef41Sopenharmony_ci 19141cb0ef41Sopenharmony_ci def FindObjectPointers(self, start=0, end=0): 19151cb0ef41Sopenharmony_ci objects = set() 19161cb0ef41Sopenharmony_ci def find_object_in_region(reader, start, size, location): 19171cb0ef41Sopenharmony_ci for slot in range(start, start + size, self.reader.TaggedPointerSize()): 19181cb0ef41Sopenharmony_ci if not self.reader.IsValidAddress(slot): break 19191cb0ef41Sopenharmony_ci # Collect only tagged pointers (object) to tagged pointers (map) 19201cb0ef41Sopenharmony_ci tagged_address = self.reader.ReadTagged(slot) 19211cb0ef41Sopenharmony_ci if not self.IsValidTaggedObjectAddress(tagged_address): continue 19221cb0ef41Sopenharmony_ci map_address = self.reader.ReadTagged(tagged_address - 1) 19231cb0ef41Sopenharmony_ci if not self.IsTaggedMapAddress(map_address): continue 19241cb0ef41Sopenharmony_ci objects.add(tagged_address) 19251cb0ef41Sopenharmony_ci 19261cb0ef41Sopenharmony_ci if not start and not end: 19271cb0ef41Sopenharmony_ci self.reader.ForEachMemoryRegion(find_object_in_region) 19281cb0ef41Sopenharmony_ci else: 19291cb0ef41Sopenharmony_ci find_object_in_region(self.reader, start, end-start, None) 19301cb0ef41Sopenharmony_ci 19311cb0ef41Sopenharmony_ci return objects 19321cb0ef41Sopenharmony_ci 19331cb0ef41Sopenharmony_ciclass KnownObject(HeapObject): 19341cb0ef41Sopenharmony_ci def __init__(self, heap, known_name): 19351cb0ef41Sopenharmony_ci HeapObject.__init__(self, heap, None, None) 19361cb0ef41Sopenharmony_ci self.known_name = known_name 19371cb0ef41Sopenharmony_ci 19381cb0ef41Sopenharmony_ci def __str__(self): 19391cb0ef41Sopenharmony_ci return "<%s>" % self.known_name 19401cb0ef41Sopenharmony_ci 19411cb0ef41Sopenharmony_ci 19421cb0ef41Sopenharmony_ciclass KnownMap(HeapObject): 19431cb0ef41Sopenharmony_ci def __init__(self, heap, known_name, instance_type): 19441cb0ef41Sopenharmony_ci HeapObject.__init__(self, heap, None, None) 19451cb0ef41Sopenharmony_ci self.instance_type = instance_type 19461cb0ef41Sopenharmony_ci self.known_name = known_name 19471cb0ef41Sopenharmony_ci 19481cb0ef41Sopenharmony_ci def __str__(self): 19491cb0ef41Sopenharmony_ci return "<%s>" % self.known_name 19501cb0ef41Sopenharmony_ci 19511cb0ef41Sopenharmony_ci 19521cb0ef41Sopenharmony_ciCOMMENT_RE = re.compile(r"^C (0x[0-9a-fA-F]+) (.*)$") 19531cb0ef41Sopenharmony_ciPAGEADDRESS_RE = re.compile( 19541cb0ef41Sopenharmony_ci r"^P (mappage|oldpage) (0x[0-9a-fA-F]+)$") 19551cb0ef41Sopenharmony_ci 19561cb0ef41Sopenharmony_ci 19571cb0ef41Sopenharmony_ciclass InspectionInfo(object): 19581cb0ef41Sopenharmony_ci def __init__(self, minidump_name, reader): 19591cb0ef41Sopenharmony_ci self.comment_file = minidump_name + ".comments" 19601cb0ef41Sopenharmony_ci self.address_comments = {} 19611cb0ef41Sopenharmony_ci self.page_address = {} 19621cb0ef41Sopenharmony_ci if os.path.exists(self.comment_file): 19631cb0ef41Sopenharmony_ci with open(self.comment_file, "r") as f: 19641cb0ef41Sopenharmony_ci lines = f.readlines() 19651cb0ef41Sopenharmony_ci f.close() 19661cb0ef41Sopenharmony_ci 19671cb0ef41Sopenharmony_ci for l in lines: 19681cb0ef41Sopenharmony_ci m = COMMENT_RE.match(l) 19691cb0ef41Sopenharmony_ci if m: 19701cb0ef41Sopenharmony_ci self.address_comments[int(m.group(1), 0)] = m.group(2) 19711cb0ef41Sopenharmony_ci m = PAGEADDRESS_RE.match(l) 19721cb0ef41Sopenharmony_ci if m: 19731cb0ef41Sopenharmony_ci self.page_address[m.group(1)] = int(m.group(2), 0) 19741cb0ef41Sopenharmony_ci self.reader = reader 19751cb0ef41Sopenharmony_ci self.styles = {} 19761cb0ef41Sopenharmony_ci self.color_addresses() 19771cb0ef41Sopenharmony_ci return 19781cb0ef41Sopenharmony_ci 19791cb0ef41Sopenharmony_ci def get_page_address(self, page_kind): 19801cb0ef41Sopenharmony_ci return self.page_address.get(page_kind, 0) 19811cb0ef41Sopenharmony_ci 19821cb0ef41Sopenharmony_ci def save_page_address(self, page_kind, address): 19831cb0ef41Sopenharmony_ci with open(self.comment_file, "a") as f: 19841cb0ef41Sopenharmony_ci f.write("P %s 0x%x\n" % (page_kind, address)) 19851cb0ef41Sopenharmony_ci f.close() 19861cb0ef41Sopenharmony_ci 19871cb0ef41Sopenharmony_ci def color_addresses(self): 19881cb0ef41Sopenharmony_ci # Color all stack addresses. 19891cb0ef41Sopenharmony_ci exception_thread = self.reader.thread_map[self.reader.exception.thread_id] 19901cb0ef41Sopenharmony_ci stack_top = self.reader.ExceptionSP() 19911cb0ef41Sopenharmony_ci stack_bottom = exception_thread.stack.start + \ 19921cb0ef41Sopenharmony_ci exception_thread.stack.memory.data_size 19931cb0ef41Sopenharmony_ci frame_pointer = self.reader.ExceptionFP() 19941cb0ef41Sopenharmony_ci self.styles[frame_pointer] = "frame" 19951cb0ef41Sopenharmony_ci for slot in range(stack_top, stack_bottom, 19961cb0ef41Sopenharmony_ci self.reader.MachinePointerSize()): 19971cb0ef41Sopenharmony_ci # stack address 19981cb0ef41Sopenharmony_ci self.styles[slot] = "sa" 19991cb0ef41Sopenharmony_ci for slot in range(stack_top, stack_bottom, 20001cb0ef41Sopenharmony_ci self.reader.MachinePointerSize()): 20011cb0ef41Sopenharmony_ci maybe_address = self.reader.ReadUIntPtr(slot) 20021cb0ef41Sopenharmony_ci # stack value 20031cb0ef41Sopenharmony_ci self.styles[maybe_address] = "sv" 20041cb0ef41Sopenharmony_ci if slot == frame_pointer: 20051cb0ef41Sopenharmony_ci self.styles[slot] = "frame" 20061cb0ef41Sopenharmony_ci frame_pointer = maybe_address 20071cb0ef41Sopenharmony_ci self.styles[self.reader.ExceptionIP()] = "pc" 20081cb0ef41Sopenharmony_ci 20091cb0ef41Sopenharmony_ci def get_style_class(self, address): 20101cb0ef41Sopenharmony_ci return self.styles.get(address, None) 20111cb0ef41Sopenharmony_ci 20121cb0ef41Sopenharmony_ci def get_style_class_string(self, address): 20131cb0ef41Sopenharmony_ci style = self.get_style_class(address) 20141cb0ef41Sopenharmony_ci if style != None: 20151cb0ef41Sopenharmony_ci return " class=%s " % style 20161cb0ef41Sopenharmony_ci else: 20171cb0ef41Sopenharmony_ci return "" 20181cb0ef41Sopenharmony_ci 20191cb0ef41Sopenharmony_ci def set_comment(self, address, comment): 20201cb0ef41Sopenharmony_ci self.address_comments[address] = comment 20211cb0ef41Sopenharmony_ci with open(self.comment_file, "a") as f: 20221cb0ef41Sopenharmony_ci f.write("C 0x%x %s\n" % (address, comment)) 20231cb0ef41Sopenharmony_ci f.close() 20241cb0ef41Sopenharmony_ci 20251cb0ef41Sopenharmony_ci def get_comment(self, address): 20261cb0ef41Sopenharmony_ci return self.address_comments.get(address, "") 20271cb0ef41Sopenharmony_ci 20281cb0ef41Sopenharmony_ci 20291cb0ef41Sopenharmony_ciclass InspectionPadawan(object): 20301cb0ef41Sopenharmony_ci """The padawan can improve annotations by sensing well-known objects.""" 20311cb0ef41Sopenharmony_ci def __init__(self, reader, heap): 20321cb0ef41Sopenharmony_ci self.reader = reader 20331cb0ef41Sopenharmony_ci self.heap = heap 20341cb0ef41Sopenharmony_ci self.known_first_map_page = 0 20351cb0ef41Sopenharmony_ci self.known_first_old_page = 0 20361cb0ef41Sopenharmony_ci self.context = None 20371cb0ef41Sopenharmony_ci 20381cb0ef41Sopenharmony_ci def __getattr__(self, name): 20391cb0ef41Sopenharmony_ci """An InspectionPadawan can be used instead of V8Heap, even though 20401cb0ef41Sopenharmony_ci it does not inherit from V8Heap (aka. mixin).""" 20411cb0ef41Sopenharmony_ci return getattr(self.heap, name) 20421cb0ef41Sopenharmony_ci 20431cb0ef41Sopenharmony_ci def GetPageOffset(self, tagged_address): 20441cb0ef41Sopenharmony_ci return tagged_address & self.heap.PageAlignmentMask() 20451cb0ef41Sopenharmony_ci 20461cb0ef41Sopenharmony_ci def IsInKnownMapSpace(self, tagged_address): 20471cb0ef41Sopenharmony_ci page_address = tagged_address & ~self.heap.PageAlignmentMask() 20481cb0ef41Sopenharmony_ci return page_address == self.known_first_map_page 20491cb0ef41Sopenharmony_ci 20501cb0ef41Sopenharmony_ci def IsInKnownOldSpace(self, tagged_address): 20511cb0ef41Sopenharmony_ci page_address = tagged_address & ~self.heap.PageAlignmentMask() 20521cb0ef41Sopenharmony_ci return page_address == self.known_first_old_page 20531cb0ef41Sopenharmony_ci 20541cb0ef41Sopenharmony_ci def ContainingKnownOldSpaceName(self, tagged_address): 20551cb0ef41Sopenharmony_ci page_address = tagged_address & ~self.heap.PageAlignmentMask() 20561cb0ef41Sopenharmony_ci if page_address == self.known_first_old_page: return "OLD_SPACE" 20571cb0ef41Sopenharmony_ci return None 20581cb0ef41Sopenharmony_ci 20591cb0ef41Sopenharmony_ci def FrameMarkerName(self, value): 20601cb0ef41Sopenharmony_ci # The frame marker is Smi-tagged but not Smi encoded and 0 is not a valid 20611cb0ef41Sopenharmony_ci # frame type. 20621cb0ef41Sopenharmony_ci value = (value >> 1) - 1 20631cb0ef41Sopenharmony_ci if 0 <= value < len(FRAME_MARKERS): 20641cb0ef41Sopenharmony_ci return "Possibly %s frame marker" % FRAME_MARKERS[value] 20651cb0ef41Sopenharmony_ci return None 20661cb0ef41Sopenharmony_ci 20671cb0ef41Sopenharmony_ci def IsFrameMarker(self, slot, address): 20681cb0ef41Sopenharmony_ci if not slot: return False 20691cb0ef41Sopenharmony_ci # Frame markers only occur directly after a frame pointer and only on the 20701cb0ef41Sopenharmony_ci # stack. 20711cb0ef41Sopenharmony_ci if not self.reader.IsExceptionStackAddress(slot): return False 20721cb0ef41Sopenharmony_ci next_slot = slot + self.reader.MachinePointerSize() 20731cb0ef41Sopenharmony_ci if not self.reader.IsValidAddress(next_slot): return False 20741cb0ef41Sopenharmony_ci next_address = self.reader.ReadUIntPtr(next_slot) 20751cb0ef41Sopenharmony_ci return self.reader.IsExceptionStackAddress(next_address) 20761cb0ef41Sopenharmony_ci 20771cb0ef41Sopenharmony_ci def FormatSmi(self, address): 20781cb0ef41Sopenharmony_ci value = self.heap.SmiUntag(address) 20791cb0ef41Sopenharmony_ci # On 32-bit systems almost everything looks like a Smi. 20801cb0ef41Sopenharmony_ci if not self.reader.Is64() or value == 0: return None 20811cb0ef41Sopenharmony_ci return "Smi(%d)" % value 20821cb0ef41Sopenharmony_ci 20831cb0ef41Sopenharmony_ci def SenseObject(self, address, slot=None): 20841cb0ef41Sopenharmony_ci if self.IsFrameMarker(slot, address): 20851cb0ef41Sopenharmony_ci return self.FrameMarkerName(address) 20861cb0ef41Sopenharmony_ci if self.heap.IsSmi(address): 20871cb0ef41Sopenharmony_ci return self.FormatSmi(address) 20881cb0ef41Sopenharmony_ci if not self.heap.IsTaggedAddress(address): return None 20891cb0ef41Sopenharmony_ci tagged_address = address 20901cb0ef41Sopenharmony_ci if self.IsInKnownOldSpace(tagged_address): 20911cb0ef41Sopenharmony_ci offset = self.GetPageOffset(tagged_address) 20921cb0ef41Sopenharmony_ci lookup_key = (self.ContainingKnownOldSpaceName(tagged_address), offset) 20931cb0ef41Sopenharmony_ci known_obj_name = KNOWN_OBJECTS.get(lookup_key) 20941cb0ef41Sopenharmony_ci if known_obj_name: 20951cb0ef41Sopenharmony_ci return KnownObject(self, known_obj_name) 20961cb0ef41Sopenharmony_ci if self.IsInKnownMapSpace(tagged_address): 20971cb0ef41Sopenharmony_ci known_map = self.SenseMap(tagged_address) 20981cb0ef41Sopenharmony_ci if known_map: 20991cb0ef41Sopenharmony_ci return known_map 21001cb0ef41Sopenharmony_ci found_obj = self.heap.FindObject(tagged_address) 21011cb0ef41Sopenharmony_ci if found_obj: return found_obj 21021cb0ef41Sopenharmony_ci address = tagged_address - 1 21031cb0ef41Sopenharmony_ci if self.reader.IsValidAddress(address): 21041cb0ef41Sopenharmony_ci map_tagged_address = self.reader.ReadTagged(address) 21051cb0ef41Sopenharmony_ci map = self.SenseMap(map_tagged_address) 21061cb0ef41Sopenharmony_ci if map is None: return None 21071cb0ef41Sopenharmony_ci instance_type_name = INSTANCE_TYPES.get(map.instance_type) 21081cb0ef41Sopenharmony_ci if instance_type_name is None: return None 21091cb0ef41Sopenharmony_ci cls = V8Heap.CLASS_MAP.get(instance_type_name, HeapObject) 21101cb0ef41Sopenharmony_ci return cls(self, map, address) 21111cb0ef41Sopenharmony_ci return None 21121cb0ef41Sopenharmony_ci 21131cb0ef41Sopenharmony_ci def SenseMap(self, tagged_address): 21141cb0ef41Sopenharmony_ci if self.IsInKnownMapSpace(tagged_address): 21151cb0ef41Sopenharmony_ci offset = self.GetPageOffset(tagged_address) 21161cb0ef41Sopenharmony_ci lookup_key = ("MAP_SPACE", offset) 21171cb0ef41Sopenharmony_ci known_map_info = KNOWN_MAPS.get(lookup_key) 21181cb0ef41Sopenharmony_ci if known_map_info: 21191cb0ef41Sopenharmony_ci known_map_type, known_map_name = known_map_info 21201cb0ef41Sopenharmony_ci return KnownMap(self, known_map_name, known_map_type) 21211cb0ef41Sopenharmony_ci found_map = self.heap.FindMap(tagged_address) 21221cb0ef41Sopenharmony_ci if found_map: return found_map 21231cb0ef41Sopenharmony_ci return None 21241cb0ef41Sopenharmony_ci 21251cb0ef41Sopenharmony_ci def FindObjectOrSmi(self, tagged_address): 21261cb0ef41Sopenharmony_ci """When used as a mixin in place of V8Heap.""" 21271cb0ef41Sopenharmony_ci found_obj = self.SenseObject(tagged_address) 21281cb0ef41Sopenharmony_ci if found_obj: return found_obj 21291cb0ef41Sopenharmony_ci if self.IsSmi(tagged_address): 21301cb0ef41Sopenharmony_ci return self.FormatSmi(tagged_address) 21311cb0ef41Sopenharmony_ci else: 21321cb0ef41Sopenharmony_ci return "Unknown(%s)" % self.reader.FormatIntPtr(tagged_address) 21331cb0ef41Sopenharmony_ci 21341cb0ef41Sopenharmony_ci def FindObject(self, tagged_address): 21351cb0ef41Sopenharmony_ci """When used as a mixin in place of V8Heap.""" 21361cb0ef41Sopenharmony_ci raise NotImplementedError 21371cb0ef41Sopenharmony_ci 21381cb0ef41Sopenharmony_ci def FindMap(self, tagged_address): 21391cb0ef41Sopenharmony_ci """When used as a mixin in place of V8Heap.""" 21401cb0ef41Sopenharmony_ci raise NotImplementedError 21411cb0ef41Sopenharmony_ci 21421cb0ef41Sopenharmony_ci def PrintKnowledge(self): 21431cb0ef41Sopenharmony_ci print(" known_first_map_page = %s\n"\ 21441cb0ef41Sopenharmony_ci " known_first_old_page = %s" % ( 21451cb0ef41Sopenharmony_ci self.reader.FormatIntPtr(self.known_first_map_page), 21461cb0ef41Sopenharmony_ci self.reader.FormatIntPtr(self.known_first_old_page))) 21471cb0ef41Sopenharmony_ci 21481cb0ef41Sopenharmony_ci def FindFirstAsciiString(self, start, end=None, min_length=32): 21491cb0ef41Sopenharmony_ci """ Walk the memory until we find a large string """ 21501cb0ef41Sopenharmony_ci if not end: end = start + 64 21511cb0ef41Sopenharmony_ci for slot in range(start, end): 21521cb0ef41Sopenharmony_ci if not self.reader.IsValidAddress(slot): break 21531cb0ef41Sopenharmony_ci message = self.reader.ReadAsciiString(slot) 21541cb0ef41Sopenharmony_ci if len(message) > min_length: 21551cb0ef41Sopenharmony_ci return (slot, message) 21561cb0ef41Sopenharmony_ci return (None,None) 21571cb0ef41Sopenharmony_ci 21581cb0ef41Sopenharmony_ci def PrintStackTraceMessage(self, start=None, print_message=True): 21591cb0ef41Sopenharmony_ci """ 21601cb0ef41Sopenharmony_ci Try to print a possible message from PushStackTraceAndDie. 21611cb0ef41Sopenharmony_ci Returns the first address where the normal stack starts again. 21621cb0ef41Sopenharmony_ci """ 21631cb0ef41Sopenharmony_ci # Only look at the first 1k words on the stack 21641cb0ef41Sopenharmony_ci ptr_size = self.reader.MachinePointerSize() 21651cb0ef41Sopenharmony_ci if start is None: start = self.reader.ExceptionSP() 21661cb0ef41Sopenharmony_ci if not self.reader.IsValidAddress(start): return start 21671cb0ef41Sopenharmony_ci end = start + ptr_size * 1024 * 4 21681cb0ef41Sopenharmony_ci magic1 = None 21691cb0ef41Sopenharmony_ci for slot in range(start, end, ptr_size): 21701cb0ef41Sopenharmony_ci if not self.reader.IsValidAddress(slot + ptr_size): break 21711cb0ef41Sopenharmony_ci magic1 = self.reader.ReadUIntPtr(slot) 21721cb0ef41Sopenharmony_ci magic2 = self.reader.ReadUIntPtr(slot + ptr_size) 21731cb0ef41Sopenharmony_ci pair = (magic1 & 0xFFFFFFFF, magic2 & 0xFFFFFFFF) 21741cb0ef41Sopenharmony_ci if pair in MAGIC_MARKER_PAIRS: 21751cb0ef41Sopenharmony_ci return self.TryExtractOldStyleStackTrace(slot, start, end, 21761cb0ef41Sopenharmony_ci print_message) 21771cb0ef41Sopenharmony_ci if pair[0] == STACK_TRACE_MARKER: 21781cb0ef41Sopenharmony_ci return self.TryExtractStackTrace(slot, start, end, print_message) 21791cb0ef41Sopenharmony_ci elif pair[0] == ERROR_MESSAGE_MARKER: 21801cb0ef41Sopenharmony_ci return self.TryExtractErrorMessage(slot, start, end, print_message) 21811cb0ef41Sopenharmony_ci # Simple fallback in case not stack trace object was found 21821cb0ef41Sopenharmony_ci return self.TryExtractOldStyleStackTrace(0, start, end, 21831cb0ef41Sopenharmony_ci print_message) 21841cb0ef41Sopenharmony_ci 21851cb0ef41Sopenharmony_ci def TryExtractStackTrace(self, slot, start, end, print_message): 21861cb0ef41Sopenharmony_ci ptr_size = self.reader.MachinePointerSize() 21871cb0ef41Sopenharmony_ci assert self.reader.ReadUIntPtr(slot) & 0xFFFFFFFF == STACK_TRACE_MARKER 21881cb0ef41Sopenharmony_ci end_marker = STACK_TRACE_MARKER + 1; 21891cb0ef41Sopenharmony_ci header_size = 10 21901cb0ef41Sopenharmony_ci # Look for the end marker after the fields and the message buffer. 21911cb0ef41Sopenharmony_ci end_search = start + (32 * 1024) + (header_size * ptr_size); 21921cb0ef41Sopenharmony_ci end_slot = self.FindPtr(end_marker, end_search, end_search + ptr_size * 512) 21931cb0ef41Sopenharmony_ci if not end_slot: return start 21941cb0ef41Sopenharmony_ci print("Stack Message (start=%s):" % self.heap.FormatIntPtr(slot)) 21951cb0ef41Sopenharmony_ci slot += ptr_size 21961cb0ef41Sopenharmony_ci for name in ("isolate","ptr1", "ptr2", "ptr3", "ptr4", "codeObject1", 21971cb0ef41Sopenharmony_ci "codeObject2", "codeObject3", "codeObject4"): 21981cb0ef41Sopenharmony_ci value = self.reader.ReadUIntPtr(slot) 21991cb0ef41Sopenharmony_ci print(" %s: %s" % (name.rjust(14), self.heap.FormatIntPtr(value))) 22001cb0ef41Sopenharmony_ci slot += ptr_size 22011cb0ef41Sopenharmony_ci print(" message start: %s" % self.heap.FormatIntPtr(slot)) 22021cb0ef41Sopenharmony_ci stack_start = end_slot + ptr_size 22031cb0ef41Sopenharmony_ci print(" stack_start: %s" % self.heap.FormatIntPtr(stack_start)) 22041cb0ef41Sopenharmony_ci (message_start, message) = self.FindFirstAsciiString(slot) 22051cb0ef41Sopenharmony_ci self.FormatStackTrace(message, print_message) 22061cb0ef41Sopenharmony_ci return stack_start 22071cb0ef41Sopenharmony_ci 22081cb0ef41Sopenharmony_ci def FindPtr(self, expected_value, start, end): 22091cb0ef41Sopenharmony_ci ptr_size = self.reader.MachinePointerSize() 22101cb0ef41Sopenharmony_ci for slot in range(start, end, ptr_size): 22111cb0ef41Sopenharmony_ci if not self.reader.IsValidAddress(slot): return None 22121cb0ef41Sopenharmony_ci value = self.reader.ReadUIntPtr(slot) 22131cb0ef41Sopenharmony_ci if value == expected_value: return slot 22141cb0ef41Sopenharmony_ci return None 22151cb0ef41Sopenharmony_ci 22161cb0ef41Sopenharmony_ci def TryExtractErrorMessage(self, slot, start, end, print_message): 22171cb0ef41Sopenharmony_ci ptr_size = self.reader.MachinePointerSize() 22181cb0ef41Sopenharmony_ci end_marker = ERROR_MESSAGE_MARKER + 1; 22191cb0ef41Sopenharmony_ci header_size = 1 22201cb0ef41Sopenharmony_ci end_search = start + 1024 + (header_size * ptr_size); 22211cb0ef41Sopenharmony_ci end_slot = self.FindPtr(end_marker, end_search, end_search + ptr_size * 512) 22221cb0ef41Sopenharmony_ci if not end_slot: return start 22231cb0ef41Sopenharmony_ci print("Error Message (start=%s):" % self.heap.FormatIntPtr(slot)) 22241cb0ef41Sopenharmony_ci slot += ptr_size 22251cb0ef41Sopenharmony_ci (message_start, message) = self.FindFirstAsciiString(slot) 22261cb0ef41Sopenharmony_ci self.FormatStackTrace(message, print_message) 22271cb0ef41Sopenharmony_ci stack_start = end_slot + ptr_size 22281cb0ef41Sopenharmony_ci return stack_start 22291cb0ef41Sopenharmony_ci 22301cb0ef41Sopenharmony_ci def TryExtractOldStyleStackTrace(self, message_slot, start, end, 22311cb0ef41Sopenharmony_ci print_message): 22321cb0ef41Sopenharmony_ci ptr_size = self.reader.MachinePointerSize() 22331cb0ef41Sopenharmony_ci if message_slot == 0: 22341cb0ef41Sopenharmony_ci """ 22351cb0ef41Sopenharmony_ci On Mac we don't always get proper magic markers, so just try printing 22361cb0ef41Sopenharmony_ci the first long ascii string found on the stack. 22371cb0ef41Sopenharmony_ci """ 22381cb0ef41Sopenharmony_ci magic1 = None 22391cb0ef41Sopenharmony_ci magic2 = None 22401cb0ef41Sopenharmony_ci message_start, message = self.FindFirstAsciiString(start, end, 128) 22411cb0ef41Sopenharmony_ci if message_start is None: return start 22421cb0ef41Sopenharmony_ci else: 22431cb0ef41Sopenharmony_ci message_start = self.reader.ReadUIntPtr(message_slot + ptr_size * 4) 22441cb0ef41Sopenharmony_ci message = self.reader.ReadAsciiString(message_start) 22451cb0ef41Sopenharmony_ci stack_start = message_start + len(message) + 1 22461cb0ef41Sopenharmony_ci # Make sure the address is word aligned 22471cb0ef41Sopenharmony_ci stack_start = stack_start - (stack_start % ptr_size) 22481cb0ef41Sopenharmony_ci if magic1 is None: 22491cb0ef41Sopenharmony_ci print("Stack Message:") 22501cb0ef41Sopenharmony_ci print(" message start: %s" % self.heap.FormatIntPtr(message_start)) 22511cb0ef41Sopenharmony_ci print(" stack_start: %s" % self.heap.FormatIntPtr(stack_start )) 22521cb0ef41Sopenharmony_ci else: 22531cb0ef41Sopenharmony_ci ptr1 = self.reader.ReadUIntPtr(slot + ptr_size * 2) 22541cb0ef41Sopenharmony_ci ptr2 = self.reader.ReadUIntPtr(slot + ptr_size * 3) 22551cb0ef41Sopenharmony_ci print("Stack Message:") 22561cb0ef41Sopenharmony_ci print(" magic1: %s" % self.heap.FormatIntPtr(magic1)) 22571cb0ef41Sopenharmony_ci print(" magic2: %s" % self.heap.FormatIntPtr(magic2)) 22581cb0ef41Sopenharmony_ci print(" ptr1: %s" % self.heap.FormatIntPtr(ptr1)) 22591cb0ef41Sopenharmony_ci print(" ptr2: %s" % self.heap.FormatIntPtr(ptr2)) 22601cb0ef41Sopenharmony_ci print(" message start: %s" % self.heap.FormatIntPtr(message_start)) 22611cb0ef41Sopenharmony_ci print(" stack_start: %s" % self.heap.FormatIntPtr(stack_start )) 22621cb0ef41Sopenharmony_ci print("") 22631cb0ef41Sopenharmony_ci self.FormatStackTrace(message, print_message) 22641cb0ef41Sopenharmony_ci return stack_start 22651cb0ef41Sopenharmony_ci 22661cb0ef41Sopenharmony_ci def FormatStackTrace(self, message, print_message): 22671cb0ef41Sopenharmony_ci if not print_message: 22681cb0ef41Sopenharmony_ci print(" Use `dsa` to print the message with annotated addresses.") 22691cb0ef41Sopenharmony_ci print("") 22701cb0ef41Sopenharmony_ci return 22711cb0ef41Sopenharmony_ci ptr_size = self.reader.MachinePointerSize() 22721cb0ef41Sopenharmony_ci # Annotate all addresses in the dumped message 22731cb0ef41Sopenharmony_ci prog = re.compile("[0-9a-fA-F]{%s}" % ptr_size*2) 22741cb0ef41Sopenharmony_ci addresses = list(set(prog.findall(message))) 22751cb0ef41Sopenharmony_ci for i in range(len(addresses)): 22761cb0ef41Sopenharmony_ci address_org = addresses[i] 22771cb0ef41Sopenharmony_ci address = self.heap.FormatIntPtr(int(address_org, 16)) 22781cb0ef41Sopenharmony_ci if address_org != address: 22791cb0ef41Sopenharmony_ci message = message.replace(address_org, address) 22801cb0ef41Sopenharmony_ci print("Message:") 22811cb0ef41Sopenharmony_ci print("="*80) 22821cb0ef41Sopenharmony_ci print(message) 22831cb0ef41Sopenharmony_ci print("="*80) 22841cb0ef41Sopenharmony_ci print("") 22851cb0ef41Sopenharmony_ci 22861cb0ef41Sopenharmony_ci 22871cb0ef41Sopenharmony_ci def TryInferFramePointer(self, slot, address): 22881cb0ef41Sopenharmony_ci """ Assume we have a framepointer if we find 4 consecutive links """ 22891cb0ef41Sopenharmony_ci for i in range(0, 4): 22901cb0ef41Sopenharmony_ci if not self.reader.IsExceptionStackAddress(address): return 0 22911cb0ef41Sopenharmony_ci next_address = self.reader.ReadUIntPtr(address) 22921cb0ef41Sopenharmony_ci if next_address == address: return 0 22931cb0ef41Sopenharmony_ci address = next_address 22941cb0ef41Sopenharmony_ci return slot 22951cb0ef41Sopenharmony_ci 22961cb0ef41Sopenharmony_ci def TryInferContext(self, address): 22971cb0ef41Sopenharmony_ci if self.context: return 22981cb0ef41Sopenharmony_ci ptr_size = self.reader.MachinePointerSize() 22991cb0ef41Sopenharmony_ci possible_context = dict() 23001cb0ef41Sopenharmony_ci count = 0 23011cb0ef41Sopenharmony_ci while self.reader.IsExceptionStackAddress(address): 23021cb0ef41Sopenharmony_ci prev_addr = self.reader.ReadUIntPtr(address-ptr_size) 23031cb0ef41Sopenharmony_ci if self.heap.IsTaggedObjectAddress(prev_addr): 23041cb0ef41Sopenharmony_ci if prev_addr in possible_context: 23051cb0ef41Sopenharmony_ci possible_context[prev_addr] += 1 23061cb0ef41Sopenharmony_ci else: 23071cb0ef41Sopenharmony_ci possible_context[prev_addr] = 1 23081cb0ef41Sopenharmony_ci address = self.reader.ReadUIntPtr(address) 23091cb0ef41Sopenharmony_ci count += 1 23101cb0ef41Sopenharmony_ci if count <= 5 or len(possible_context) == 0: return 23111cb0ef41Sopenharmony_ci # Find entry with highest count 23121cb0ef41Sopenharmony_ci possible_context = list(possible_context.items()) 23131cb0ef41Sopenharmony_ci possible_context.sort(key=lambda pair: pair[1]) 23141cb0ef41Sopenharmony_ci address,count = possible_context[-1] 23151cb0ef41Sopenharmony_ci if count <= 4: return 23161cb0ef41Sopenharmony_ci self.context = address 23171cb0ef41Sopenharmony_ci 23181cb0ef41Sopenharmony_ci def InterpretMemory(self, start, end): 23191cb0ef41Sopenharmony_ci # On 64 bit we omit frame pointers, so we have to do some more guesswork. 23201cb0ef41Sopenharmony_ci frame_pointer = 0 23211cb0ef41Sopenharmony_ci if not self.reader.Is64(): 23221cb0ef41Sopenharmony_ci frame_pointer = self.reader.ExceptionFP() 23231cb0ef41Sopenharmony_ci # Follow the framepointer into the address range 23241cb0ef41Sopenharmony_ci while frame_pointer and frame_pointer < start: 23251cb0ef41Sopenharmony_ci frame_pointer = self.reader.ReadUIntPtr(frame_pointer) 23261cb0ef41Sopenharmony_ci if not self.reader.IsExceptionStackAddress(frame_pointer) or \ 23271cb0ef41Sopenharmony_ci not frame_pointer: 23281cb0ef41Sopenharmony_ci frame_pointer = 0 23291cb0ef41Sopenharmony_ci break 23301cb0ef41Sopenharmony_ci in_oom_dump_area = False 23311cb0ef41Sopenharmony_ci is_stack = self.reader.IsExceptionStackAddress(start) 23321cb0ef41Sopenharmony_ci free_space_end = 0 23331cb0ef41Sopenharmony_ci ptr_size = self.reader.TaggedPointerSize() 23341cb0ef41Sopenharmony_ci 23351cb0ef41Sopenharmony_ci for slot in range(start, end, ptr_size): 23361cb0ef41Sopenharmony_ci if not self.reader.IsValidAddress(slot): 23371cb0ef41Sopenharmony_ci print("%s: Address is not contained within the minidump!" % slot) 23381cb0ef41Sopenharmony_ci return 23391cb0ef41Sopenharmony_ci maybe_address = self.reader.ReadUIntPtr(slot) 23401cb0ef41Sopenharmony_ci address_info = [] 23411cb0ef41Sopenharmony_ci # Mark continuous free space objects 23421cb0ef41Sopenharmony_ci if slot == free_space_end: 23431cb0ef41Sopenharmony_ci address_info.append("+") 23441cb0ef41Sopenharmony_ci elif slot <= free_space_end: 23451cb0ef41Sopenharmony_ci address_info.append("|") 23461cb0ef41Sopenharmony_ci else: 23471cb0ef41Sopenharmony_ci free_space_end = 0 23481cb0ef41Sopenharmony_ci 23491cb0ef41Sopenharmony_ci heap_object = self.SenseObject(maybe_address, slot) 23501cb0ef41Sopenharmony_ci if heap_object: 23511cb0ef41Sopenharmony_ci # Detect Free-space ranges 23521cb0ef41Sopenharmony_ci if isinstance(heap_object, KnownMap) and \ 23531cb0ef41Sopenharmony_ci heap_object.known_name == "FreeSpaceMap": 23541cb0ef41Sopenharmony_ci # The free-space length is is stored as a Smi in the next slot. 23551cb0ef41Sopenharmony_ci length = self.reader.ReadTagged(slot + ptr_size) 23561cb0ef41Sopenharmony_ci if self.heap.IsSmi(length): 23571cb0ef41Sopenharmony_ci length = self.heap.SmiUntag(length) 23581cb0ef41Sopenharmony_ci free_space_end = slot + length - ptr_size 23591cb0ef41Sopenharmony_ci address_info.append(str(heap_object)) 23601cb0ef41Sopenharmony_ci relative_offset = self.heap.RelativeOffset(slot, maybe_address) 23611cb0ef41Sopenharmony_ci if relative_offset: 23621cb0ef41Sopenharmony_ci address_info.append(relative_offset) 23631cb0ef41Sopenharmony_ci if maybe_address == self.context: 23641cb0ef41Sopenharmony_ci address_info.append("CONTEXT") 23651cb0ef41Sopenharmony_ci 23661cb0ef41Sopenharmony_ci maybe_address_contents = None 23671cb0ef41Sopenharmony_ci if is_stack: 23681cb0ef41Sopenharmony_ci if self.reader.IsExceptionStackAddress(maybe_address): 23691cb0ef41Sopenharmony_ci maybe_address_contents = \ 23701cb0ef41Sopenharmony_ci self.reader.ReadUIntPtr(maybe_address) & 0xFFFFFFFF 23711cb0ef41Sopenharmony_ci if maybe_address_contents == 0xdecade00: 23721cb0ef41Sopenharmony_ci in_oom_dump_area = True 23731cb0ef41Sopenharmony_ci if frame_pointer == 0: 23741cb0ef41Sopenharmony_ci frame_pointer = self.TryInferFramePointer(slot, maybe_address) 23751cb0ef41Sopenharmony_ci if frame_pointer != 0: 23761cb0ef41Sopenharmony_ci self.TryInferContext(slot) 23771cb0ef41Sopenharmony_ci maybe_symbol = self.reader.FindSymbol(maybe_address) 23781cb0ef41Sopenharmony_ci if in_oom_dump_area: 23791cb0ef41Sopenharmony_ci if maybe_address_contents == 0xdecade00: 23801cb0ef41Sopenharmony_ci address_info = ["<==== HeapStats start marker"] 23811cb0ef41Sopenharmony_ci elif maybe_address_contents == 0xdecade01: 23821cb0ef41Sopenharmony_ci address_info = ["<==== HeapStats end marker"] 23831cb0ef41Sopenharmony_ci elif maybe_address_contents is not None: 23841cb0ef41Sopenharmony_ci address_info = [" %d (%d Mbytes)" % (maybe_address_contents, 23851cb0ef41Sopenharmony_ci maybe_address_contents >> 20)] 23861cb0ef41Sopenharmony_ci if slot == frame_pointer: 23871cb0ef41Sopenharmony_ci if not self.reader.IsExceptionStackAddress(maybe_address): 23881cb0ef41Sopenharmony_ci address_info.append("<==== BAD frame pointer") 23891cb0ef41Sopenharmony_ci frame_pointer = 0 23901cb0ef41Sopenharmony_ci else: 23911cb0ef41Sopenharmony_ci address_info.append("<==== Frame pointer") 23921cb0ef41Sopenharmony_ci frame_pointer = maybe_address 23931cb0ef41Sopenharmony_ci address_type_marker = self.heap.AddressTypeMarker(maybe_address) 23941cb0ef41Sopenharmony_ci string_value = self.reader.ReadAsciiPtr(slot) 23951cb0ef41Sopenharmony_ci print("%s: %s %s %s %s" % (self.reader.FormatIntPtr(slot), 23961cb0ef41Sopenharmony_ci self.reader.FormatIntPtr(maybe_address), 23971cb0ef41Sopenharmony_ci address_type_marker, 23981cb0ef41Sopenharmony_ci string_value, 23991cb0ef41Sopenharmony_ci ' | '.join(address_info))) 24001cb0ef41Sopenharmony_ci if maybe_address_contents == 0xdecade01: 24011cb0ef41Sopenharmony_ci in_oom_dump_area = False 24021cb0ef41Sopenharmony_ci heap_object = self.heap.FindObject(maybe_address) 24031cb0ef41Sopenharmony_ci if heap_object: 24041cb0ef41Sopenharmony_ci heap_object.Print(Printer()) 24051cb0ef41Sopenharmony_ci print("") 24061cb0ef41Sopenharmony_ci 24071cb0ef41Sopenharmony_ciWEB_HEADER = """ 24081cb0ef41Sopenharmony_ci<!DOCTYPE html> 24091cb0ef41Sopenharmony_ci<html> 24101cb0ef41Sopenharmony_ci<head> 24111cb0ef41Sopenharmony_ci<meta content="text/html; charset=utf-8" http-equiv="content-type"> 24121cb0ef41Sopenharmony_ci<style media="screen" type="text/css"> 24131cb0ef41Sopenharmony_ci 24141cb0ef41Sopenharmony_ci.code { 24151cb0ef41Sopenharmony_ci font-family: monospace; 24161cb0ef41Sopenharmony_ci} 24171cb0ef41Sopenharmony_ci 24181cb0ef41Sopenharmony_ci.dmptable { 24191cb0ef41Sopenharmony_ci border-collapse : collapse; 24201cb0ef41Sopenharmony_ci border-spacing : 0px; 24211cb0ef41Sopenharmony_ci table-layout: fixed; 24221cb0ef41Sopenharmony_ci} 24231cb0ef41Sopenharmony_ci 24241cb0ef41Sopenharmony_ci.codedump { 24251cb0ef41Sopenharmony_ci border-collapse : collapse; 24261cb0ef41Sopenharmony_ci border-spacing : 0px; 24271cb0ef41Sopenharmony_ci table-layout: fixed; 24281cb0ef41Sopenharmony_ci} 24291cb0ef41Sopenharmony_ci 24301cb0ef41Sopenharmony_ci.addrcomments { 24311cb0ef41Sopenharmony_ci border : 0px; 24321cb0ef41Sopenharmony_ci} 24331cb0ef41Sopenharmony_ci 24341cb0ef41Sopenharmony_ci.register { 24351cb0ef41Sopenharmony_ci padding-right : 1em; 24361cb0ef41Sopenharmony_ci} 24371cb0ef41Sopenharmony_ci 24381cb0ef41Sopenharmony_ci.header { 24391cb0ef41Sopenharmony_ci clear : both; 24401cb0ef41Sopenharmony_ci} 24411cb0ef41Sopenharmony_ci 24421cb0ef41Sopenharmony_ci.header .navigation { 24431cb0ef41Sopenharmony_ci float : left; 24441cb0ef41Sopenharmony_ci} 24451cb0ef41Sopenharmony_ci 24461cb0ef41Sopenharmony_ci.header .dumpname { 24471cb0ef41Sopenharmony_ci float : right; 24481cb0ef41Sopenharmony_ci} 24491cb0ef41Sopenharmony_ci 24501cb0ef41Sopenharmony_citr.highlight-line { 24511cb0ef41Sopenharmony_ci background-color : yellow; 24521cb0ef41Sopenharmony_ci} 24531cb0ef41Sopenharmony_ci 24541cb0ef41Sopenharmony_ci.highlight { 24551cb0ef41Sopenharmony_ci background-color : magenta; 24561cb0ef41Sopenharmony_ci} 24571cb0ef41Sopenharmony_ci 24581cb0ef41Sopenharmony_citr.inexact-highlight-line { 24591cb0ef41Sopenharmony_ci background-color : pink; 24601cb0ef41Sopenharmony_ci} 24611cb0ef41Sopenharmony_ci 24621cb0ef41Sopenharmony_ciinput { 24631cb0ef41Sopenharmony_ci background-color: inherit; 24641cb0ef41Sopenharmony_ci border: 1px solid LightGray; 24651cb0ef41Sopenharmony_ci} 24661cb0ef41Sopenharmony_ci 24671cb0ef41Sopenharmony_ci.dumpcomments { 24681cb0ef41Sopenharmony_ci border : 1px solid LightGray; 24691cb0ef41Sopenharmony_ci width : 32em; 24701cb0ef41Sopenharmony_ci} 24711cb0ef41Sopenharmony_ci 24721cb0ef41Sopenharmony_ci.regions td { 24731cb0ef41Sopenharmony_ci padding:0 15px 0 15px; 24741cb0ef41Sopenharmony_ci} 24751cb0ef41Sopenharmony_ci 24761cb0ef41Sopenharmony_ci.stackframe td { 24771cb0ef41Sopenharmony_ci background-color : cyan; 24781cb0ef41Sopenharmony_ci} 24791cb0ef41Sopenharmony_ci 24801cb0ef41Sopenharmony_ci.stackaddress, .sa { 24811cb0ef41Sopenharmony_ci background-color : LightGray; 24821cb0ef41Sopenharmony_ci} 24831cb0ef41Sopenharmony_ci 24841cb0ef41Sopenharmony_ci.stackval, .sv { 24851cb0ef41Sopenharmony_ci background-color : LightCyan; 24861cb0ef41Sopenharmony_ci} 24871cb0ef41Sopenharmony_ci 24881cb0ef41Sopenharmony_ci.frame { 24891cb0ef41Sopenharmony_ci background-color : cyan; 24901cb0ef41Sopenharmony_ci} 24911cb0ef41Sopenharmony_ci 24921cb0ef41Sopenharmony_ci.commentinput, .ci { 24931cb0ef41Sopenharmony_ci width : 20em; 24941cb0ef41Sopenharmony_ci} 24951cb0ef41Sopenharmony_ci 24961cb0ef41Sopenharmony_ci/* a.nodump */ 24971cb0ef41Sopenharmony_cia.nd:visited { 24981cb0ef41Sopenharmony_ci color : black; 24991cb0ef41Sopenharmony_ci text-decoration : none; 25001cb0ef41Sopenharmony_ci} 25011cb0ef41Sopenharmony_ci 25021cb0ef41Sopenharmony_cia.nd:link { 25031cb0ef41Sopenharmony_ci color : black; 25041cb0ef41Sopenharmony_ci text-decoration : none; 25051cb0ef41Sopenharmony_ci} 25061cb0ef41Sopenharmony_ci 25071cb0ef41Sopenharmony_cia:visited { 25081cb0ef41Sopenharmony_ci color : blueviolet; 25091cb0ef41Sopenharmony_ci} 25101cb0ef41Sopenharmony_ci 25111cb0ef41Sopenharmony_cia:link { 25121cb0ef41Sopenharmony_ci color : blue; 25131cb0ef41Sopenharmony_ci} 25141cb0ef41Sopenharmony_ci 25151cb0ef41Sopenharmony_ci.disasmcomment { 25161cb0ef41Sopenharmony_ci color : DarkGreen; 25171cb0ef41Sopenharmony_ci} 25181cb0ef41Sopenharmony_ci 25191cb0ef41Sopenharmony_ci</style> 25201cb0ef41Sopenharmony_ci 25211cb0ef41Sopenharmony_ci<script type="application/javascript"> 25221cb0ef41Sopenharmony_ci 25231cb0ef41Sopenharmony_civar address_str = "address-"; 25241cb0ef41Sopenharmony_civar address_len = address_str.length; 25251cb0ef41Sopenharmony_ci 25261cb0ef41Sopenharmony_cifunction comment() { 25271cb0ef41Sopenharmony_ci var s = event.srcElement.id; 25281cb0ef41Sopenharmony_ci var index = s.indexOf(address_str); 25291cb0ef41Sopenharmony_ci if (index >= 0) { 25301cb0ef41Sopenharmony_ci send_comment(s.substring(index + address_len), event.srcElement.value); 25311cb0ef41Sopenharmony_ci } 25321cb0ef41Sopenharmony_ci} 25331cb0ef41Sopenharmony_civar c = comment; 25341cb0ef41Sopenharmony_ci 25351cb0ef41Sopenharmony_cifunction send_comment(address, comment) { 25361cb0ef41Sopenharmony_ci xmlhttp = new XMLHttpRequest(); 25371cb0ef41Sopenharmony_ci address = encodeURIComponent(address) 25381cb0ef41Sopenharmony_ci comment = encodeURIComponent(comment) 25391cb0ef41Sopenharmony_ci xmlhttp.open("GET", 25401cb0ef41Sopenharmony_ci "setcomment?%(query_dump)s&address=" + address + 25411cb0ef41Sopenharmony_ci "&comment=" + comment, true); 25421cb0ef41Sopenharmony_ci xmlhttp.send(); 25431cb0ef41Sopenharmony_ci} 25441cb0ef41Sopenharmony_ci 25451cb0ef41Sopenharmony_civar dump_str = "dump-"; 25461cb0ef41Sopenharmony_civar dump_len = dump_str.length; 25471cb0ef41Sopenharmony_ci 25481cb0ef41Sopenharmony_cifunction dump_comment() { 25491cb0ef41Sopenharmony_ci var s = event.srcElement.id; 25501cb0ef41Sopenharmony_ci var index = s.indexOf(dump_str); 25511cb0ef41Sopenharmony_ci if (index >= 0) { 25521cb0ef41Sopenharmony_ci send_dump_desc(s.substring(index + dump_len), event.srcElement.value); 25531cb0ef41Sopenharmony_ci } 25541cb0ef41Sopenharmony_ci} 25551cb0ef41Sopenharmony_ci 25561cb0ef41Sopenharmony_cifunction send_dump_desc(name, desc) { 25571cb0ef41Sopenharmony_ci xmlhttp = new XMLHttpRequest(); 25581cb0ef41Sopenharmony_ci name = encodeURIComponent(name) 25591cb0ef41Sopenharmony_ci desc = encodeURIComponent(desc) 25601cb0ef41Sopenharmony_ci xmlhttp.open("GET", 25611cb0ef41Sopenharmony_ci "setdumpdesc?dump=" + name + 25621cb0ef41Sopenharmony_ci "&description=" + desc, true); 25631cb0ef41Sopenharmony_ci xmlhttp.send(); 25641cb0ef41Sopenharmony_ci} 25651cb0ef41Sopenharmony_ci 25661cb0ef41Sopenharmony_cifunction onpage(kind, address) { 25671cb0ef41Sopenharmony_ci xmlhttp = new XMLHttpRequest(); 25681cb0ef41Sopenharmony_ci kind = encodeURIComponent(kind) 25691cb0ef41Sopenharmony_ci address = encodeURIComponent(address) 25701cb0ef41Sopenharmony_ci xmlhttp.onreadystatechange = function() { 25711cb0ef41Sopenharmony_ci if (xmlhttp.readyState==4 && xmlhttp.status==200) { 25721cb0ef41Sopenharmony_ci location.reload(true) 25731cb0ef41Sopenharmony_ci } 25741cb0ef41Sopenharmony_ci }; 25751cb0ef41Sopenharmony_ci xmlhttp.open("GET", 25761cb0ef41Sopenharmony_ci "setpageaddress?%(query_dump)s&kind=" + kind + 25771cb0ef41Sopenharmony_ci "&address=" + address); 25781cb0ef41Sopenharmony_ci xmlhttp.send(); 25791cb0ef41Sopenharmony_ci} 25801cb0ef41Sopenharmony_ci 25811cb0ef41Sopenharmony_ci</script> 25821cb0ef41Sopenharmony_ci 25831cb0ef41Sopenharmony_ci<title>Dump %(dump_name)s</title> 25841cb0ef41Sopenharmony_ci</head> 25851cb0ef41Sopenharmony_ci 25861cb0ef41Sopenharmony_ci<body> 25871cb0ef41Sopenharmony_ci <div class="header"> 25881cb0ef41Sopenharmony_ci <form class="navigation" action="search.html"> 25891cb0ef41Sopenharmony_ci <a href="summary.html?%(query_dump)s">Context info</a> 25901cb0ef41Sopenharmony_ci <a href="info.html?%(query_dump)s">Dump info</a> 25911cb0ef41Sopenharmony_ci <a href="modules.html?%(query_dump)s">Modules</a> 25921cb0ef41Sopenharmony_ci 25931cb0ef41Sopenharmony_ci <input type="search" name="val"> 25941cb0ef41Sopenharmony_ci <input type="submit" name="search" value="Search"> 25951cb0ef41Sopenharmony_ci <input type="hidden" name="dump" value="%(dump_name)s"> 25961cb0ef41Sopenharmony_ci </form> 25971cb0ef41Sopenharmony_ci <form class="navigation" action="disasm.html#highlight"> 25981cb0ef41Sopenharmony_ci 25991cb0ef41Sopenharmony_ci 26001cb0ef41Sopenharmony_ci 26011cb0ef41Sopenharmony_ci <input type="search" name="val"> 26021cb0ef41Sopenharmony_ci <input type="submit" name="disasm" value="Disasm"> 26031cb0ef41Sopenharmony_ci 26041cb0ef41Sopenharmony_ci 26051cb0ef41Sopenharmony_ci 26061cb0ef41Sopenharmony_ci <a href="dumps.html">Dumps...</a> 26071cb0ef41Sopenharmony_ci </form> 26081cb0ef41Sopenharmony_ci </div> 26091cb0ef41Sopenharmony_ci <br> 26101cb0ef41Sopenharmony_ci <hr> 26111cb0ef41Sopenharmony_ci""" 26121cb0ef41Sopenharmony_ci 26131cb0ef41Sopenharmony_ci 26141cb0ef41Sopenharmony_ciWEB_FOOTER = """ 26151cb0ef41Sopenharmony_ci</body> 26161cb0ef41Sopenharmony_ci</html> 26171cb0ef41Sopenharmony_ci""" 26181cb0ef41Sopenharmony_ci 26191cb0ef41Sopenharmony_ci 26201cb0ef41Sopenharmony_ciclass WebParameterError(Exception): 26211cb0ef41Sopenharmony_ci pass 26221cb0ef41Sopenharmony_ci 26231cb0ef41Sopenharmony_ci 26241cb0ef41Sopenharmony_ciclass InspectionWebHandler(http_server.BaseHTTPRequestHandler): 26251cb0ef41Sopenharmony_ci 26261cb0ef41Sopenharmony_ci def formatter(self, query_components): 26271cb0ef41Sopenharmony_ci name = query_components.get("dump", [None])[0] 26281cb0ef41Sopenharmony_ci return self.server.get_dump_formatter(name) 26291cb0ef41Sopenharmony_ci 26301cb0ef41Sopenharmony_ci def send_success_html_headers(self): 26311cb0ef41Sopenharmony_ci self.send_response(200) 26321cb0ef41Sopenharmony_ci self.send_header("Cache-Control", "no-cache, no-store, must-revalidate") 26331cb0ef41Sopenharmony_ci self.send_header("Pragma", "no-cache") 26341cb0ef41Sopenharmony_ci self.send_header("Expires", "0") 26351cb0ef41Sopenharmony_ci self.send_header('Content-type','text/html') 26361cb0ef41Sopenharmony_ci self.end_headers() 26371cb0ef41Sopenharmony_ci return 26381cb0ef41Sopenharmony_ci 26391cb0ef41Sopenharmony_ci def write(self, string): 26401cb0ef41Sopenharmony_ci self.wfile.write(string.encode('utf-8')) 26411cb0ef41Sopenharmony_ci 26421cb0ef41Sopenharmony_ci def do_GET(self): 26431cb0ef41Sopenharmony_ci try: 26441cb0ef41Sopenharmony_ci parsedurl = urllib.parse.urlparse(self.path) 26451cb0ef41Sopenharmony_ci query_components = urllib.parse.parse_qs(parsedurl.query) 26461cb0ef41Sopenharmony_ci out_buffer = io.StringIO() 26471cb0ef41Sopenharmony_ci if parsedurl.path == "/dumps.html": 26481cb0ef41Sopenharmony_ci self.send_success_html_headers() 26491cb0ef41Sopenharmony_ci self.server.output_dumps(out_buffer) 26501cb0ef41Sopenharmony_ci self.write(out_buffer.getvalue()) 26511cb0ef41Sopenharmony_ci elif parsedurl.path == "/summary.html": 26521cb0ef41Sopenharmony_ci self.send_success_html_headers() 26531cb0ef41Sopenharmony_ci self.formatter(query_components).output_summary(out_buffer) 26541cb0ef41Sopenharmony_ci self.write(out_buffer.getvalue()) 26551cb0ef41Sopenharmony_ci elif parsedurl.path == "/info.html": 26561cb0ef41Sopenharmony_ci self.send_success_html_headers() 26571cb0ef41Sopenharmony_ci self.formatter(query_components).output_info(out_buffer) 26581cb0ef41Sopenharmony_ci self.write(out_buffer.getvalue()) 26591cb0ef41Sopenharmony_ci elif parsedurl.path == "/modules.html": 26601cb0ef41Sopenharmony_ci self.send_success_html_headers() 26611cb0ef41Sopenharmony_ci self.formatter(query_components).output_modules(out_buffer) 26621cb0ef41Sopenharmony_ci self.write(out_buffer.getvalue()) 26631cb0ef41Sopenharmony_ci elif parsedurl.path == "/search.html" or parsedurl.path == "/s": 26641cb0ef41Sopenharmony_ci address = query_components.get("val", []) 26651cb0ef41Sopenharmony_ci if len(address) != 1: 26661cb0ef41Sopenharmony_ci self.send_error(404, "Invalid params") 26671cb0ef41Sopenharmony_ci return 26681cb0ef41Sopenharmony_ci self.send_success_html_headers() 26691cb0ef41Sopenharmony_ci self.formatter(query_components).output_search_res( 26701cb0ef41Sopenharmony_ci out_buffer, address[0]) 26711cb0ef41Sopenharmony_ci self.write(out_buffer.getvalue()) 26721cb0ef41Sopenharmony_ci elif parsedurl.path == "/disasm.html": 26731cb0ef41Sopenharmony_ci address = query_components.get("val", []) 26741cb0ef41Sopenharmony_ci exact = query_components.get("exact", ["on"]) 26751cb0ef41Sopenharmony_ci if len(address) != 1: 26761cb0ef41Sopenharmony_ci self.send_error(404, "Invalid params") 26771cb0ef41Sopenharmony_ci return 26781cb0ef41Sopenharmony_ci self.send_success_html_headers() 26791cb0ef41Sopenharmony_ci self.formatter(query_components).output_disasm( 26801cb0ef41Sopenharmony_ci out_buffer, address[0], exact[0]) 26811cb0ef41Sopenharmony_ci self.write(out_buffer.getvalue()) 26821cb0ef41Sopenharmony_ci elif parsedurl.path == "/data.html": 26831cb0ef41Sopenharmony_ci address = query_components.get("val", []) 26841cb0ef41Sopenharmony_ci datakind = query_components.get("type", ["address"]) 26851cb0ef41Sopenharmony_ci if len(address) == 1 and len(datakind) == 1: 26861cb0ef41Sopenharmony_ci self.send_success_html_headers() 26871cb0ef41Sopenharmony_ci self.formatter(query_components).output_data( 26881cb0ef41Sopenharmony_ci out_buffer, address[0], datakind[0]) 26891cb0ef41Sopenharmony_ci self.write(out_buffer.getvalue()) 26901cb0ef41Sopenharmony_ci else: 26911cb0ef41Sopenharmony_ci self.send_error(404,'Invalid params') 26921cb0ef41Sopenharmony_ci elif parsedurl.path == "/setdumpdesc": 26931cb0ef41Sopenharmony_ci name = query_components.get("dump", [""]) 26941cb0ef41Sopenharmony_ci description = query_components.get("description", [""]) 26951cb0ef41Sopenharmony_ci if len(name) == 1 and len(description) == 1: 26961cb0ef41Sopenharmony_ci name = name[0] 26971cb0ef41Sopenharmony_ci description = description[0] 26981cb0ef41Sopenharmony_ci if self.server.set_dump_desc(name, description): 26991cb0ef41Sopenharmony_ci self.send_success_html_headers() 27001cb0ef41Sopenharmony_ci self.write("OK") 27011cb0ef41Sopenharmony_ci return 27021cb0ef41Sopenharmony_ci self.send_error(404,'Invalid params') 27031cb0ef41Sopenharmony_ci elif parsedurl.path == "/setcomment": 27041cb0ef41Sopenharmony_ci address = query_components.get("address", []) 27051cb0ef41Sopenharmony_ci comment = query_components.get("comment", [""]) 27061cb0ef41Sopenharmony_ci if len(address) == 1 and len(comment) == 1: 27071cb0ef41Sopenharmony_ci address = address[0] 27081cb0ef41Sopenharmony_ci comment = comment[0] 27091cb0ef41Sopenharmony_ci self.formatter(query_components).set_comment(address, comment) 27101cb0ef41Sopenharmony_ci self.send_success_html_headers() 27111cb0ef41Sopenharmony_ci self.write("OK") 27121cb0ef41Sopenharmony_ci else: 27131cb0ef41Sopenharmony_ci self.send_error(404,'Invalid params') 27141cb0ef41Sopenharmony_ci elif parsedurl.path == "/setpageaddress": 27151cb0ef41Sopenharmony_ci kind = query_components.get("kind", []) 27161cb0ef41Sopenharmony_ci address = query_components.get("address", [""]) 27171cb0ef41Sopenharmony_ci if len(kind) == 1 and len(address) == 1: 27181cb0ef41Sopenharmony_ci kind = kind[0] 27191cb0ef41Sopenharmony_ci address = address[0] 27201cb0ef41Sopenharmony_ci self.formatter(query_components).set_page_address(kind, address) 27211cb0ef41Sopenharmony_ci self.send_success_html_headers() 27221cb0ef41Sopenharmony_ci self.write("OK") 27231cb0ef41Sopenharmony_ci else: 27241cb0ef41Sopenharmony_ci self.send_error(404,'Invalid params') 27251cb0ef41Sopenharmony_ci else: 27261cb0ef41Sopenharmony_ci self.send_error(404,'File Not Found: %s' % self.path) 27271cb0ef41Sopenharmony_ci 27281cb0ef41Sopenharmony_ci except IOError: 27291cb0ef41Sopenharmony_ci self.send_error(404,'File Not Found: %s' % self.path) 27301cb0ef41Sopenharmony_ci 27311cb0ef41Sopenharmony_ci except WebParameterError as e: 27321cb0ef41Sopenharmony_ci self.send_error(404, 'Web parameter error: %s' % e.message) 27331cb0ef41Sopenharmony_ci 27341cb0ef41Sopenharmony_ci 27351cb0ef41Sopenharmony_ciHTML_REG_FORMAT = "<span class=\"register\"><b>%s</b>: %s</span><br/>\n" 27361cb0ef41Sopenharmony_ci 27371cb0ef41Sopenharmony_ci 27381cb0ef41Sopenharmony_ciclass InspectionWebFormatter(object): 27391cb0ef41Sopenharmony_ci CONTEXT_FULL = 0 27401cb0ef41Sopenharmony_ci CONTEXT_SHORT = 1 27411cb0ef41Sopenharmony_ci 27421cb0ef41Sopenharmony_ci def __init__(self, switches, minidump_name, http_server): 27431cb0ef41Sopenharmony_ci self.dumpfilename = os.path.split(minidump_name)[1] 27441cb0ef41Sopenharmony_ci self.encfilename = urllib.parse.urlencode({'dump': self.dumpfilename}) 27451cb0ef41Sopenharmony_ci self.reader = MinidumpReader(switches, minidump_name) 27461cb0ef41Sopenharmony_ci self.server = http_server 27471cb0ef41Sopenharmony_ci 27481cb0ef41Sopenharmony_ci # Set up the heap 27491cb0ef41Sopenharmony_ci exception_thread = self.reader.thread_map[self.reader.exception.thread_id] 27501cb0ef41Sopenharmony_ci stack_top = self.reader.ExceptionSP() 27511cb0ef41Sopenharmony_ci stack_bottom = exception_thread.stack.start + \ 27521cb0ef41Sopenharmony_ci exception_thread.stack.memory.data_size 27531cb0ef41Sopenharmony_ci stack_map = {self.reader.ExceptionIP(): -1} 27541cb0ef41Sopenharmony_ci for slot in range(stack_top, stack_bottom, 27551cb0ef41Sopenharmony_ci self.reader.MachinePointerSize()): 27561cb0ef41Sopenharmony_ci maybe_address = self.reader.ReadUIntPtr(slot) 27571cb0ef41Sopenharmony_ci if not maybe_address in stack_map: 27581cb0ef41Sopenharmony_ci stack_map[maybe_address] = slot 27591cb0ef41Sopenharmony_ci self.heap = V8Heap(self.reader, stack_map) 27601cb0ef41Sopenharmony_ci 27611cb0ef41Sopenharmony_ci self.padawan = InspectionPadawan(self.reader, self.heap) 27621cb0ef41Sopenharmony_ci self.comments = InspectionInfo(minidump_name, self.reader) 27631cb0ef41Sopenharmony_ci self.padawan.known_first_old_page = ( 27641cb0ef41Sopenharmony_ci self.comments.get_page_address("oldpage")) 27651cb0ef41Sopenharmony_ci self.padawan.known_first_map_page = ( 27661cb0ef41Sopenharmony_ci self.comments.get_page_address("mappage")) 27671cb0ef41Sopenharmony_ci 27681cb0ef41Sopenharmony_ci def set_comment(self, straddress, comment): 27691cb0ef41Sopenharmony_ci try: 27701cb0ef41Sopenharmony_ci address = int(straddress, 0) 27711cb0ef41Sopenharmony_ci self.comments.set_comment(address, comment) 27721cb0ef41Sopenharmony_ci except ValueError: 27731cb0ef41Sopenharmony_ci print("Invalid address") 27741cb0ef41Sopenharmony_ci 27751cb0ef41Sopenharmony_ci def set_page_address(self, kind, straddress): 27761cb0ef41Sopenharmony_ci try: 27771cb0ef41Sopenharmony_ci address = int(straddress, 0) 27781cb0ef41Sopenharmony_ci if kind == "oldpage": 27791cb0ef41Sopenharmony_ci self.padawan.known_first_old_page = address 27801cb0ef41Sopenharmony_ci elif kind == "mappage": 27811cb0ef41Sopenharmony_ci self.padawan.known_first_map_page = address 27821cb0ef41Sopenharmony_ci self.comments.save_page_address(kind, address) 27831cb0ef41Sopenharmony_ci except ValueError: 27841cb0ef41Sopenharmony_ci print("Invalid address") 27851cb0ef41Sopenharmony_ci 27861cb0ef41Sopenharmony_ci def td_from_address(self, f, address): 27871cb0ef41Sopenharmony_ci f.write("<td %s>" % self.comments.get_style_class_string(address)) 27881cb0ef41Sopenharmony_ci 27891cb0ef41Sopenharmony_ci def format_address(self, maybeaddress, straddress = None): 27901cb0ef41Sopenharmony_ci if maybeaddress is None: 27911cb0ef41Sopenharmony_ci return "not in dump" 27921cb0ef41Sopenharmony_ci else: 27931cb0ef41Sopenharmony_ci if straddress is None: 27941cb0ef41Sopenharmony_ci straddress = "0x" + self.reader.FormatIntPtr(maybeaddress) 27951cb0ef41Sopenharmony_ci style_class = "" 27961cb0ef41Sopenharmony_ci if not self.reader.IsValidAddress(maybeaddress): 27971cb0ef41Sopenharmony_ci style_class = "class=nd" 27981cb0ef41Sopenharmony_ci return ("<a %s href=s?%s&val=%s>%s</a>" % 27991cb0ef41Sopenharmony_ci (style_class, self.encfilename, straddress, straddress)) 28001cb0ef41Sopenharmony_ci 28011cb0ef41Sopenharmony_ci def format_onheap_address(self, size, maybeaddress, uncompressed): 28021cb0ef41Sopenharmony_ci if maybeaddress is None: 28031cb0ef41Sopenharmony_ci return "not in dump" 28041cb0ef41Sopenharmony_ci else: 28051cb0ef41Sopenharmony_ci straddress = "0x" + self.reader.FormatTagged(maybeaddress) 28061cb0ef41Sopenharmony_ci struncompressed = "0x" + self.reader.FormatIntPtr(uncompressed) 28071cb0ef41Sopenharmony_ci style_class = "" 28081cb0ef41Sopenharmony_ci if not self.reader.IsValidAddress(maybeaddress): 28091cb0ef41Sopenharmony_ci style_class = "class=nd" 28101cb0ef41Sopenharmony_ci return ("<a %s href=s?%s&val=%s>%s</a>" % 28111cb0ef41Sopenharmony_ci (style_class, self.encfilename, struncompressed, straddress)) 28121cb0ef41Sopenharmony_ci 28131cb0ef41Sopenharmony_ci def output_header(self, f): 28141cb0ef41Sopenharmony_ci f.write(WEB_HEADER % { 28151cb0ef41Sopenharmony_ci "query_dump": self.encfilename, 28161cb0ef41Sopenharmony_ci "dump_name": html.escape(self.dumpfilename) 28171cb0ef41Sopenharmony_ci }) 28181cb0ef41Sopenharmony_ci 28191cb0ef41Sopenharmony_ci def output_footer(self, f): 28201cb0ef41Sopenharmony_ci f.write(WEB_FOOTER) 28211cb0ef41Sopenharmony_ci 28221cb0ef41Sopenharmony_ci MAX_CONTEXT_STACK = 2048 28231cb0ef41Sopenharmony_ci 28241cb0ef41Sopenharmony_ci def output_summary(self, f): 28251cb0ef41Sopenharmony_ci self.output_header(f) 28261cb0ef41Sopenharmony_ci f.write('<div class="code">') 28271cb0ef41Sopenharmony_ci self.output_context(f, InspectionWebFormatter.CONTEXT_SHORT) 28281cb0ef41Sopenharmony_ci self.output_disasm_pc(f) 28291cb0ef41Sopenharmony_ci 28301cb0ef41Sopenharmony_ci # Output stack 28311cb0ef41Sopenharmony_ci exception_thread = self.reader.thread_map[self.reader.exception.thread_id] 28321cb0ef41Sopenharmony_ci stack_top = self.reader.ExceptionSP() 28331cb0ef41Sopenharmony_ci stack_bottom = min(exception_thread.stack.start + \ 28341cb0ef41Sopenharmony_ci exception_thread.stack.memory.data_size, 28351cb0ef41Sopenharmony_ci stack_top + self.MAX_CONTEXT_STACK) 28361cb0ef41Sopenharmony_ci self.output_words(f, stack_top - 16, stack_bottom, stack_top, "Stack", 28371cb0ef41Sopenharmony_ci self.heap.MachinePointerSize()) 28381cb0ef41Sopenharmony_ci 28391cb0ef41Sopenharmony_ci f.write('</div>') 28401cb0ef41Sopenharmony_ci self.output_footer(f) 28411cb0ef41Sopenharmony_ci return 28421cb0ef41Sopenharmony_ci 28431cb0ef41Sopenharmony_ci def output_info(self, f): 28441cb0ef41Sopenharmony_ci self.output_header(f) 28451cb0ef41Sopenharmony_ci f.write("<h3>Dump info</h3>") 28461cb0ef41Sopenharmony_ci f.write("Description: ") 28471cb0ef41Sopenharmony_ci self.server.output_dump_desc_field(f, self.dumpfilename) 28481cb0ef41Sopenharmony_ci f.write("<br>") 28491cb0ef41Sopenharmony_ci f.write("Filename: ") 28501cb0ef41Sopenharmony_ci f.write("<span class=\"code\">%s</span><br>" % (self.dumpfilename)) 28511cb0ef41Sopenharmony_ci dt = datetime.datetime.fromtimestamp(self.reader.header.time_date_stampt) 28521cb0ef41Sopenharmony_ci f.write("Timestamp: %s<br>" % dt.strftime('%Y-%m-%d %H:%M:%S')) 28531cb0ef41Sopenharmony_ci self.output_context(f, InspectionWebFormatter.CONTEXT_FULL) 28541cb0ef41Sopenharmony_ci self.output_address_ranges(f) 28551cb0ef41Sopenharmony_ci self.output_footer(f) 28561cb0ef41Sopenharmony_ci return 28571cb0ef41Sopenharmony_ci 28581cb0ef41Sopenharmony_ci def output_address_ranges(self, f): 28591cb0ef41Sopenharmony_ci regions = {} 28601cb0ef41Sopenharmony_ci def print_region(_reader, start, size, _location): 28611cb0ef41Sopenharmony_ci regions[start] = size 28621cb0ef41Sopenharmony_ci self.reader.ForEachMemoryRegion(print_region) 28631cb0ef41Sopenharmony_ci f.write("<h3>Available memory regions</h3>") 28641cb0ef41Sopenharmony_ci f.write('<div class="code">') 28651cb0ef41Sopenharmony_ci f.write("<table class=\"regions\">") 28661cb0ef41Sopenharmony_ci f.write("<thead><tr>") 28671cb0ef41Sopenharmony_ci f.write("<th>Start address</th>") 28681cb0ef41Sopenharmony_ci f.write("<th>End address</th>") 28691cb0ef41Sopenharmony_ci f.write("<th>Number of bytes</th>") 28701cb0ef41Sopenharmony_ci f.write("</tr></thead>") 28711cb0ef41Sopenharmony_ci for start in sorted(regions): 28721cb0ef41Sopenharmony_ci size = regions[start] 28731cb0ef41Sopenharmony_ci f.write("<tr>") 28741cb0ef41Sopenharmony_ci f.write("<td>%s</td>" % self.format_address(start)) 28751cb0ef41Sopenharmony_ci f.write("<td> %s</td>" % self.format_address(start + size)) 28761cb0ef41Sopenharmony_ci f.write("<td> %d</td>" % size) 28771cb0ef41Sopenharmony_ci f.write("</tr>") 28781cb0ef41Sopenharmony_ci f.write("</table>") 28791cb0ef41Sopenharmony_ci f.write('</div>') 28801cb0ef41Sopenharmony_ci return 28811cb0ef41Sopenharmony_ci 28821cb0ef41Sopenharmony_ci def output_module_details(self, f, module): 28831cb0ef41Sopenharmony_ci f.write("<b>%s</b>" % GetModuleName(self.reader, module)) 28841cb0ef41Sopenharmony_ci file_version = GetVersionString(module.version_info.dwFileVersionMS, 28851cb0ef41Sopenharmony_ci module.version_info.dwFileVersionLS) 28861cb0ef41Sopenharmony_ci product_version = GetVersionString(module.version_info.dwProductVersionMS, 28871cb0ef41Sopenharmony_ci module.version_info.dwProductVersionLS) 28881cb0ef41Sopenharmony_ci f.write("<br> ") 28891cb0ef41Sopenharmony_ci f.write("base: %s" % self.reader.FormatIntPtr(module.base_of_image)) 28901cb0ef41Sopenharmony_ci f.write("<br> ") 28911cb0ef41Sopenharmony_ci f.write(" end: %s" % self.reader.FormatIntPtr(module.base_of_image + 28921cb0ef41Sopenharmony_ci module.size_of_image)) 28931cb0ef41Sopenharmony_ci f.write("<br> ") 28941cb0ef41Sopenharmony_ci f.write(" file version: %s" % file_version) 28951cb0ef41Sopenharmony_ci f.write("<br> ") 28961cb0ef41Sopenharmony_ci f.write(" product version: %s" % product_version) 28971cb0ef41Sopenharmony_ci f.write("<br> ") 28981cb0ef41Sopenharmony_ci time_date_stamp = datetime.datetime.fromtimestamp(module.time_date_stamp) 28991cb0ef41Sopenharmony_ci f.write(" timestamp: %s" % time_date_stamp) 29001cb0ef41Sopenharmony_ci f.write("<br>"); 29011cb0ef41Sopenharmony_ci 29021cb0ef41Sopenharmony_ci def output_modules(self, f): 29031cb0ef41Sopenharmony_ci self.output_header(f) 29041cb0ef41Sopenharmony_ci f.write('<div class="code">') 29051cb0ef41Sopenharmony_ci for module in self.reader.module_list.modules: 29061cb0ef41Sopenharmony_ci self.output_module_details(f, module) 29071cb0ef41Sopenharmony_ci f.write("</div>") 29081cb0ef41Sopenharmony_ci self.output_footer(f) 29091cb0ef41Sopenharmony_ci return 29101cb0ef41Sopenharmony_ci 29111cb0ef41Sopenharmony_ci def output_context(self, f, details): 29121cb0ef41Sopenharmony_ci exception_thread = self.reader.thread_map[self.reader.exception.thread_id] 29131cb0ef41Sopenharmony_ci f.write("<h3>Exception context</h3>") 29141cb0ef41Sopenharmony_ci f.write('<div class="code">') 29151cb0ef41Sopenharmony_ci f.write("Thread id: %d" % exception_thread.id) 29161cb0ef41Sopenharmony_ci f.write(" Exception code: %08X<br/>" % 29171cb0ef41Sopenharmony_ci self.reader.exception.exception.code) 29181cb0ef41Sopenharmony_ci if details == InspectionWebFormatter.CONTEXT_FULL: 29191cb0ef41Sopenharmony_ci if self.reader.exception.exception.parameter_count > 0: 29201cb0ef41Sopenharmony_ci f.write(" Exception parameters: ") 29211cb0ef41Sopenharmony_ci for i in range(0, self.reader.exception.exception.parameter_count): 29221cb0ef41Sopenharmony_ci f.write("%08x" % self.reader.exception.exception.information[i]) 29231cb0ef41Sopenharmony_ci f.write("<br><br>") 29241cb0ef41Sopenharmony_ci 29251cb0ef41Sopenharmony_ci for r in CONTEXT_FOR_ARCH[self.reader.arch]: 29261cb0ef41Sopenharmony_ci f.write(HTML_REG_FORMAT % 29271cb0ef41Sopenharmony_ci (r, self.format_address(self.reader.Register(r)))) 29281cb0ef41Sopenharmony_ci # TODO(vitalyr): decode eflags. 29291cb0ef41Sopenharmony_ci if self.reader.arch in [MD_CPU_ARCHITECTURE_ARM, MD_CPU_ARCHITECTURE_ARM64]: 29301cb0ef41Sopenharmony_ci f.write("<b>cpsr</b>: %s" % bin(self.reader.exception_context.cpsr)[2:]) 29311cb0ef41Sopenharmony_ci else: 29321cb0ef41Sopenharmony_ci f.write("<b>eflags</b>: %s" % 29331cb0ef41Sopenharmony_ci bin(self.reader.exception_context.eflags)[2:]) 29341cb0ef41Sopenharmony_ci f.write('</div>') 29351cb0ef41Sopenharmony_ci return 29361cb0ef41Sopenharmony_ci 29371cb0ef41Sopenharmony_ci def align_down(self, a, size): 29381cb0ef41Sopenharmony_ci alignment_correction = a % size 29391cb0ef41Sopenharmony_ci return a - alignment_correction 29401cb0ef41Sopenharmony_ci 29411cb0ef41Sopenharmony_ci def align_up(self, a, size): 29421cb0ef41Sopenharmony_ci alignment_correction = (size - 1) - ((a + size - 1) % size) 29431cb0ef41Sopenharmony_ci return a + alignment_correction 29441cb0ef41Sopenharmony_ci 29451cb0ef41Sopenharmony_ci def format_object(self, address): 29461cb0ef41Sopenharmony_ci heap_object = self.padawan.SenseObject(address) 29471cb0ef41Sopenharmony_ci return html.escape(str(heap_object or "")) 29481cb0ef41Sopenharmony_ci 29491cb0ef41Sopenharmony_ci def output_data(self, f, straddress, datakind): 29501cb0ef41Sopenharmony_ci try: 29511cb0ef41Sopenharmony_ci self.output_header(f) 29521cb0ef41Sopenharmony_ci address = int(straddress, 0) 29531cb0ef41Sopenharmony_ci if not self.reader.IsValidAddress(address): 29541cb0ef41Sopenharmony_ci f.write("<h3>Address 0x%x not found in the dump.</h3>" % address) 29551cb0ef41Sopenharmony_ci return 29561cb0ef41Sopenharmony_ci region = self.reader.FindRegion(address) 29571cb0ef41Sopenharmony_ci if datakind == "address": 29581cb0ef41Sopenharmony_ci self.output_words(f, region[0], region[0] + region[1], address, "Dump", 29591cb0ef41Sopenharmony_ci self.heap.MachinePointerSize()) 29601cb0ef41Sopenharmony_ci if datakind == "tagged": 29611cb0ef41Sopenharmony_ci self.output_words(f, region[0], region[0] + region[1], address, 29621cb0ef41Sopenharmony_ci "Tagged Dump", self.heap.TaggedPointerSize()) 29631cb0ef41Sopenharmony_ci elif datakind == "ascii": 29641cb0ef41Sopenharmony_ci self.output_ascii(f, region[0], region[0] + region[1], address) 29651cb0ef41Sopenharmony_ci self.output_footer(f) 29661cb0ef41Sopenharmony_ci 29671cb0ef41Sopenharmony_ci except ValueError: 29681cb0ef41Sopenharmony_ci f.write("<h3>Unrecognized address format \"%s\".</h3>" % straddress) 29691cb0ef41Sopenharmony_ci return 29701cb0ef41Sopenharmony_ci 29711cb0ef41Sopenharmony_ci def output_words(self, f, start_address, end_address, highlight_address, desc, 29721cb0ef41Sopenharmony_ci size): 29731cb0ef41Sopenharmony_ci region = self.reader.FindRegion(highlight_address) 29741cb0ef41Sopenharmony_ci if region is None: 29751cb0ef41Sopenharmony_ci f.write("<h3>Address 0x%x not found in the dump.</h3>" % 29761cb0ef41Sopenharmony_ci (highlight_address)) 29771cb0ef41Sopenharmony_ci return 29781cb0ef41Sopenharmony_ci start_address = self.align_down(start_address, size) 29791cb0ef41Sopenharmony_ci low = self.align_down(region[0], size) 29801cb0ef41Sopenharmony_ci high = self.align_up(region[0] + region[1], size) 29811cb0ef41Sopenharmony_ci if start_address < low: 29821cb0ef41Sopenharmony_ci start_address = low 29831cb0ef41Sopenharmony_ci end_address = self.align_up(end_address, size) 29841cb0ef41Sopenharmony_ci if end_address > high: 29851cb0ef41Sopenharmony_ci end_address = high 29861cb0ef41Sopenharmony_ci 29871cb0ef41Sopenharmony_ci expand = "" 29881cb0ef41Sopenharmony_ci if start_address != low or end_address != high: 29891cb0ef41Sopenharmony_ci expand = ("(<a href=\"data.html?%s&val=0x%x#highlight\">" 29901cb0ef41Sopenharmony_ci " more..." 29911cb0ef41Sopenharmony_ci " </a>)" % 29921cb0ef41Sopenharmony_ci (self.encfilename, highlight_address)) 29931cb0ef41Sopenharmony_ci 29941cb0ef41Sopenharmony_ci f.write("<h3>%s 0x%x - 0x%x, " 29951cb0ef41Sopenharmony_ci "highlighting <a href=\"#highlight\">0x%x</a> %s</h3>" % 29961cb0ef41Sopenharmony_ci (desc, start_address, end_address, highlight_address, expand)) 29971cb0ef41Sopenharmony_ci f.write('<div class="code">') 29981cb0ef41Sopenharmony_ci f.write("<table class=codedump>") 29991cb0ef41Sopenharmony_ci 30001cb0ef41Sopenharmony_ci for j in range(0, end_address - start_address, size): 30011cb0ef41Sopenharmony_ci slot = start_address + j 30021cb0ef41Sopenharmony_ci heap_object = "" 30031cb0ef41Sopenharmony_ci maybe_address = None 30041cb0ef41Sopenharmony_ci maybe_uncompressed_address = None 30051cb0ef41Sopenharmony_ci end_region = region[0] + region[1] 30061cb0ef41Sopenharmony_ci if slot < region[0] or slot + size > end_region: 30071cb0ef41Sopenharmony_ci straddress = "0x" 30081cb0ef41Sopenharmony_ci for i in range(end_region, slot + size): 30091cb0ef41Sopenharmony_ci straddress += "??" 30101cb0ef41Sopenharmony_ci for i in reversed( 30111cb0ef41Sopenharmony_ci range(max(slot, region[0]), min(slot + size, end_region))): 30121cb0ef41Sopenharmony_ci straddress += "%02x" % self.reader.ReadU8(i) 30131cb0ef41Sopenharmony_ci for i in range(slot, region[0]): 30141cb0ef41Sopenharmony_ci straddress += "??" 30151cb0ef41Sopenharmony_ci else: 30161cb0ef41Sopenharmony_ci maybe_address = self.reader.ReadSized(slot, size) 30171cb0ef41Sopenharmony_ci if size == self.reader.MachinePointerSize(): 30181cb0ef41Sopenharmony_ci maybe_uncompressed_address = maybe_address 30191cb0ef41Sopenharmony_ci else: 30201cb0ef41Sopenharmony_ci maybe_uncompressed_address = (slot & (0xFFFFFF << 32)) | ( 30211cb0ef41Sopenharmony_ci maybe_address & 0xFFFFFF) 30221cb0ef41Sopenharmony_ci 30231cb0ef41Sopenharmony_ci if size == self.reader.TaggedPointerSize(): 30241cb0ef41Sopenharmony_ci straddress = self.format_onheap_address(size, maybe_address, 30251cb0ef41Sopenharmony_ci maybe_uncompressed_address) 30261cb0ef41Sopenharmony_ci if maybe_address: 30271cb0ef41Sopenharmony_ci heap_object = self.format_object(maybe_address) 30281cb0ef41Sopenharmony_ci else: 30291cb0ef41Sopenharmony_ci straddress = self.format_address(maybe_address) 30301cb0ef41Sopenharmony_ci 30311cb0ef41Sopenharmony_ci address_fmt = "%s </td>" 30321cb0ef41Sopenharmony_ci if slot == highlight_address: 30331cb0ef41Sopenharmony_ci f.write("<tr class=highlight-line>") 30341cb0ef41Sopenharmony_ci address_fmt = "<a id=highlight></a>%s </td>" 30351cb0ef41Sopenharmony_ci elif slot < highlight_address and highlight_address < slot + size: 30361cb0ef41Sopenharmony_ci f.write("<tr class=inexact-highlight-line>") 30371cb0ef41Sopenharmony_ci address_fmt = "<a id=highlight></a>%s </td>" 30381cb0ef41Sopenharmony_ci else: 30391cb0ef41Sopenharmony_ci f.write("<tr>") 30401cb0ef41Sopenharmony_ci 30411cb0ef41Sopenharmony_ci f.write("<td>") 30421cb0ef41Sopenharmony_ci self.output_comment_box(f, "da-", slot) 30431cb0ef41Sopenharmony_ci f.write("</td>") 30441cb0ef41Sopenharmony_ci self.td_from_address(f, slot) 30451cb0ef41Sopenharmony_ci f.write(address_fmt % self.format_address(slot)) 30461cb0ef41Sopenharmony_ci self.td_from_address(f, maybe_uncompressed_address) 30471cb0ef41Sopenharmony_ci f.write(": %s </td>" % straddress) 30481cb0ef41Sopenharmony_ci f.write("<td>") 30491cb0ef41Sopenharmony_ci if maybe_uncompressed_address != None: 30501cb0ef41Sopenharmony_ci self.output_comment_box(f, "sv-" + self.reader.FormatIntPtr(slot), 30511cb0ef41Sopenharmony_ci maybe_uncompressed_address) 30521cb0ef41Sopenharmony_ci f.write("</td>") 30531cb0ef41Sopenharmony_ci f.write("<td>%s</td>" % (heap_object or '')) 30541cb0ef41Sopenharmony_ci f.write("</tr>") 30551cb0ef41Sopenharmony_ci f.write("</table>") 30561cb0ef41Sopenharmony_ci f.write("</div>") 30571cb0ef41Sopenharmony_ci return 30581cb0ef41Sopenharmony_ci 30591cb0ef41Sopenharmony_ci def output_ascii(self, f, start_address, end_address, highlight_address): 30601cb0ef41Sopenharmony_ci region = self.reader.FindRegion(highlight_address) 30611cb0ef41Sopenharmony_ci if region is None: 30621cb0ef41Sopenharmony_ci f.write("<h3>Address %x not found in the dump.</h3>" % 30631cb0ef41Sopenharmony_ci highlight_address) 30641cb0ef41Sopenharmony_ci return 30651cb0ef41Sopenharmony_ci if start_address < region[0]: 30661cb0ef41Sopenharmony_ci start_address = region[0] 30671cb0ef41Sopenharmony_ci if end_address > region[0] + region[1]: 30681cb0ef41Sopenharmony_ci end_address = region[0] + region[1] 30691cb0ef41Sopenharmony_ci 30701cb0ef41Sopenharmony_ci expand = "" 30711cb0ef41Sopenharmony_ci if start_address != region[0] or end_address != region[0] + region[1]: 30721cb0ef41Sopenharmony_ci link = ("data.html?%s&val=0x%x&type=ascii#highlight" % 30731cb0ef41Sopenharmony_ci (self.encfilename, highlight_address)) 30741cb0ef41Sopenharmony_ci expand = "(<a href=\"%s\">more...</a>)" % link 30751cb0ef41Sopenharmony_ci 30761cb0ef41Sopenharmony_ci f.write("<h3>ASCII dump 0x%x - 0x%x, highlighting 0x%x %s</h3>" % 30771cb0ef41Sopenharmony_ci (start_address, end_address, highlight_address, expand)) 30781cb0ef41Sopenharmony_ci 30791cb0ef41Sopenharmony_ci line_width = 64 30801cb0ef41Sopenharmony_ci 30811cb0ef41Sopenharmony_ci f.write('<div class="code">') 30821cb0ef41Sopenharmony_ci 30831cb0ef41Sopenharmony_ci start = self.align_down(start_address, line_width) 30841cb0ef41Sopenharmony_ci 30851cb0ef41Sopenharmony_ci for i in range(end_address - start): 30861cb0ef41Sopenharmony_ci address = start + i 30871cb0ef41Sopenharmony_ci if address % 64 == 0: 30881cb0ef41Sopenharmony_ci if address != start: 30891cb0ef41Sopenharmony_ci f.write("<br>") 30901cb0ef41Sopenharmony_ci f.write("0x%08x: " % address) 30911cb0ef41Sopenharmony_ci if address < start_address: 30921cb0ef41Sopenharmony_ci f.write(" ") 30931cb0ef41Sopenharmony_ci else: 30941cb0ef41Sopenharmony_ci if address == highlight_address: 30951cb0ef41Sopenharmony_ci f.write("<span class=\"highlight\">") 30961cb0ef41Sopenharmony_ci code = self.reader.ReadU8(address) 30971cb0ef41Sopenharmony_ci if code < 127 and code >= 32: 30981cb0ef41Sopenharmony_ci f.write("&#") 30991cb0ef41Sopenharmony_ci f.write(str(code)) 31001cb0ef41Sopenharmony_ci f.write(";") 31011cb0ef41Sopenharmony_ci else: 31021cb0ef41Sopenharmony_ci f.write("·") 31031cb0ef41Sopenharmony_ci if address == highlight_address: 31041cb0ef41Sopenharmony_ci f.write("</span>") 31051cb0ef41Sopenharmony_ci f.write("</div>") 31061cb0ef41Sopenharmony_ci return 31071cb0ef41Sopenharmony_ci 31081cb0ef41Sopenharmony_ci def output_disasm(self, f, straddress, strexact): 31091cb0ef41Sopenharmony_ci try: 31101cb0ef41Sopenharmony_ci self.output_header(f) 31111cb0ef41Sopenharmony_ci address = int(straddress, 0) 31121cb0ef41Sopenharmony_ci if not self.reader.IsValidAddress(address): 31131cb0ef41Sopenharmony_ci f.write("<h3>Address 0x%x not found in the dump.</h3>" % address) 31141cb0ef41Sopenharmony_ci return 31151cb0ef41Sopenharmony_ci region = self.reader.FindRegion(address) 31161cb0ef41Sopenharmony_ci self.output_disasm_range( 31171cb0ef41Sopenharmony_ci f, region[0], region[0] + region[1], address, strexact == "on") 31181cb0ef41Sopenharmony_ci self.output_footer(f) 31191cb0ef41Sopenharmony_ci except ValueError: 31201cb0ef41Sopenharmony_ci f.write("<h3>Unrecognized address format \"%s\".</h3>" % straddress) 31211cb0ef41Sopenharmony_ci return 31221cb0ef41Sopenharmony_ci 31231cb0ef41Sopenharmony_ci def output_disasm_range( 31241cb0ef41Sopenharmony_ci self, f, start_address, end_address, highlight_address, exact): 31251cb0ef41Sopenharmony_ci region = self.reader.FindRegion(highlight_address) 31261cb0ef41Sopenharmony_ci if start_address < region[0]: 31271cb0ef41Sopenharmony_ci start_address = region[0] 31281cb0ef41Sopenharmony_ci if end_address > region[0] + region[1]: 31291cb0ef41Sopenharmony_ci end_address = region[0] + region[1] 31301cb0ef41Sopenharmony_ci count = end_address - start_address 31311cb0ef41Sopenharmony_ci lines = self.reader.GetDisasmLines(start_address, count) 31321cb0ef41Sopenharmony_ci found = False 31331cb0ef41Sopenharmony_ci if exact: 31341cb0ef41Sopenharmony_ci for line in lines: 31351cb0ef41Sopenharmony_ci if line[0] + start_address == highlight_address: 31361cb0ef41Sopenharmony_ci found = True 31371cb0ef41Sopenharmony_ci break 31381cb0ef41Sopenharmony_ci if not found: 31391cb0ef41Sopenharmony_ci start_address = highlight_address 31401cb0ef41Sopenharmony_ci count = end_address - start_address 31411cb0ef41Sopenharmony_ci lines = self.reader.GetDisasmLines(highlight_address, count) 31421cb0ef41Sopenharmony_ci expand = "" 31431cb0ef41Sopenharmony_ci if start_address != region[0] or end_address != region[0] + region[1]: 31441cb0ef41Sopenharmony_ci exactness = "" 31451cb0ef41Sopenharmony_ci if exact and not found and end_address == region[0] + region[1]: 31461cb0ef41Sopenharmony_ci exactness = "&exact=off" 31471cb0ef41Sopenharmony_ci expand = ("(<a href=\"disasm.html?%s%s" 31481cb0ef41Sopenharmony_ci "&val=0x%x#highlight\">more...</a>)" % 31491cb0ef41Sopenharmony_ci (self.encfilename, exactness, highlight_address)) 31501cb0ef41Sopenharmony_ci 31511cb0ef41Sopenharmony_ci f.write("<h3>Disassembling 0x%x - 0x%x, highlighting 0x%x %s</h3>" % 31521cb0ef41Sopenharmony_ci (start_address, end_address, highlight_address, expand)) 31531cb0ef41Sopenharmony_ci f.write('<div class="code">') 31541cb0ef41Sopenharmony_ci f.write("<table class=\"codedump\">"); 31551cb0ef41Sopenharmony_ci for i in range(len(lines)): 31561cb0ef41Sopenharmony_ci line = lines[i] 31571cb0ef41Sopenharmony_ci next_address = count 31581cb0ef41Sopenharmony_ci if i + 1 < len(lines): 31591cb0ef41Sopenharmony_ci next_line = lines[i + 1] 31601cb0ef41Sopenharmony_ci next_address = next_line[0] 31611cb0ef41Sopenharmony_ci self.format_disasm_line( 31621cb0ef41Sopenharmony_ci f, start_address, line, next_address, highlight_address) 31631cb0ef41Sopenharmony_ci f.write("</table>") 31641cb0ef41Sopenharmony_ci f.write("</div>") 31651cb0ef41Sopenharmony_ci return 31661cb0ef41Sopenharmony_ci 31671cb0ef41Sopenharmony_ci def annotate_disasm_addresses(self, line): 31681cb0ef41Sopenharmony_ci extra = [] 31691cb0ef41Sopenharmony_ci for m in ADDRESS_RE.finditer(line): 31701cb0ef41Sopenharmony_ci maybe_address = int(m.group(0), 16) 31711cb0ef41Sopenharmony_ci formatted_address = self.format_address(maybe_address, m.group(0)) 31721cb0ef41Sopenharmony_ci line = line.replace(m.group(0), formatted_address) 31731cb0ef41Sopenharmony_ci object_info = self.padawan.SenseObject(maybe_address) 31741cb0ef41Sopenharmony_ci if not object_info: 31751cb0ef41Sopenharmony_ci continue 31761cb0ef41Sopenharmony_ci extra.append(html.escape(str(object_info))) 31771cb0ef41Sopenharmony_ci if len(extra) == 0: 31781cb0ef41Sopenharmony_ci return line 31791cb0ef41Sopenharmony_ci return ("%s <span class=disasmcomment>;; %s</span>" % 31801cb0ef41Sopenharmony_ci (line, ", ".join(extra))) 31811cb0ef41Sopenharmony_ci 31821cb0ef41Sopenharmony_ci def format_disasm_line( 31831cb0ef41Sopenharmony_ci self, f, start, line, next_address, highlight_address): 31841cb0ef41Sopenharmony_ci line_address = start + line[0] 31851cb0ef41Sopenharmony_ci address_fmt = " <td>%s</td>" 31861cb0ef41Sopenharmony_ci if line_address == highlight_address: 31871cb0ef41Sopenharmony_ci f.write("<tr class=highlight-line>") 31881cb0ef41Sopenharmony_ci address_fmt = " <td><a id=highlight>%s</a></td>" 31891cb0ef41Sopenharmony_ci elif (line_address < highlight_address and 31901cb0ef41Sopenharmony_ci highlight_address < next_address + start): 31911cb0ef41Sopenharmony_ci f.write("<tr class=inexact-highlight-line>") 31921cb0ef41Sopenharmony_ci address_fmt = " <td><a id=highlight>%s</a></td>" 31931cb0ef41Sopenharmony_ci else: 31941cb0ef41Sopenharmony_ci f.write("<tr>") 31951cb0ef41Sopenharmony_ci num_bytes = next_address - line[0] 31961cb0ef41Sopenharmony_ci stack_slot = self.heap.stack_map.get(line_address) 31971cb0ef41Sopenharmony_ci marker = "" 31981cb0ef41Sopenharmony_ci if stack_slot: 31991cb0ef41Sopenharmony_ci marker = "=>" 32001cb0ef41Sopenharmony_ci 32011cb0ef41Sopenharmony_ci code = line[1] 32021cb0ef41Sopenharmony_ci 32031cb0ef41Sopenharmony_ci # Some disassemblers insert spaces between each byte, 32041cb0ef41Sopenharmony_ci # while some do not. 32051cb0ef41Sopenharmony_ci if code[2] == " ": 32061cb0ef41Sopenharmony_ci op_offset = 3 * num_bytes - 1 32071cb0ef41Sopenharmony_ci else: 32081cb0ef41Sopenharmony_ci op_offset = 2 * num_bytes 32091cb0ef41Sopenharmony_ci 32101cb0ef41Sopenharmony_ci # Compute the actual call target which the disassembler is too stupid 32111cb0ef41Sopenharmony_ci # to figure out (it adds the call offset to the disassembly offset rather 32121cb0ef41Sopenharmony_ci # than the absolute instruction address). 32131cb0ef41Sopenharmony_ci if self.heap.reader.arch == MD_CPU_ARCHITECTURE_X86: 32141cb0ef41Sopenharmony_ci if code.startswith("e8"): 32151cb0ef41Sopenharmony_ci words = code.split() 32161cb0ef41Sopenharmony_ci if len(words) > 6 and words[5] == "call": 32171cb0ef41Sopenharmony_ci offset = int(words[4] + words[3] + words[2] + words[1], 16) 32181cb0ef41Sopenharmony_ci target = (line_address + offset + 5) & 0xFFFFFFFF 32191cb0ef41Sopenharmony_ci code = code.replace(words[6], "0x%08x" % target) 32201cb0ef41Sopenharmony_ci # TODO(jkummerow): port this hack to ARM and x64. 32211cb0ef41Sopenharmony_ci 32221cb0ef41Sopenharmony_ci opcodes = code[:op_offset] 32231cb0ef41Sopenharmony_ci code = self.annotate_disasm_addresses(code[op_offset:]) 32241cb0ef41Sopenharmony_ci f.write(" <td>") 32251cb0ef41Sopenharmony_ci self.output_comment_box(f, "codel-", line_address) 32261cb0ef41Sopenharmony_ci f.write("</td>") 32271cb0ef41Sopenharmony_ci f.write(address_fmt % marker) 32281cb0ef41Sopenharmony_ci f.write(" ") 32291cb0ef41Sopenharmony_ci self.td_from_address(f, line_address) 32301cb0ef41Sopenharmony_ci f.write(self.format_address(line_address)) 32311cb0ef41Sopenharmony_ci f.write(" (+0x%x)</td>" % line[0]) 32321cb0ef41Sopenharmony_ci f.write("<td>: %s </td>" % opcodes) 32331cb0ef41Sopenharmony_ci f.write("<td>%s</td>" % code) 32341cb0ef41Sopenharmony_ci f.write("</tr>") 32351cb0ef41Sopenharmony_ci 32361cb0ef41Sopenharmony_ci def output_comment_box(self, f, prefix, address): 32371cb0ef41Sopenharmony_ci comment = self.comments.get_comment(address) 32381cb0ef41Sopenharmony_ci value = "" 32391cb0ef41Sopenharmony_ci if comment: 32401cb0ef41Sopenharmony_ci value = " value=\"%s\"" % html.escape(comment) 32411cb0ef41Sopenharmony_ci f.write("<input type=text class=ci " 32421cb0ef41Sopenharmony_ci "id=%s-address-0x%s onchange=c()%s>" % 32431cb0ef41Sopenharmony_ci (prefix, 32441cb0ef41Sopenharmony_ci self.reader.FormatIntPtr(address), 32451cb0ef41Sopenharmony_ci value)) 32461cb0ef41Sopenharmony_ci 32471cb0ef41Sopenharmony_ci MAX_FOUND_RESULTS = 100 32481cb0ef41Sopenharmony_ci 32491cb0ef41Sopenharmony_ci def output_find_results(self, f, results): 32501cb0ef41Sopenharmony_ci f.write("Addresses") 32511cb0ef41Sopenharmony_ci toomany = len(results) > self.MAX_FOUND_RESULTS 32521cb0ef41Sopenharmony_ci if toomany: 32531cb0ef41Sopenharmony_ci f.write("(found %i results, displaying only first %i)" % 32541cb0ef41Sopenharmony_ci (len(results), self.MAX_FOUND_RESULTS)) 32551cb0ef41Sopenharmony_ci f.write(": ") 32561cb0ef41Sopenharmony_ci results = sorted(results) 32571cb0ef41Sopenharmony_ci results = results[:min(len(results), self.MAX_FOUND_RESULTS)] 32581cb0ef41Sopenharmony_ci for address in results: 32591cb0ef41Sopenharmony_ci f.write("<span %s>%s</span>" % 32601cb0ef41Sopenharmony_ci (self.comments.get_style_class_string(address), 32611cb0ef41Sopenharmony_ci self.format_address(address))) 32621cb0ef41Sopenharmony_ci if toomany: 32631cb0ef41Sopenharmony_ci f.write("...") 32641cb0ef41Sopenharmony_ci 32651cb0ef41Sopenharmony_ci 32661cb0ef41Sopenharmony_ci def output_page_info(self, f, page_kind, page_address, my_page_address): 32671cb0ef41Sopenharmony_ci if my_page_address == page_address and page_address != 0: 32681cb0ef41Sopenharmony_ci f.write("Marked first %s page." % page_kind) 32691cb0ef41Sopenharmony_ci else: 32701cb0ef41Sopenharmony_ci f.write("<span id=\"%spage\" style=\"display:none\">" % page_kind) 32711cb0ef41Sopenharmony_ci f.write("Marked first %s page." % page_kind) 32721cb0ef41Sopenharmony_ci f.write("</span>\n") 32731cb0ef41Sopenharmony_ci f.write("<button onclick=\"onpage('%spage', '0x%x')\">" % 32741cb0ef41Sopenharmony_ci (page_kind, my_page_address)) 32751cb0ef41Sopenharmony_ci f.write("Mark as first %s page</button>" % page_kind) 32761cb0ef41Sopenharmony_ci return 32771cb0ef41Sopenharmony_ci 32781cb0ef41Sopenharmony_ci def output_search_res(self, f, straddress): 32791cb0ef41Sopenharmony_ci try: 32801cb0ef41Sopenharmony_ci self.output_header(f) 32811cb0ef41Sopenharmony_ci f.write("<h3>Search results for %s</h3>" % straddress) 32821cb0ef41Sopenharmony_ci 32831cb0ef41Sopenharmony_ci address = int(straddress, 0) 32841cb0ef41Sopenharmony_ci 32851cb0ef41Sopenharmony_ci f.write("Comment: ") 32861cb0ef41Sopenharmony_ci self.output_comment_box(f, "search-", address) 32871cb0ef41Sopenharmony_ci f.write("<br>") 32881cb0ef41Sopenharmony_ci 32891cb0ef41Sopenharmony_ci page_address = address & ~self.heap.PageAlignmentMask() 32901cb0ef41Sopenharmony_ci 32911cb0ef41Sopenharmony_ci f.write("Page info: ") 32921cb0ef41Sopenharmony_ci self.output_page_info(f, "old", self.padawan.known_first_old_page, \ 32931cb0ef41Sopenharmony_ci page_address) 32941cb0ef41Sopenharmony_ci self.output_page_info(f, "map", self.padawan.known_first_map_page, \ 32951cb0ef41Sopenharmony_ci page_address) 32961cb0ef41Sopenharmony_ci 32971cb0ef41Sopenharmony_ci if not self.reader.IsValidAddress(address): 32981cb0ef41Sopenharmony_ci f.write("<h3>The contents at address %s not found in the dump.</h3>" % \ 32991cb0ef41Sopenharmony_ci straddress) 33001cb0ef41Sopenharmony_ci else: 33011cb0ef41Sopenharmony_ci # Print as words 33021cb0ef41Sopenharmony_ci self.output_words(f, address - 8, address + 32, address, "Dump", 33031cb0ef41Sopenharmony_ci self.heap.MachinePointerSize()) 33041cb0ef41Sopenharmony_ci 33051cb0ef41Sopenharmony_ci if self.heap.IsPointerCompressed(): 33061cb0ef41Sopenharmony_ci self.output_words(f, address - 8, address + 32, address, 33071cb0ef41Sopenharmony_ci "Tagged Dump", self.heap.TaggedPointerSize()) 33081cb0ef41Sopenharmony_ci 33091cb0ef41Sopenharmony_ci # Print as ASCII 33101cb0ef41Sopenharmony_ci f.write("<hr>") 33111cb0ef41Sopenharmony_ci self.output_ascii(f, address, address + 256, address) 33121cb0ef41Sopenharmony_ci 33131cb0ef41Sopenharmony_ci # Print as code 33141cb0ef41Sopenharmony_ci f.write("<hr>") 33151cb0ef41Sopenharmony_ci self.output_disasm_range(f, address - 16, address + 16, address, True) 33161cb0ef41Sopenharmony_ci 33171cb0ef41Sopenharmony_ci aligned_res, unaligned_res = self.reader.FindWordList(address) 33181cb0ef41Sopenharmony_ci 33191cb0ef41Sopenharmony_ci if len(aligned_res) > 0: 33201cb0ef41Sopenharmony_ci f.write("<h3>Occurrences of 0x%x at aligned addresses</h3>" % 33211cb0ef41Sopenharmony_ci address) 33221cb0ef41Sopenharmony_ci self.output_find_results(f, aligned_res) 33231cb0ef41Sopenharmony_ci 33241cb0ef41Sopenharmony_ci if len(unaligned_res) > 0: 33251cb0ef41Sopenharmony_ci f.write("<h3>Occurrences of 0x%x at unaligned addresses</h3>" % \ 33261cb0ef41Sopenharmony_ci address) 33271cb0ef41Sopenharmony_ci self.output_find_results(f, unaligned_res) 33281cb0ef41Sopenharmony_ci 33291cb0ef41Sopenharmony_ci if len(aligned_res) + len(unaligned_res) == 0: 33301cb0ef41Sopenharmony_ci f.write("<h3>No occurrences of 0x%x found in the dump</h3>" % address) 33311cb0ef41Sopenharmony_ci 33321cb0ef41Sopenharmony_ci self.output_footer(f) 33331cb0ef41Sopenharmony_ci 33341cb0ef41Sopenharmony_ci except ValueError: 33351cb0ef41Sopenharmony_ci f.write("<h3>Unrecognized address format \"%s\".</h3>" % straddress) 33361cb0ef41Sopenharmony_ci return 33371cb0ef41Sopenharmony_ci 33381cb0ef41Sopenharmony_ci def output_disasm_pc(self, f): 33391cb0ef41Sopenharmony_ci address = self.reader.ExceptionIP() 33401cb0ef41Sopenharmony_ci if not self.reader.IsValidAddress(address): 33411cb0ef41Sopenharmony_ci return 33421cb0ef41Sopenharmony_ci self.output_disasm_range(f, address - 16, address + 16, address, True) 33431cb0ef41Sopenharmony_ci 33441cb0ef41Sopenharmony_ci 33451cb0ef41Sopenharmony_ciWEB_DUMPS_HEADER = """ 33461cb0ef41Sopenharmony_ci<!DOCTYPE html> 33471cb0ef41Sopenharmony_ci<html> 33481cb0ef41Sopenharmony_ci<head> 33491cb0ef41Sopenharmony_ci<meta content="text/html; charset=utf-8" http-equiv="content-type"> 33501cb0ef41Sopenharmony_ci<style media="screen" type="text/css"> 33511cb0ef41Sopenharmony_ci 33521cb0ef41Sopenharmony_ci.dumplist { 33531cb0ef41Sopenharmony_ci border-collapse : collapse; 33541cb0ef41Sopenharmony_ci border-spacing : 0px; 33551cb0ef41Sopenharmony_ci font-family: monospace; 33561cb0ef41Sopenharmony_ci} 33571cb0ef41Sopenharmony_ci 33581cb0ef41Sopenharmony_ci.dumpcomments { 33591cb0ef41Sopenharmony_ci border : 1px solid LightGray; 33601cb0ef41Sopenharmony_ci width : 32em; 33611cb0ef41Sopenharmony_ci} 33621cb0ef41Sopenharmony_ci 33631cb0ef41Sopenharmony_ci</style> 33641cb0ef41Sopenharmony_ci 33651cb0ef41Sopenharmony_ci<script type="application/javascript"> 33661cb0ef41Sopenharmony_ci 33671cb0ef41Sopenharmony_civar dump_str = "dump-"; 33681cb0ef41Sopenharmony_civar dump_len = dump_str.length; 33691cb0ef41Sopenharmony_ci 33701cb0ef41Sopenharmony_cifunction dump_comment() { 33711cb0ef41Sopenharmony_ci var s = event.srcElement.id; 33721cb0ef41Sopenharmony_ci var index = s.indexOf(dump_str); 33731cb0ef41Sopenharmony_ci if (index >= 0) { 33741cb0ef41Sopenharmony_ci send_dump_desc(s.substring(index + dump_len), event.srcElement.value); 33751cb0ef41Sopenharmony_ci } 33761cb0ef41Sopenharmony_ci} 33771cb0ef41Sopenharmony_ci 33781cb0ef41Sopenharmony_cifunction send_dump_desc(name, desc) { 33791cb0ef41Sopenharmony_ci xmlhttp = new XMLHttpRequest(); 33801cb0ef41Sopenharmony_ci name = encodeURIComponent(name) 33811cb0ef41Sopenharmony_ci desc = encodeURIComponent(desc) 33821cb0ef41Sopenharmony_ci xmlhttp.open("GET", 33831cb0ef41Sopenharmony_ci "setdumpdesc?dump=" + name + 33841cb0ef41Sopenharmony_ci "&description=" + desc, true); 33851cb0ef41Sopenharmony_ci xmlhttp.send(); 33861cb0ef41Sopenharmony_ci} 33871cb0ef41Sopenharmony_ci 33881cb0ef41Sopenharmony_ci</script> 33891cb0ef41Sopenharmony_ci 33901cb0ef41Sopenharmony_ci<title>Dump list</title> 33911cb0ef41Sopenharmony_ci</head> 33921cb0ef41Sopenharmony_ci 33931cb0ef41Sopenharmony_ci<body> 33941cb0ef41Sopenharmony_ci""" 33951cb0ef41Sopenharmony_ci 33961cb0ef41Sopenharmony_ciWEB_DUMPS_FOOTER = """ 33971cb0ef41Sopenharmony_ci</body> 33981cb0ef41Sopenharmony_ci</html> 33991cb0ef41Sopenharmony_ci""" 34001cb0ef41Sopenharmony_ci 34011cb0ef41Sopenharmony_ciDUMP_FILE_RE = re.compile(r"[-_0-9a-zA-Z][-\._0-9a-zA-Z]*\.dmp$") 34021cb0ef41Sopenharmony_ci 34031cb0ef41Sopenharmony_ci 34041cb0ef41Sopenharmony_ciclass InspectionWebServer(http_server.HTTPServer): 34051cb0ef41Sopenharmony_ci 34061cb0ef41Sopenharmony_ci def __init__(self, port_number, switches, minidump_name): 34071cb0ef41Sopenharmony_ci super().__init__(('localhost', port_number), InspectionWebHandler) 34081cb0ef41Sopenharmony_ci splitpath = os.path.split(minidump_name) 34091cb0ef41Sopenharmony_ci self.dumppath = splitpath[0] 34101cb0ef41Sopenharmony_ci self.dumpfilename = splitpath[1] 34111cb0ef41Sopenharmony_ci self.default_formatter = InspectionWebFormatter( 34121cb0ef41Sopenharmony_ci switches, minidump_name, self) 34131cb0ef41Sopenharmony_ci self.formatters = { self.dumpfilename : self.default_formatter } 34141cb0ef41Sopenharmony_ci self.switches = switches 34151cb0ef41Sopenharmony_ci 34161cb0ef41Sopenharmony_ci def output_dump_desc_field(self, f, name): 34171cb0ef41Sopenharmony_ci try: 34181cb0ef41Sopenharmony_ci descfile = open(os.path.join(self.dumppath, name + ".desc"), "r") 34191cb0ef41Sopenharmony_ci desc = descfile.readline() 34201cb0ef41Sopenharmony_ci descfile.close() 34211cb0ef41Sopenharmony_ci except IOError: 34221cb0ef41Sopenharmony_ci desc = "" 34231cb0ef41Sopenharmony_ci f.write("<input type=\"text\" class=\"dumpcomments\" " 34241cb0ef41Sopenharmony_ci "id=\"dump-%s\" onchange=\"dump_comment()\" value=\"%s\">\n" % 34251cb0ef41Sopenharmony_ci (html.escape(name), desc)) 34261cb0ef41Sopenharmony_ci 34271cb0ef41Sopenharmony_ci def set_dump_desc(self, name, description): 34281cb0ef41Sopenharmony_ci if not DUMP_FILE_RE.match(name): 34291cb0ef41Sopenharmony_ci return False 34301cb0ef41Sopenharmony_ci fname = os.path.join(self.dumppath, name) 34311cb0ef41Sopenharmony_ci if not os.path.isfile(fname): 34321cb0ef41Sopenharmony_ci return False 34331cb0ef41Sopenharmony_ci fname = fname + ".desc" 34341cb0ef41Sopenharmony_ci descfile = open(fname, "w") 34351cb0ef41Sopenharmony_ci descfile.write(description) 34361cb0ef41Sopenharmony_ci descfile.close() 34371cb0ef41Sopenharmony_ci return True 34381cb0ef41Sopenharmony_ci 34391cb0ef41Sopenharmony_ci def get_dump_formatter(self, name): 34401cb0ef41Sopenharmony_ci if name is None: 34411cb0ef41Sopenharmony_ci return self.default_formatter 34421cb0ef41Sopenharmony_ci else: 34431cb0ef41Sopenharmony_ci if not DUMP_FILE_RE.match(name): 34441cb0ef41Sopenharmony_ci raise WebParameterError("Invalid name '%s'" % name) 34451cb0ef41Sopenharmony_ci formatter = self.formatters.get(name, None) 34461cb0ef41Sopenharmony_ci if formatter is None: 34471cb0ef41Sopenharmony_ci try: 34481cb0ef41Sopenharmony_ci formatter = InspectionWebFormatter( 34491cb0ef41Sopenharmony_ci self.switches, os.path.join(self.dumppath, name), self) 34501cb0ef41Sopenharmony_ci self.formatters[name] = formatter 34511cb0ef41Sopenharmony_ci except IOError: 34521cb0ef41Sopenharmony_ci raise WebParameterError("Could not open dump '%s'" % name) 34531cb0ef41Sopenharmony_ci return formatter 34541cb0ef41Sopenharmony_ci 34551cb0ef41Sopenharmony_ci def output_dumps(self, f): 34561cb0ef41Sopenharmony_ci f.write(WEB_DUMPS_HEADER) 34571cb0ef41Sopenharmony_ci f.write("<h3>List of available dumps</h3>") 34581cb0ef41Sopenharmony_ci f.write("<table class=\"dumplist\">\n") 34591cb0ef41Sopenharmony_ci f.write("<thead><tr>") 34601cb0ef41Sopenharmony_ci f.write("<th>Name</th>") 34611cb0ef41Sopenharmony_ci f.write("<th>File time</th>") 34621cb0ef41Sopenharmony_ci f.write("<th>Comment</th>") 34631cb0ef41Sopenharmony_ci f.write("</tr></thead>") 34641cb0ef41Sopenharmony_ci dumps_by_time = {} 34651cb0ef41Sopenharmony_ci for fname in os.listdir(self.dumppath): 34661cb0ef41Sopenharmony_ci if DUMP_FILE_RE.match(fname): 34671cb0ef41Sopenharmony_ci mtime = os.stat(os.path.join(self.dumppath, fname)).st_mtime 34681cb0ef41Sopenharmony_ci fnames = dumps_by_time.get(mtime, []) 34691cb0ef41Sopenharmony_ci fnames.append(fname) 34701cb0ef41Sopenharmony_ci dumps_by_time[mtime] = fnames 34711cb0ef41Sopenharmony_ci 34721cb0ef41Sopenharmony_ci for mtime in sorted(dumps_by_time, reverse=True): 34731cb0ef41Sopenharmony_ci fnames = dumps_by_time[mtime] 34741cb0ef41Sopenharmony_ci for fname in fnames: 34751cb0ef41Sopenharmony_ci f.write("<tr>\n") 34761cb0ef41Sopenharmony_ci f.write("<td><a href=\"summary.html?%s\">%s</a></td>\n" % 34771cb0ef41Sopenharmony_ci ((urllib.parse.urlencode({'dump': fname}), fname))) 34781cb0ef41Sopenharmony_ci f.write("<td> ") 34791cb0ef41Sopenharmony_ci f.write(datetime.datetime.fromtimestamp(mtime)) 34801cb0ef41Sopenharmony_ci f.write("</td>") 34811cb0ef41Sopenharmony_ci f.write("<td> ") 34821cb0ef41Sopenharmony_ci self.output_dump_desc_field(f, fname) 34831cb0ef41Sopenharmony_ci f.write("</td>") 34841cb0ef41Sopenharmony_ci f.write("</tr>\n") 34851cb0ef41Sopenharmony_ci f.write("</table>\n") 34861cb0ef41Sopenharmony_ci f.write(WEB_DUMPS_FOOTER) 34871cb0ef41Sopenharmony_ci return 34881cb0ef41Sopenharmony_ci 34891cb0ef41Sopenharmony_ciclass InspectionShell(cmd.Cmd): 34901cb0ef41Sopenharmony_ci def __init__(self, reader, heap): 34911cb0ef41Sopenharmony_ci cmd.Cmd.__init__(self) 34921cb0ef41Sopenharmony_ci self.reader = reader 34931cb0ef41Sopenharmony_ci self.heap = heap 34941cb0ef41Sopenharmony_ci self.padawan = InspectionPadawan(reader, heap) 34951cb0ef41Sopenharmony_ci self.prompt = "(grok) " 34961cb0ef41Sopenharmony_ci 34971cb0ef41Sopenharmony_ci self.dd_start = 0 34981cb0ef41Sopenharmony_ci self.dd_num = 0x10 34991cb0ef41Sopenharmony_ci self.u_start = 0 35001cb0ef41Sopenharmony_ci self.u_num = 0 35011cb0ef41Sopenharmony_ci 35021cb0ef41Sopenharmony_ci def EvalExpression(self, expr): 35031cb0ef41Sopenharmony_ci # Auto convert hex numbers to a python compatible format 35041cb0ef41Sopenharmony_ci if expr[:2] == "00": 35051cb0ef41Sopenharmony_ci expr = "0x"+expr 35061cb0ef41Sopenharmony_ci result = None 35071cb0ef41Sopenharmony_ci try: 35081cb0ef41Sopenharmony_ci # Ugly hack to patch in register values. 35091cb0ef41Sopenharmony_ci registers = [register 35101cb0ef41Sopenharmony_ci for register,value in self.reader.ContextDescriptor().fields] 35111cb0ef41Sopenharmony_ci registers.sort(key=lambda r: len(r)) 35121cb0ef41Sopenharmony_ci registers.reverse() 35131cb0ef41Sopenharmony_ci for register in registers: 35141cb0ef41Sopenharmony_ci expr = expr.replace("$"+register, str(self.reader.Register(register))) 35151cb0ef41Sopenharmony_ci result = eval(expr) 35161cb0ef41Sopenharmony_ci except Exception as e: 35171cb0ef41Sopenharmony_ci print("**** Could not evaluate '%s': %s" % (expr, e)) 35181cb0ef41Sopenharmony_ci raise e 35191cb0ef41Sopenharmony_ci return result 35201cb0ef41Sopenharmony_ci 35211cb0ef41Sopenharmony_ci def ParseAddressExpr(self, expr): 35221cb0ef41Sopenharmony_ci address = 0; 35231cb0ef41Sopenharmony_ci try: 35241cb0ef41Sopenharmony_ci result = self.EvalExpression(expr) 35251cb0ef41Sopenharmony_ci except: 35261cb0ef41Sopenharmony_ci return 0 35271cb0ef41Sopenharmony_ci try: 35281cb0ef41Sopenharmony_ci address = int(result) 35291cb0ef41Sopenharmony_ci except Exception as e: 35301cb0ef41Sopenharmony_ci print("**** Could not convert '%s' => %s to valid address: %s" % ( 35311cb0ef41Sopenharmony_ci expr, result , e)) 35321cb0ef41Sopenharmony_ci return address 35331cb0ef41Sopenharmony_ci 35341cb0ef41Sopenharmony_ci def do_help(self, cmd=None): 35351cb0ef41Sopenharmony_ci if len(cmd) == 0: 35361cb0ef41Sopenharmony_ci print("Available commands") 35371cb0ef41Sopenharmony_ci print("=" * 79) 35381cb0ef41Sopenharmony_ci prefix = "do_" 35391cb0ef41Sopenharmony_ci methods = inspect.getmembers(InspectionShell, predicate=inspect.ismethod) 35401cb0ef41Sopenharmony_ci for name,method in methods: 35411cb0ef41Sopenharmony_ci if not name.startswith(prefix): continue 35421cb0ef41Sopenharmony_ci doc = inspect.getdoc(method) 35431cb0ef41Sopenharmony_ci if not doc: continue 35441cb0ef41Sopenharmony_ci name = prefix.join(name.split(prefix)[1:]) 35451cb0ef41Sopenharmony_ci description = doc.splitlines()[0] 35461cb0ef41Sopenharmony_ci print((name + ": ").ljust(16) + description) 35471cb0ef41Sopenharmony_ci print("=" * 79) 35481cb0ef41Sopenharmony_ci else: 35491cb0ef41Sopenharmony_ci return super(InspectionShell, self).do_help(cmd) 35501cb0ef41Sopenharmony_ci 35511cb0ef41Sopenharmony_ci def do_p(self, cmd): 35521cb0ef41Sopenharmony_ci """ see print """ 35531cb0ef41Sopenharmony_ci return self.do_print(cmd) 35541cb0ef41Sopenharmony_ci 35551cb0ef41Sopenharmony_ci def do_print(self, cmd): 35561cb0ef41Sopenharmony_ci """ 35571cb0ef41Sopenharmony_ci Evaluate an arbitrary python command. 35581cb0ef41Sopenharmony_ci """ 35591cb0ef41Sopenharmony_ci try: 35601cb0ef41Sopenharmony_ci print(self.EvalExpression(cmd)) 35611cb0ef41Sopenharmony_ci except: 35621cb0ef41Sopenharmony_ci pass 35631cb0ef41Sopenharmony_ci 35641cb0ef41Sopenharmony_ci def do_da(self, address): 35651cb0ef41Sopenharmony_ci """ see display_ascii""" 35661cb0ef41Sopenharmony_ci return self.do_display_ascii(address) 35671cb0ef41Sopenharmony_ci 35681cb0ef41Sopenharmony_ci def do_display_ascii(self, address): 35691cb0ef41Sopenharmony_ci """ 35701cb0ef41Sopenharmony_ci Print ASCII string starting at specified address. 35711cb0ef41Sopenharmony_ci """ 35721cb0ef41Sopenharmony_ci address = self.ParseAddressExpr(address) 35731cb0ef41Sopenharmony_ci string = self.reader.ReadAsciiString(address) 35741cb0ef41Sopenharmony_ci if string == "": 35751cb0ef41Sopenharmony_ci print("Not an ASCII string at %s" % self.reader.FormatIntPtr(address)) 35761cb0ef41Sopenharmony_ci else: 35771cb0ef41Sopenharmony_ci print("%s\n" % string) 35781cb0ef41Sopenharmony_ci 35791cb0ef41Sopenharmony_ci def do_dsa(self, address): 35801cb0ef41Sopenharmony_ci """ see display_stack_ascii""" 35811cb0ef41Sopenharmony_ci return self.do_display_stack_ascii(address) 35821cb0ef41Sopenharmony_ci 35831cb0ef41Sopenharmony_ci def do_display_stack_ascii(self, address): 35841cb0ef41Sopenharmony_ci """ 35851cb0ef41Sopenharmony_ci Print ASCII stack error message. 35861cb0ef41Sopenharmony_ci """ 35871cb0ef41Sopenharmony_ci if self.reader.exception is None: 35881cb0ef41Sopenharmony_ci print("Minidump has no exception info") 35891cb0ef41Sopenharmony_ci return 35901cb0ef41Sopenharmony_ci if len(address) == 0: 35911cb0ef41Sopenharmony_ci address = None 35921cb0ef41Sopenharmony_ci else: 35931cb0ef41Sopenharmony_ci address = self.ParseAddressExpr(address) 35941cb0ef41Sopenharmony_ci self.padawan.PrintStackTraceMessage(address) 35951cb0ef41Sopenharmony_ci 35961cb0ef41Sopenharmony_ci def do_dd(self, args): 35971cb0ef41Sopenharmony_ci """ 35981cb0ef41Sopenharmony_ci Interpret memory in the given region [address, address + num * word_size) 35991cb0ef41Sopenharmony_ci 36001cb0ef41Sopenharmony_ci (if available) as a sequence of words. Automatic alignment is not performed. 36011cb0ef41Sopenharmony_ci If the num is not specified, a default value of 16 words is usif not self.Is 36021cb0ef41Sopenharmony_ci If no address is given, dd continues printing at the next word. 36031cb0ef41Sopenharmony_ci 36041cb0ef41Sopenharmony_ci Synopsis: dd 0x<address>|$register [0x<num>] 36051cb0ef41Sopenharmony_ci """ 36061cb0ef41Sopenharmony_ci if len(args) != 0: 36071cb0ef41Sopenharmony_ci args = args.split(' ') 36081cb0ef41Sopenharmony_ci self.dd_start = self.ParseAddressExpr(args[0]) 36091cb0ef41Sopenharmony_ci self.dd_num = int(args[1], 16) if len(args) > 1 else 0x10 36101cb0ef41Sopenharmony_ci else: 36111cb0ef41Sopenharmony_ci self.dd_start += self.dd_num * self.reader.MachinePointerSize() 36121cb0ef41Sopenharmony_ci if not self.reader.IsAlignedAddress(self.dd_start): 36131cb0ef41Sopenharmony_ci print("Warning: Dumping un-aligned memory, is this what you had in mind?") 36141cb0ef41Sopenharmony_ci end = self.dd_start + self.reader.MachinePointerSize() * self.dd_num 36151cb0ef41Sopenharmony_ci self.padawan.InterpretMemory(self.dd_start, end) 36161cb0ef41Sopenharmony_ci 36171cb0ef41Sopenharmony_ci def do_do(self, address): 36181cb0ef41Sopenharmony_ci """ see display_object """ 36191cb0ef41Sopenharmony_ci return self.do_display_object(address) 36201cb0ef41Sopenharmony_ci 36211cb0ef41Sopenharmony_ci def do_display_object(self, address): 36221cb0ef41Sopenharmony_ci """ 36231cb0ef41Sopenharmony_ci Interpret memory at the given address as a V8 object. 36241cb0ef41Sopenharmony_ci 36251cb0ef41Sopenharmony_ci Automatic alignment makes sure that you can pass tagged as well as 36261cb0ef41Sopenharmony_ci un-tagged addresses. 36271cb0ef41Sopenharmony_ci """ 36281cb0ef41Sopenharmony_ci address = self.ParseAddressExpr(address) 36291cb0ef41Sopenharmony_ci if self.reader.IsAlignedAddress(address): 36301cb0ef41Sopenharmony_ci address = address + 1 36311cb0ef41Sopenharmony_ci elif not self.heap.IsTaggedObjectAddress(address): 36321cb0ef41Sopenharmony_ci print("Address doesn't look like a valid pointer!") 36331cb0ef41Sopenharmony_ci return 36341cb0ef41Sopenharmony_ci heap_object = self.padawan.SenseObject(address) 36351cb0ef41Sopenharmony_ci if heap_object: 36361cb0ef41Sopenharmony_ci heap_object.Print(Printer()) 36371cb0ef41Sopenharmony_ci else: 36381cb0ef41Sopenharmony_ci print("Address cannot be interpreted as object!") 36391cb0ef41Sopenharmony_ci 36401cb0ef41Sopenharmony_ci def do_dso(self, args): 36411cb0ef41Sopenharmony_ci """ see display_stack_objects """ 36421cb0ef41Sopenharmony_ci return self.do_display_stack_objects(args) 36431cb0ef41Sopenharmony_ci 36441cb0ef41Sopenharmony_ci def do_display_stack_objects(self, args): 36451cb0ef41Sopenharmony_ci """ 36461cb0ef41Sopenharmony_ci Find and Print object pointers in the given range. 36471cb0ef41Sopenharmony_ci 36481cb0ef41Sopenharmony_ci Print all possible object pointers that are on the stack or in the given 36491cb0ef41Sopenharmony_ci address range. 36501cb0ef41Sopenharmony_ci 36511cb0ef41Sopenharmony_ci Usage: dso [START_ADDR,[END_ADDR]] 36521cb0ef41Sopenharmony_ci """ 36531cb0ef41Sopenharmony_ci start = self.reader.StackTop() 36541cb0ef41Sopenharmony_ci end = self.reader.StackBottom() 36551cb0ef41Sopenharmony_ci if len(args) != 0: 36561cb0ef41Sopenharmony_ci args = args.split(' ') 36571cb0ef41Sopenharmony_ci start = self.ParseAddressExpr(args[0]) 36581cb0ef41Sopenharmony_ci end = self.ParseAddressExpr(args[1]) if len(args) > 1 else end 36591cb0ef41Sopenharmony_ci objects = self.heap.FindObjectPointers(start, end) 36601cb0ef41Sopenharmony_ci for address in objects: 36611cb0ef41Sopenharmony_ci heap_object = self.padawan.SenseObject(address) 36621cb0ef41Sopenharmony_ci info = "" 36631cb0ef41Sopenharmony_ci if heap_object: 36641cb0ef41Sopenharmony_ci info = str(heap_object) 36651cb0ef41Sopenharmony_ci print("%s %s" % (self.padawan.FormatIntPtr(address), info)) 36661cb0ef41Sopenharmony_ci 36671cb0ef41Sopenharmony_ci def do_do_desc(self, address): 36681cb0ef41Sopenharmony_ci """ 36691cb0ef41Sopenharmony_ci Print a descriptor array in a readable format. 36701cb0ef41Sopenharmony_ci """ 36711cb0ef41Sopenharmony_ci start = self.ParseAddressExpr(address) 36721cb0ef41Sopenharmony_ci if ((start & 1) == 1): start = start - 1 36731cb0ef41Sopenharmony_ci DescriptorArray(FixedArray(self.heap, None, start)).Print(Printer()) 36741cb0ef41Sopenharmony_ci 36751cb0ef41Sopenharmony_ci def do_do_map(self, address): 36761cb0ef41Sopenharmony_ci """ 36771cb0ef41Sopenharmony_ci Print a Map in a readable format. 36781cb0ef41Sopenharmony_ci """ 36791cb0ef41Sopenharmony_ci start = self.ParseAddressExpr(address) 36801cb0ef41Sopenharmony_ci if ((start & 1) == 1): start = start - 1 36811cb0ef41Sopenharmony_ci Map(self.heap, None, start).Print(Printer()) 36821cb0ef41Sopenharmony_ci 36831cb0ef41Sopenharmony_ci def do_do_trans(self, address): 36841cb0ef41Sopenharmony_ci """ 36851cb0ef41Sopenharmony_ci Print a transition array in a readable format. 36861cb0ef41Sopenharmony_ci """ 36871cb0ef41Sopenharmony_ci start = self.ParseAddressExpr(address) 36881cb0ef41Sopenharmony_ci if ((start & 1) == 1): start = start - 1 36891cb0ef41Sopenharmony_ci TransitionArray(FixedArray(self.heap, None, start)).Print(Printer()) 36901cb0ef41Sopenharmony_ci 36911cb0ef41Sopenharmony_ci def do_dp(self, address): 36921cb0ef41Sopenharmony_ci """ see display_page """ 36931cb0ef41Sopenharmony_ci return self.do_display_page(address) 36941cb0ef41Sopenharmony_ci 36951cb0ef41Sopenharmony_ci def do_display_page(self, address): 36961cb0ef41Sopenharmony_ci """ 36971cb0ef41Sopenharmony_ci Prints details about the V8 heap page of the given address. 36981cb0ef41Sopenharmony_ci 36991cb0ef41Sopenharmony_ci Interpret memory at the given address as being on a V8 heap page 37001cb0ef41Sopenharmony_ci and print information about the page header (if available). 37011cb0ef41Sopenharmony_ci """ 37021cb0ef41Sopenharmony_ci address = self.ParseAddressExpr(address) 37031cb0ef41Sopenharmony_ci page_address = address & ~self.heap.PageAlignmentMask() 37041cb0ef41Sopenharmony_ci if self.reader.IsValidAddress(page_address): 37051cb0ef41Sopenharmony_ci print("**** Not Implemented") 37061cb0ef41Sopenharmony_ci return 37071cb0ef41Sopenharmony_ci else: 37081cb0ef41Sopenharmony_ci print("Page header is not available!") 37091cb0ef41Sopenharmony_ci 37101cb0ef41Sopenharmony_ci def do_k(self, arguments): 37111cb0ef41Sopenharmony_ci """ 37121cb0ef41Sopenharmony_ci Teach V8 heap layout information to the inspector. 37131cb0ef41Sopenharmony_ci 37141cb0ef41Sopenharmony_ci This increases the amount of annotations the inspector can produce while 37151cb0ef41Sopenharmony_ci dumping data. The first page of each heap space is of particular interest 37161cb0ef41Sopenharmony_ci because it contains known objects that do not move. 37171cb0ef41Sopenharmony_ci """ 37181cb0ef41Sopenharmony_ci self.padawan.PrintKnowledge() 37191cb0ef41Sopenharmony_ci 37201cb0ef41Sopenharmony_ci def do_ko(self, address): 37211cb0ef41Sopenharmony_ci """ see known_oldspace """ 37221cb0ef41Sopenharmony_ci return self.do_known_oldspace(address) 37231cb0ef41Sopenharmony_ci 37241cb0ef41Sopenharmony_ci def do_known_oldspace(self, address): 37251cb0ef41Sopenharmony_ci """ 37261cb0ef41Sopenharmony_ci Teach V8 heap layout information to the inspector. 37271cb0ef41Sopenharmony_ci 37281cb0ef41Sopenharmony_ci Set the first old space page by passing any pointer into that page. 37291cb0ef41Sopenharmony_ci """ 37301cb0ef41Sopenharmony_ci address = self.ParseAddressExpr(address) 37311cb0ef41Sopenharmony_ci page_address = address & ~self.heap.PageAlignmentMask() 37321cb0ef41Sopenharmony_ci self.padawan.known_first_old_page = page_address 37331cb0ef41Sopenharmony_ci 37341cb0ef41Sopenharmony_ci def do_km(self, address): 37351cb0ef41Sopenharmony_ci """ see known_map """ 37361cb0ef41Sopenharmony_ci return self.do_known_map(address) 37371cb0ef41Sopenharmony_ci 37381cb0ef41Sopenharmony_ci def do_known_map(self, address): 37391cb0ef41Sopenharmony_ci """ 37401cb0ef41Sopenharmony_ci Teach V8 heap layout information to the inspector. 37411cb0ef41Sopenharmony_ci 37421cb0ef41Sopenharmony_ci Set the first map-space page by passing any pointer into that page. 37431cb0ef41Sopenharmony_ci """ 37441cb0ef41Sopenharmony_ci address = self.ParseAddressExpr(address) 37451cb0ef41Sopenharmony_ci page_address = address & ~self.heap.PageAlignmentMask() 37461cb0ef41Sopenharmony_ci self.padawan.known_first_map_page = page_address 37471cb0ef41Sopenharmony_ci 37481cb0ef41Sopenharmony_ci def do_list(self, smth): 37491cb0ef41Sopenharmony_ci """ 37501cb0ef41Sopenharmony_ci List all available memory regions. 37511cb0ef41Sopenharmony_ci """ 37521cb0ef41Sopenharmony_ci def print_region(reader, start, size, location): 37531cb0ef41Sopenharmony_ci print(" %s - %s (%d bytes)" % (reader.FormatIntPtr(start), 37541cb0ef41Sopenharmony_ci reader.FormatIntPtr(start + size), 37551cb0ef41Sopenharmony_ci size)) 37561cb0ef41Sopenharmony_ci print("Available memory regions:") 37571cb0ef41Sopenharmony_ci self.reader.ForEachMemoryRegion(print_region) 37581cb0ef41Sopenharmony_ci 37591cb0ef41Sopenharmony_ci def do_lm(self, arg): 37601cb0ef41Sopenharmony_ci """ see list_modules """ 37611cb0ef41Sopenharmony_ci return self.do_list_modules(arg) 37621cb0ef41Sopenharmony_ci 37631cb0ef41Sopenharmony_ci def do_list_modules(self, arg): 37641cb0ef41Sopenharmony_ci """ 37651cb0ef41Sopenharmony_ci List details for all loaded modules in the minidump. 37661cb0ef41Sopenharmony_ci 37671cb0ef41Sopenharmony_ci An argument can be passed to limit the output to only those modules that 37681cb0ef41Sopenharmony_ci contain the argument as a substring (case insensitive match). 37691cb0ef41Sopenharmony_ci """ 37701cb0ef41Sopenharmony_ci for module in self.reader.module_list.modules: 37711cb0ef41Sopenharmony_ci if arg: 37721cb0ef41Sopenharmony_ci name = GetModuleName(self.reader, module).lower() 37731cb0ef41Sopenharmony_ci if name.find(arg.lower()) >= 0: 37741cb0ef41Sopenharmony_ci PrintModuleDetails(self.reader, module) 37751cb0ef41Sopenharmony_ci else: 37761cb0ef41Sopenharmony_ci PrintModuleDetails(self.reader, module) 37771cb0ef41Sopenharmony_ci print() 37781cb0ef41Sopenharmony_ci 37791cb0ef41Sopenharmony_ci def do_s(self, word): 37801cb0ef41Sopenharmony_ci """ see search """ 37811cb0ef41Sopenharmony_ci return self.do_search(word) 37821cb0ef41Sopenharmony_ci 37831cb0ef41Sopenharmony_ci def do_search(self, word): 37841cb0ef41Sopenharmony_ci """ 37851cb0ef41Sopenharmony_ci Search for a given word in available memory regions. 37861cb0ef41Sopenharmony_ci 37871cb0ef41Sopenharmony_ci The given word is expanded to full pointer size and searched at aligned 37881cb0ef41Sopenharmony_ci as well as un-aligned memory locations. Use 'sa' to search aligned locations 37891cb0ef41Sopenharmony_ci only. 37901cb0ef41Sopenharmony_ci """ 37911cb0ef41Sopenharmony_ci try: 37921cb0ef41Sopenharmony_ci word = self.ParseAddressExpr(word) 37931cb0ef41Sopenharmony_ci except ValueError: 37941cb0ef41Sopenharmony_ci print("Malformed word, prefix with '0x' to use hexadecimal format.") 37951cb0ef41Sopenharmony_ci return 37961cb0ef41Sopenharmony_ci print( 37971cb0ef41Sopenharmony_ci "Searching for word %d/0x%s:" % (word, self.reader.FormatIntPtr(word))) 37981cb0ef41Sopenharmony_ci self.reader.FindWord(word) 37991cb0ef41Sopenharmony_ci 38001cb0ef41Sopenharmony_ci def do_sh(self, none): 38011cb0ef41Sopenharmony_ci """ 38021cb0ef41Sopenharmony_ci Search for the V8 Heap object in all available memory regions. 38031cb0ef41Sopenharmony_ci 38041cb0ef41Sopenharmony_ci You might get lucky and find this rare treasure full of invaluable 38051cb0ef41Sopenharmony_ci information. 38061cb0ef41Sopenharmony_ci """ 38071cb0ef41Sopenharmony_ci print("**** Not Implemented") 38081cb0ef41Sopenharmony_ci 38091cb0ef41Sopenharmony_ci def do_u(self, args): 38101cb0ef41Sopenharmony_ci """ see disassemble """ 38111cb0ef41Sopenharmony_ci return self.do_disassemble(args) 38121cb0ef41Sopenharmony_ci 38131cb0ef41Sopenharmony_ci def do_disassemble(self, args): 38141cb0ef41Sopenharmony_ci """ 38151cb0ef41Sopenharmony_ci Unassemble memory in the region [address, address + size). 38161cb0ef41Sopenharmony_ci 38171cb0ef41Sopenharmony_ci If the size is not specified, a default value of 32 bytes is used. 38181cb0ef41Sopenharmony_ci Synopsis: u 0x<address> 0x<size> 38191cb0ef41Sopenharmony_ci """ 38201cb0ef41Sopenharmony_ci if len(args) != 0: 38211cb0ef41Sopenharmony_ci args = args.split(' ') 38221cb0ef41Sopenharmony_ci self.u_start = self.ParseAddressExpr(args[0]) 38231cb0ef41Sopenharmony_ci self.u_size = self.ParseAddressExpr(args[1]) if len(args) > 1 else 0x20 38241cb0ef41Sopenharmony_ci skip = False 38251cb0ef41Sopenharmony_ci else: 38261cb0ef41Sopenharmony_ci # Skip the first instruction if we reuse the last address. 38271cb0ef41Sopenharmony_ci skip = True 38281cb0ef41Sopenharmony_ci 38291cb0ef41Sopenharmony_ci if not self.reader.IsValidAddress(self.u_start): 38301cb0ef41Sopenharmony_ci print("Address %s is not contained within the minidump!" % ( 38311cb0ef41Sopenharmony_ci self.reader.FormatIntPtr(self.u_start))) 38321cb0ef41Sopenharmony_ci return 38331cb0ef41Sopenharmony_ci lines = self.reader.GetDisasmLines(self.u_start, self.u_size) 38341cb0ef41Sopenharmony_ci if len(lines) == 0: 38351cb0ef41Sopenharmony_ci print("Address %s could not be disassembled!" % ( 38361cb0ef41Sopenharmony_ci self.reader.FormatIntPtr(self.u_start))) 38371cb0ef41Sopenharmony_ci print(" Could not disassemble using %s." % OBJDUMP_BIN) 38381cb0ef41Sopenharmony_ci print(" Pass path to architecture specific objdump via --objdump?") 38391cb0ef41Sopenharmony_ci return 38401cb0ef41Sopenharmony_ci for line in lines: 38411cb0ef41Sopenharmony_ci if skip: 38421cb0ef41Sopenharmony_ci skip = False 38431cb0ef41Sopenharmony_ci continue 38441cb0ef41Sopenharmony_ci print(FormatDisasmLine(self.u_start, self.heap, line)) 38451cb0ef41Sopenharmony_ci # Set the next start address = last line 38461cb0ef41Sopenharmony_ci self.u_start += lines[-1][0] 38471cb0ef41Sopenharmony_ci print() 38481cb0ef41Sopenharmony_ci 38491cb0ef41Sopenharmony_ci def do_EOF(self, none): 38501cb0ef41Sopenharmony_ci raise KeyboardInterrupt 38511cb0ef41Sopenharmony_ci 38521cb0ef41Sopenharmony_ciEIP_PROXIMITY = 64 38531cb0ef41Sopenharmony_ci 38541cb0ef41Sopenharmony_ciCONTEXT_FOR_ARCH = { 38551cb0ef41Sopenharmony_ci MD_CPU_ARCHITECTURE_AMD64: 38561cb0ef41Sopenharmony_ci ['rax', 'rbx', 'rcx', 'rdx', 'rdi', 'rsi', 'rbp', 'rsp', 'rip', 38571cb0ef41Sopenharmony_ci 'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15'], 38581cb0ef41Sopenharmony_ci MD_CPU_ARCHITECTURE_ARM: 38591cb0ef41Sopenharmony_ci ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 38601cb0ef41Sopenharmony_ci 'r10', 'r11', 'r12', 'sp', 'lr', 'pc'], 38611cb0ef41Sopenharmony_ci MD_CPU_ARCHITECTURE_ARM64: 38621cb0ef41Sopenharmony_ci ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 38631cb0ef41Sopenharmony_ci 'r10', 'r11', 'r12', 'r13', 'r14', 'r15', 'r16', 'r17', 'r18', 'r19', 38641cb0ef41Sopenharmony_ci 'r20', 'r21', 'r22', 'r23', 'r24', 'r25', 'r26', 'r27', 'r28', 38651cb0ef41Sopenharmony_ci 'fp', 'lr', 'sp', 'pc'], 38661cb0ef41Sopenharmony_ci MD_CPU_ARCHITECTURE_X86: 38671cb0ef41Sopenharmony_ci ['eax', 'ebx', 'ecx', 'edx', 'edi', 'esi', 'ebp', 'esp', 'eip'] 38681cb0ef41Sopenharmony_ci} 38691cb0ef41Sopenharmony_ci 38701cb0ef41Sopenharmony_ciKNOWN_MODULES = {'chrome.exe', 'chrome.dll'} 38711cb0ef41Sopenharmony_ci 38721cb0ef41Sopenharmony_cidef GetVersionString(ms, ls): 38731cb0ef41Sopenharmony_ci return "%d.%d.%d.%d" % (ms >> 16, ms & 0xffff, ls >> 16, ls & 0xffff) 38741cb0ef41Sopenharmony_ci 38751cb0ef41Sopenharmony_ci 38761cb0ef41Sopenharmony_cidef GetModuleName(reader, module): 38771cb0ef41Sopenharmony_ci name = reader.ReadMinidumpString(module.module_name_rva) 38781cb0ef41Sopenharmony_ci # simplify for path manipulation 38791cb0ef41Sopenharmony_ci name = name.encode('utf-8') 38801cb0ef41Sopenharmony_ci return str(os.path.basename(str(name).replace("\\", "/"))) 38811cb0ef41Sopenharmony_ci 38821cb0ef41Sopenharmony_ci 38831cb0ef41Sopenharmony_cidef PrintModuleDetails(reader, module): 38841cb0ef41Sopenharmony_ci print("%s" % GetModuleName(reader, module)) 38851cb0ef41Sopenharmony_ci file_version = GetVersionString(module.version_info.dwFileVersionMS, 38861cb0ef41Sopenharmony_ci module.version_info.dwFileVersionLS); 38871cb0ef41Sopenharmony_ci product_version = GetVersionString(module.version_info.dwProductVersionMS, 38881cb0ef41Sopenharmony_ci module.version_info.dwProductVersionLS) 38891cb0ef41Sopenharmony_ci print(" base: %s" % reader.FormatIntPtr(module.base_of_image)) 38901cb0ef41Sopenharmony_ci print(" end: %s" % reader.FormatIntPtr(module.base_of_image + 38911cb0ef41Sopenharmony_ci module.size_of_image)) 38921cb0ef41Sopenharmony_ci print(" file version: %s" % file_version) 38931cb0ef41Sopenharmony_ci print(" product version: %s" % product_version) 38941cb0ef41Sopenharmony_ci time_date_stamp = datetime.datetime.fromtimestamp(module.time_date_stamp) 38951cb0ef41Sopenharmony_ci print(" timestamp: %s" % time_date_stamp) 38961cb0ef41Sopenharmony_ci 38971cb0ef41Sopenharmony_ci 38981cb0ef41Sopenharmony_cidef AnalyzeMinidump(options, minidump_name): 38991cb0ef41Sopenharmony_ci reader = MinidumpReader(options, minidump_name) 39001cb0ef41Sopenharmony_ci # Use a separate function to prevent leaking the minidump buffer through 39011cb0ef41Sopenharmony_ci # ctypes in local variables. 39021cb0ef41Sopenharmony_ci _AnalyzeMinidump(options, reader) 39031cb0ef41Sopenharmony_ci reader.Dispose() 39041cb0ef41Sopenharmony_ci 39051cb0ef41Sopenharmony_ci 39061cb0ef41Sopenharmony_cidef _AnalyzeMinidump(options, reader): 39071cb0ef41Sopenharmony_ci heap = None 39081cb0ef41Sopenharmony_ci 39091cb0ef41Sopenharmony_ci stack_top = reader.ExceptionSP() 39101cb0ef41Sopenharmony_ci stack_bottom = reader.StackBottom() 39111cb0ef41Sopenharmony_ci stack_map = {reader.ExceptionIP(): -1} 39121cb0ef41Sopenharmony_ci for slot in range(stack_top, stack_bottom, reader.MachinePointerSize()): 39131cb0ef41Sopenharmony_ci maybe_address = reader.ReadUIntPtr(slot) 39141cb0ef41Sopenharmony_ci if not maybe_address in stack_map: 39151cb0ef41Sopenharmony_ci stack_map[maybe_address] = slot 39161cb0ef41Sopenharmony_ci 39171cb0ef41Sopenharmony_ci heap = V8Heap(reader, stack_map) 39181cb0ef41Sopenharmony_ci padawan = InspectionPadawan(reader, heap) 39191cb0ef41Sopenharmony_ci 39201cb0ef41Sopenharmony_ci DebugPrint("========================================") 39211cb0ef41Sopenharmony_ci if reader.exception is None: 39221cb0ef41Sopenharmony_ci print("Minidump has no exception info") 39231cb0ef41Sopenharmony_ci else: 39241cb0ef41Sopenharmony_ci print("Address markers:") 39251cb0ef41Sopenharmony_ci print(" T = valid tagged pointer in the minidump") 39261cb0ef41Sopenharmony_ci print(" S = address on the exception stack") 39271cb0ef41Sopenharmony_ci print(" C = address in loaded C/C++ module") 39281cb0ef41Sopenharmony_ci print(" * = address in the minidump") 39291cb0ef41Sopenharmony_ci print("") 39301cb0ef41Sopenharmony_ci print("Exception info:") 39311cb0ef41Sopenharmony_ci exception_thread = reader.ExceptionThread() 39321cb0ef41Sopenharmony_ci print(" thread id: %d" % exception_thread.id) 39331cb0ef41Sopenharmony_ci print(" code: %08X" % reader.exception.exception.code) 39341cb0ef41Sopenharmony_ci print(" context:") 39351cb0ef41Sopenharmony_ci context = CONTEXT_FOR_ARCH[reader.arch] 39361cb0ef41Sopenharmony_ci maxWidth = max(map(lambda s: len(s), context)) 39371cb0ef41Sopenharmony_ci for r in context: 39381cb0ef41Sopenharmony_ci register_value = reader.Register(r) 39391cb0ef41Sopenharmony_ci print(" %s: %s" % (r.rjust(maxWidth), 39401cb0ef41Sopenharmony_ci heap.FormatIntPtr(register_value))) 39411cb0ef41Sopenharmony_ci # TODO(vitalyr): decode eflags. 39421cb0ef41Sopenharmony_ci if reader.arch in [MD_CPU_ARCHITECTURE_ARM, MD_CPU_ARCHITECTURE_ARM64]: 39431cb0ef41Sopenharmony_ci print(" cpsr: %s" % bin(reader.exception_context.cpsr)[2:]) 39441cb0ef41Sopenharmony_ci else: 39451cb0ef41Sopenharmony_ci print(" eflags: %s" % bin(reader.exception_context.eflags)[2:]) 39461cb0ef41Sopenharmony_ci 39471cb0ef41Sopenharmony_ci print() 39481cb0ef41Sopenharmony_ci print(" modules:") 39491cb0ef41Sopenharmony_ci for module in reader.module_list.modules: 39501cb0ef41Sopenharmony_ci name = GetModuleName(reader, module) 39511cb0ef41Sopenharmony_ci if name in KNOWN_MODULES: 39521cb0ef41Sopenharmony_ci print(" %s at %08X" % (name, module.base_of_image)) 39531cb0ef41Sopenharmony_ci reader.TryLoadSymbolsFor(name, module) 39541cb0ef41Sopenharmony_ci print() 39551cb0ef41Sopenharmony_ci 39561cb0ef41Sopenharmony_ci print(" stack-top: %s" % heap.FormatIntPtr(reader.StackTop())) 39571cb0ef41Sopenharmony_ci print(" stack-bottom: %s" % heap.FormatIntPtr(reader.StackBottom())) 39581cb0ef41Sopenharmony_ci print("") 39591cb0ef41Sopenharmony_ci 39601cb0ef41Sopenharmony_ci if options.shell: 39611cb0ef41Sopenharmony_ci padawan.PrintStackTraceMessage(print_message=False) 39621cb0ef41Sopenharmony_ci 39631cb0ef41Sopenharmony_ci print("Disassembly around exception.eip:") 39641cb0ef41Sopenharmony_ci eip_symbol = reader.FindSymbol(reader.ExceptionIP()) 39651cb0ef41Sopenharmony_ci if eip_symbol is not None: 39661cb0ef41Sopenharmony_ci print(eip_symbol) 39671cb0ef41Sopenharmony_ci disasm_start = reader.ExceptionIP() - EIP_PROXIMITY 39681cb0ef41Sopenharmony_ci disasm_bytes = 2 * EIP_PROXIMITY 39691cb0ef41Sopenharmony_ci if (options.full): 39701cb0ef41Sopenharmony_ci full_range = reader.FindRegion(reader.ExceptionIP()) 39711cb0ef41Sopenharmony_ci if full_range is not None: 39721cb0ef41Sopenharmony_ci disasm_start = full_range[0] 39731cb0ef41Sopenharmony_ci disasm_bytes = full_range[1] 39741cb0ef41Sopenharmony_ci 39751cb0ef41Sopenharmony_ci lines = reader.GetDisasmLines(disasm_start, disasm_bytes) 39761cb0ef41Sopenharmony_ci 39771cb0ef41Sopenharmony_ci if not lines: 39781cb0ef41Sopenharmony_ci print("Could not disassemble using %s." % OBJDUMP_BIN) 39791cb0ef41Sopenharmony_ci print("Pass path to architecture specific objdump via --objdump?") 39801cb0ef41Sopenharmony_ci 39811cb0ef41Sopenharmony_ci for line in lines: 39821cb0ef41Sopenharmony_ci print(FormatDisasmLine(disasm_start, heap, line)) 39831cb0ef41Sopenharmony_ci print() 39841cb0ef41Sopenharmony_ci 39851cb0ef41Sopenharmony_ci if heap is None: 39861cb0ef41Sopenharmony_ci heap = V8Heap(reader, None) 39871cb0ef41Sopenharmony_ci 39881cb0ef41Sopenharmony_ci if options.full: 39891cb0ef41Sopenharmony_ci FullDump(reader, heap) 39901cb0ef41Sopenharmony_ci 39911cb0ef41Sopenharmony_ci if options.command: 39921cb0ef41Sopenharmony_ci InspectionShell(reader, heap).onecmd(options.command) 39931cb0ef41Sopenharmony_ci 39941cb0ef41Sopenharmony_ci if options.shell: 39951cb0ef41Sopenharmony_ci try: 39961cb0ef41Sopenharmony_ci InspectionShell(reader, heap).cmdloop("type help to get help") 39971cb0ef41Sopenharmony_ci except KeyboardInterrupt: 39981cb0ef41Sopenharmony_ci print("Kthxbye.") 39991cb0ef41Sopenharmony_ci elif not options.command: 40001cb0ef41Sopenharmony_ci if reader.exception is not None: 40011cb0ef41Sopenharmony_ci print("Annotated stack (from exception.esp to bottom):") 40021cb0ef41Sopenharmony_ci stack_start = padawan.PrintStackTraceMessage() 40031cb0ef41Sopenharmony_ci padawan.InterpretMemory(stack_start, stack_bottom) 40041cb0ef41Sopenharmony_ci 40051cb0ef41Sopenharmony_ci 40061cb0ef41Sopenharmony_ciif __name__ == "__main__": 40071cb0ef41Sopenharmony_ci parser = optparse.OptionParser(USAGE) 40081cb0ef41Sopenharmony_ci parser.add_option("-s", "--shell", dest="shell", action="store_true", 40091cb0ef41Sopenharmony_ci help="start an interactive inspector shell") 40101cb0ef41Sopenharmony_ci parser.add_option("-w", "--web", dest="web", action="store_true", 40111cb0ef41Sopenharmony_ci help="start a web server on localhost:%i" % PORT_NUMBER) 40121cb0ef41Sopenharmony_ci parser.add_option("-c", "--command", dest="command", default="", 40131cb0ef41Sopenharmony_ci help="run an interactive inspector shell command and exit") 40141cb0ef41Sopenharmony_ci parser.add_option("-f", "--full", dest="full", action="store_true", 40151cb0ef41Sopenharmony_ci help="dump all information contained in the minidump") 40161cb0ef41Sopenharmony_ci parser.add_option("--symdir", dest="symdir", default=".", 40171cb0ef41Sopenharmony_ci help="directory containing *.pdb.sym file with symbols") 40181cb0ef41Sopenharmony_ci parser.add_option("--objdump", default="", 40191cb0ef41Sopenharmony_ci help="objdump tool to use [default: %s]" % ( 40201cb0ef41Sopenharmony_ci DEFAULT_OBJDUMP_BIN)) 40211cb0ef41Sopenharmony_ci options, args = parser.parse_args() 40221cb0ef41Sopenharmony_ci if len(args) != 1: 40231cb0ef41Sopenharmony_ci parser.print_help() 40241cb0ef41Sopenharmony_ci sys.exit(1) 40251cb0ef41Sopenharmony_ci if options.web: 40261cb0ef41Sopenharmony_ci try: 40271cb0ef41Sopenharmony_ci server = InspectionWebServer(PORT_NUMBER, options, args[0]) 40281cb0ef41Sopenharmony_ci print('Started httpserver on port ' , PORT_NUMBER) 40291cb0ef41Sopenharmony_ci webbrowser.open('http://localhost:%i/summary.html' % PORT_NUMBER) 40301cb0ef41Sopenharmony_ci server.serve_forever() 40311cb0ef41Sopenharmony_ci except KeyboardInterrupt: 40321cb0ef41Sopenharmony_ci print('^C received, shutting down the web server') 40331cb0ef41Sopenharmony_ci server.socket.close() 40341cb0ef41Sopenharmony_ci else: 40351cb0ef41Sopenharmony_ci AnalyzeMinidump(options, args[0]) 4036