13fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# Copyright 2011 the V8 project authors. All rights reserved.
23fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# Redistribution and use in source and binary forms, with or without
33fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# modification, are permitted provided that the following conditions are
43fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# met:
53fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#
63fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#     * Redistributions of source code must retain the above copyright
73fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#       notice, this list of conditions and the following disclaimer.
83fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#     * Redistributions in binary form must reproduce the above
93fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#       copyright notice, this list of conditions and the following
103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#       disclaimer in the documentation and/or other materials provided
113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#       with the distribution.
123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#     * Neither the name of Google Inc. nor the names of its
133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#       contributors may be used to endorse or promote products derived
143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#       from this software without specific prior written permission.
153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#
163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochimport re
293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
303fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkSmiTag = 0
313fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkSmiTagSize = 1
323fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkSmiTagMask = (1 << kSmiTagSize) - 1
333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
353fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkHeapObjectTag = 1
363fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkHeapObjectTagSize = 2
373fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1
383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
403fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkFailureTag = 3
413fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkFailureTagSize = 2
423fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkFailureTagMask = (1 << kFailureTagSize) - 1
433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
453fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkSmiShiftSize32 = 0
463fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkSmiValueSize32 = 31
473fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkSmiShiftBits32 = kSmiTagSize + kSmiShiftSize32
483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
503fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkSmiShiftSize64 = 31
513fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkSmiValueSize64 = 32
523fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkSmiShiftBits64 = kSmiTagSize + kSmiShiftSize64
533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
553fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkAllBits = 0xFFFFFFFF
563fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkTopBit32 = 0x80000000
573fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochkTopBit64 = 0x8000000000000000
583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdocht_u32 = gdb.lookup_type('unsigned int')
613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdocht_u64 = gdb.lookup_type('unsigned long long')
623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochdef has_smi_tag(v):
653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return v & kSmiTagMask == kSmiTag
663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochdef has_failure_tag(v):
693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return v & kFailureTagMask == kFailureTag
703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochdef has_heap_object_tag(v):
733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return v & kHeapObjectTagMask == kHeapObjectTag
743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochdef raw_heap_object(v):
773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return v - kHeapObjectTag
783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochdef smi_to_int_32(v):
813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  v = v & kAllBits
823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (v & kTopBit32) == kTopBit32:
833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return ((v & kAllBits) >> kSmiShiftBits32) - 2147483648
843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  else:
853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return (v & kAllBits) >> kSmiShiftBits32
863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochdef smi_to_int_64(v):
893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return (v >> kSmiShiftBits64)
903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochdef decode_v8_value(v, bitness):
933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  base_str = 'v8[%x]' % v
943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if has_smi_tag(v):
953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if bitness == 32:
963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return base_str + (" SMI(%d)" % smi_to_int_32(v))
973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    else:
983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return base_str + (" SMI(%d)" % smi_to_int_64(v))
993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  elif has_failure_tag(v):
1003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return base_str + " (failure)"
1013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  elif has_heap_object_tag(v):
1023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return base_str + (" H(0x%x)" % raw_heap_object(v))
1033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  else:
1043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return base_str
1053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass V8ValuePrinter(object):
1083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  "Print a v8value."
1093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  def __init__(self, val):
1103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    self.val = val
1113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  def to_string(self):
1123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if self.val.type.sizeof == 4:
1133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      v_u32 = self.val.cast(t_u32)
1143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return decode_v8_value(int(v_u32), 32)
1153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    elif self.val.type.sizeof == 8:
1163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      v_u64 = self.val.cast(t_u64)
1173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return decode_v8_value(int(v_u64), 64)
1183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    else:
1193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return 'v8value?'
1203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  def display_hint(self):
1213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return 'v8value'
1223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochdef v8_pretty_printers(val):
1253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  lookup_tag = val.type.tag
1263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if lookup_tag == None:
1273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return None
1283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  elif lookup_tag == 'v8value':
1293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return V8ValuePrinter(val)
1303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return None
1313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochgdb.pretty_printers.append(v8_pretty_printers)
1323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochdef v8_to_int(v):
1353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if v.type.sizeof == 4:
1363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return int(v.cast(t_u32))
1373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  elif v.type.sizeof == 8:
1383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return int(v.cast(t_u64))
1393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  else:
1403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return '?'
1413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
142589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochdef v8_get_value(vstring):
1443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  v = gdb.parse_and_eval(vstring)
1453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return v8_to_int(v)
1463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass V8PrintObject (gdb.Command):
1493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  """Prints a v8 object."""
1503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  def __init__ (self):
1513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    super (V8PrintObject, self).__init__ ("v8print", gdb.COMMAND_DATA)
1523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  def invoke (self, arg, from_tty):
1533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    v = v8_get_value(arg)
1543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    gdb.execute('call __gdb_print_v8_object(%d)' % v)
1553fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochV8PrintObject()
156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass FindAnywhere (gdb.Command):
159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  """Search memory for the given pattern."""
160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MAPPING_RE = re.compile(r"^\s*\[\d+\]\s+0x([0-9A-Fa-f]+)->0x([0-9A-Fa-f]+)")
161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LIVE_MAPPING_RE = re.compile(r"^\s+0x([0-9A-Fa-f]+)\s+0x([0-9A-Fa-f]+)")
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  def __init__ (self):
163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    super (FindAnywhere, self).__init__ ("find-anywhere", gdb.COMMAND_DATA)
164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  def find (self, startAddr, endAddr, value):
165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    try:
166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      result = gdb.execute(
167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          "find 0x%s, 0x%s, %s" % (startAddr, endAddr, value),
168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          to_string = True)
169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if result.find("not found") == -1:
170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        print(result)
171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    except:
172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      pass
173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  def invoke (self, value, from_tty):
175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for l in gdb.execute("maint info sections", to_string = True).split('\n'):
176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      m = FindAnywhere.MAPPING_RE.match(l)
177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if m is None:
178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        continue
179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      self.find(m.group(1), m.group(2), value)
180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for l in gdb.execute("info proc mappings", to_string = True).split('\n'):
181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      m = FindAnywhere.LIVE_MAPPING_RE.match(l)
182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if m is None:
183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        continue
184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      self.find(m.group(1), m.group(2), value)
185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochFindAnywhere()
187