The Sol Programming Language!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

old-sol-gdb.py 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. # GDB Sol extensions
  2. import gdb.printing
  3. import sys
  4. import traceback
  5. class _CatchExceptions(object):
  6. def __init__(self):
  7. self.excs = []
  8. def print_eidx(self, idx):
  9. traceback.print_exception(*self.excs[idx])
  10. def __enter__(self):
  11. pass
  12. def __exit__(self, t, v, tb):
  13. if t is not None:
  14. self.excs.append((t, v, tb))
  15. guard = _CatchExceptions()
  16. class DslArray(gdb.Function):
  17. '''Returns the (DSL_DATATYPE[]) array base of a dsl_array or dsl_seq (if it wraps an array), else NULL'''
  18. def __init__(self):
  19. super(DslArray, self).__init__('dsl_array')
  20. def invoke(self, val):
  21. with guard:
  22. stype = str(val.type)
  23. tp = gdb.lookup_type('sol_object_t').pointer()
  24. if str(val.type).startswith('dsl_seq'):
  25. if str(val['type']) != 'DSL_SEQ_ARRAY':
  26. return gdb.Value(0).cast(tp.pointer())
  27. val = val['array']
  28. if str(val.type).startswith('dsl_array'):
  29. return val['data'].dereference().cast(tp.array(val['len']))
  30. return gdb.Value(0).cast(tp.pointer())
  31. DslArray.instance = DslArray()
  32. class DslLen(gdb.Function):
  33. '''Returns the length of a DSL sequence'''
  34. def __init__(self):
  35. super(DslLen, self).__init__('dsl_array')
  36. def invoke(self, val):
  37. with guard:
  38. stype = str(val.type)
  39. if stype.startswith('dsl_seq'):
  40. return int(gdb.lookup_symbol('dsl_seq_len')[0].value()(val))
  41. if stype.startswith('dsl_array'):
  42. return int(gdb.lookup_symbol('dsl_array_len')[0].value()(val))
  43. if stype.startswith('dsl_list'):
  44. return int(gdb.lookup_symbol('dsl_list_len')[0].value()(val))
  45. return -1
  46. DslLen.instance = DslLen()
  47. class SolObj(gdb.Function):
  48. '''Casts the argument to a sol_object_t *'''
  49. def __init__(self):
  50. super(SolObj, self).__init__('sol_obj')
  51. def invoke(self, val):
  52. with guard:
  53. return val.cast(gdb.lookup_type('sol_object_t').pointer())
  54. SolObj.instance = SolObj()
  55. class SolObjectPrettyPrinter(object):
  56. STYPE_TO_DISPHINT = {
  57. 'SOL_SINGLET': 'string',
  58. 'SOL_INTEGER': 'number',
  59. 'SOL_FLOAT': 'number',
  60. 'SOL_STRING': 'string',
  61. 'SOL_LIST': 'array',
  62. 'SOL_MAP': 'map',
  63. 'SOL_MCELL': 'map',
  64. 'SOL_FUNCTION': 'function',
  65. 'SOL_CFUNCTION': 'function',
  66. 'SOL_STMT': 'syntax',
  67. 'SOL_EXPR': 'syntax',
  68. }
  69. def __init__(self, obj):
  70. self.obj = obj
  71. def display_hint(self):
  72. return self.STYPE_TO_DISPHINT.get(str(self.obj['type']), 'string')
  73. def to_string(self):
  74. with guard:
  75. return getattr(self, 'str_'+str(self.obj['type']), self.str_default)(self.obj)
  76. def str_default(self, obj):
  77. return '<Unknown object %r type %s>'%(obj, str(obj['type']))
  78. def str_SOL_SINGLET(self, obj):
  79. return obj['str']
  80. def str_SOL_INTEGER(self, obj):
  81. return str(obj['ival'])
  82. def str_SOL_FLOAT(self, obj):
  83. return str(obj['fval'])
  84. def str_SOL_STRING(self, obj):
  85. return obj['str']
  86. def str_SOL_LIST(self, obj):
  87. return '[List len=%d]'%(DslLen.instance.invoke(obj['seq']),)
  88. def str_SOL_MAP(self, obj):
  89. return '{Map len=%d}'%(DslLen.instance.invoke(obj['seq']),)
  90. def str_SOL_MCELL(self, obj):
  91. return '<{[%s] = %s}>'%(SolObjectPrettyPrinter(obj['key']).to_string(), SolObjectPrettyPrinter(obj['val']).to_string())
  92. def str_SOL_FUNCTION(self, obj):
  93. return '<Function %s>'%(obj['fname'],)
  94. def str_SOL_CFUNCTION(self, obj):
  95. return '<CFunction %r>'%(obj['cfunc'],)
  96. def str_SOL_STMT(self, obj):
  97. return str(obj['node'].cast(gdb.lookup_type('stmt_node').pointer())['type'])
  98. def str_SOL_EXPR(self, obj):
  99. return str(obj['node'].cast(gdb.lookup_type('expr_node').pointer())['type'])
  100. def children(self):
  101. with guard:
  102. stype = str(self.obj['type'])
  103. if stype in ('SOL_LIST', 'SOL_MAP'):
  104. if str(self.obj['seq']['type']) == 'DSL_SEQ_ARRAY':
  105. tp = gdb.lookup_type('sol_object_t').pointer()
  106. lseq = DslLen.instance.invoke(self.obj['seq'])
  107. arr = self.obj['seq']['array']['data'].dereference().cast(tp.array(lseq))
  108. if stype == 'SOL_LIST':
  109. return [(str(i), arr[i]) for i in range(lseq)]
  110. else:
  111. return sum([[(str(i)+'k', arr[i]['key']), (str(i)+'v', arr[i]['val'])] for i in range(lseq)], [])
  112. if stype == 'SOL_FUNCTION':
  113. return [('stmt', self.obj['func'].cast(gdb.lookup_type('stmt_node').pointer))]
  114. return []
  115. @classmethod
  116. def check_printable(cls, obj):
  117. with guard:
  118. stype = str(obj.type)
  119. if stype.startswith('sol_object_t') or stype.startswith('struct sol_tag_object_t'):
  120. return cls(obj)
  121. return None
  122. # pp = gdb.printing.RegexpCollectionPrettyPrinter('Sol')
  123. # pp.add_printer('sol_object_t', '^sol_object_t.*$', SolObjectPrettyPrinter)
  124. # pp.add_printer('sol_tag_object_t', '^struct sol_tag_object_t.*$', SolObjectPrettyPrinter)
  125. # gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)
  126. gdb.pretty_printers.append(SolObjectPrettyPrinter.check_printable)
  127. print('Sol extensions loaded!')