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 29 kSmiTag = 0 30 kSmiTagSize = 1 31 kSmiTagMask = (1 << kSmiTagSize) - 1 32 33 34 kHeapObjectTag = 1 35 kHeapObjectTagSize = 2 36 kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1 37 38 39 kFailureTag = 3 40 kFailureTagSize = 2 41 kFailureTagMask = (1 << kFailureTagSize) - 1 42 43 44 kSmiShiftSize32 = 0 45 kSmiValueSize32 = 31 46 kSmiShiftBits32 = kSmiTagSize + kSmiShiftSize32 47 48 49 kSmiShiftSize64 = 31 50 kSmiValueSize64 = 32 51 kSmiShiftBits64 = kSmiTagSize + kSmiShiftSize64 52 53 54 kAllBits = 0xFFFFFFFF 55 kTopBit32 = 0x80000000 56 kTopBit64 = 0x8000000000000000 57 58 59 t_u32 = gdb.lookup_type('unsigned int') 60 t_u64 = gdb.lookup_type('unsigned long long') 61 62 63 def has_smi_tag(v): 64 return v & kSmiTagMask == kSmiTag 65 66 67 def has_failure_tag(v): 68 return v & kFailureTagMask == kFailureTag 69 70 71 def has_heap_object_tag(v): 72 return v & kHeapObjectTagMask == kHeapObjectTag 73 74 75 def raw_heap_object(v): 76 return v - kHeapObjectTag 77 78 79 def 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 87 def smi_to_int_64(v): 88 return (v >> kSmiShiftBits64) 89 90 91 def 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 106 class 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 123 def 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 130 gdb.pretty_printers.append(v8_pretty_printers) 131 132 133 def 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 142 def v8_get_value(vstring): 143 v = gdb.parse_and_eval(vstring) 144 return v8_to_int(v) 145 146 147 class 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) 154 V8PrintObject() 155