1# Copyright 2011 the V8 project authors. All rights reserved. 2# Redistribution and use in source and binary forms, with or without 3# modification, are permitted provided that the following conditions are 4# met: 5# 6# * Redistributions of source code must retain the above copyright 7# notice, this list of conditions and the following disclaimer. 8# * Redistributions in binary form must reproduce the above 9# copyright notice, this list of conditions and the following 10# disclaimer in the documentation and/or other materials provided 11# with the distribution. 12# * Neither the name of Google Inc. nor the names of its 13# contributors may be used to endorse or promote products derived 14# from this software without specific prior written permission. 15# 16# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 29kSmiTag = 0 30kSmiTagSize = 1 31kSmiTagMask = (1 << kSmiTagSize) - 1 32 33 34kHeapObjectTag = 1 35kHeapObjectTagSize = 2 36kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1 37 38 39kFailureTag = 3 40kFailureTagSize = 2 41kFailureTagMask = (1 << kFailureTagSize) - 1 42 43 44kSmiShiftSize32 = 0 45kSmiValueSize32 = 31 46kSmiShiftBits32 = kSmiTagSize + kSmiShiftSize32 47 48 49kSmiShiftSize64 = 31 50kSmiValueSize64 = 32 51kSmiShiftBits64 = kSmiTagSize + kSmiShiftSize64 52 53 54kAllBits = 0xFFFFFFFF 55kTopBit32 = 0x80000000 56kTopBit64 = 0x8000000000000000 57 58 59t_u32 = gdb.lookup_type('unsigned int') 60t_u64 = gdb.lookup_type('unsigned long long') 61 62 63def has_smi_tag(v): 64 return v & kSmiTagMask == kSmiTag 65 66 67def has_failure_tag(v): 68 return v & kFailureTagMask == kFailureTag 69 70 71def has_heap_object_tag(v): 72 return v & kHeapObjectTagMask == kHeapObjectTag 73 74 75def raw_heap_object(v): 76 return v - kHeapObjectTag 77 78 79def smi_to_int_32(v): 80 v = v & kAllBits 81 if (v & kTopBit32) == kTopBit32: 82 return ((v & kAllBits) >> kSmiShiftBits32) - 2147483648 83 else: 84 return (v & kAllBits) >> kSmiShiftBits32 85 86 87def smi_to_int_64(v): 88 return (v >> kSmiShiftBits64) 89 90 91def decode_v8_value(v, bitness): 92 base_str = 'v8[%x]' % v 93 if has_smi_tag(v): 94 if bitness == 32: 95 return base_str + (" SMI(%d)" % smi_to_int_32(v)) 96 else: 97 return base_str + (" SMI(%d)" % smi_to_int_64(v)) 98 elif has_failure_tag(v): 99 return base_str + " (failure)" 100 elif has_heap_object_tag(v): 101 return base_str + (" H(0x%x)" % raw_heap_object(v)) 102 else: 103 return base_str 104 105 106class V8ValuePrinter(object): 107 "Print a v8value." 108 def __init__(self, val): 109 self.val = val 110 def to_string(self): 111 if self.val.type.sizeof == 4: 112 v_u32 = self.val.cast(t_u32) 113 return decode_v8_value(int(v_u32), 32) 114 elif self.val.type.sizeof == 8: 115 v_u64 = self.val.cast(t_u64) 116 return decode_v8_value(int(v_u64), 64) 117 else: 118 return 'v8value?' 119 def display_hint(self): 120 return 'v8value' 121 122 123def v8_pretty_printers(val): 124 lookup_tag = val.type.tag 125 if lookup_tag == None: 126 return None 127 elif lookup_tag == 'v8value': 128 return V8ValuePrinter(val) 129 return None 130gdb.pretty_printers.append(v8_pretty_printers) 131 132 133def v8_to_int(v): 134 if v.type.sizeof == 4: 135 return int(v.cast(t_u32)) 136 elif v.type.sizeof == 8: 137 return int(v.cast(t_u64)) 138 else: 139 return '?' 140 141 142def v8_get_value(vstring): 143 v = gdb.parse_and_eval(vstring) 144 return v8_to_int(v) 145 146 147class V8PrintObject (gdb.Command): 148 """Prints a v8 object.""" 149 def __init__ (self): 150 super (V8PrintObject, self).__init__ ("v8print", gdb.COMMAND_DATA) 151 def invoke (self, arg, from_tty): 152 v = v8_get_value(arg) 153 gdb.execute('call __gdb_print_v8_object(%d)' % v) 154V8PrintObject() 155