mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 09:30:44 +00:00
095556663d
* These are not as good as natvis but better than nothing... maybe
224 lines
8.9 KiB
Python
224 lines
8.9 KiB
Python
import re
|
|
|
|
class _childplusextras_iterator():
|
|
def __init__(self, extras, elems, usedCount):
|
|
self.extras = extras
|
|
self.elems = elems
|
|
self.usedCount = usedCount
|
|
self.i = 0
|
|
|
|
def __iter__(self):
|
|
return self
|
|
|
|
def __next__(self):
|
|
if len(self.extras) > 0:
|
|
return self.extras.pop(0)
|
|
|
|
if self.i >= self.usedCount:
|
|
raise StopIteration
|
|
ret = ('[{}]'.format(self.i), self.elems[self.i])
|
|
|
|
self.i = self.i + 1
|
|
return ret
|
|
|
|
class rdcstrPrinter(object):
|
|
def __init__(self, val):
|
|
self.val = val
|
|
|
|
def to_string(self):
|
|
if self.val['d']['fixed']['flags'] & int(self.val['FIXED_STATE']):
|
|
return self.val['d']['fixed']['str']
|
|
if self.val['d']['fixed']['flags'] & int(self.val['ALLOC_STATE']):
|
|
return self.val['d']['alloc']['str']
|
|
return self.val['d']['arr']['str'].cast(gdb.lookup_type("char").pointer())
|
|
|
|
def display_hint(self):
|
|
return 'string'
|
|
|
|
class rdcinflexiblestrPrinter(object):
|
|
def __init__(self, val):
|
|
self.val = val
|
|
|
|
def to_string(self):
|
|
return self.val['pointer'].cast(gdb.lookup_type("char").pointer())
|
|
|
|
def display_hint(self):
|
|
return 'string'
|
|
|
|
class rdcarrayPrinter(object):
|
|
def __init__(self, val):
|
|
self.val = val
|
|
|
|
def children(self):
|
|
return _childplusextras_iterator([], self.val['elems'], self.val['usedCount'])
|
|
|
|
def to_string(self):
|
|
return None
|
|
|
|
def display_hint(self):
|
|
return 'array'
|
|
|
|
class rdcpairPrinter(object):
|
|
def __init__(self, val):
|
|
self.val = val
|
|
|
|
def children(self):
|
|
return [('first', self.val['first']), ('second', self.val['second'])]
|
|
|
|
def to_string(self):
|
|
return ('{{ {}, {} }}'.format(self.val['first'], self.val['second']))
|
|
|
|
class rdcbytetrieNodePrinter(object):
|
|
def __init__(self, val):
|
|
self.val = val
|
|
self.nodeSize = self.val['v']['_trie'] & int(0xC000)
|
|
self.trietype = self.val.type.name.replace('::NodeOrLeaf', '')
|
|
|
|
def children(self):
|
|
ret = []
|
|
|
|
prefixLen = self.val['v']['_trie'] & int(0x1FFF)
|
|
prefixName = '{} byte prefix'.format(prefixLen)
|
|
thisPtr = int(self.val.address)
|
|
prefixValue = thisPtr + self.val.type.sizeof
|
|
prefixValue = gdb.Value(prefixValue).cast(gdb.lookup_type("byte").pointer())
|
|
|
|
ret.append((prefixName, prefixValue))
|
|
|
|
if self.val['v']['_trie'] & int(0x2000):
|
|
ret.append(('value', self.val['v']))
|
|
|
|
if self.nodeSize == 0xC000:
|
|
ret.append(('children', gdb.Value(thisPtr).cast(gdb.lookup_type(self.trietype + "::FatNode").pointer()).dereference()['children']))
|
|
elif self.nodeSize == 0x8000:
|
|
ret.append(('children', gdb.Value(thisPtr).cast(gdb.lookup_type(self.trietype + "::SmallNode<(unsigned char)'\\b'>").pointer()).dereference()['children']))
|
|
ret.append(('childBytes', gdb.Value(thisPtr).cast(gdb.lookup_type(self.trietype + "::SmallNode<(unsigned char)'\\b'>").pointer()).dereference()['childBytes']))
|
|
elif self.nodeSize == 0x4000:
|
|
ret.append(('children', gdb.Value(thisPtr).cast(gdb.lookup_type(self.trietype + "::SmallNode<(unsigned char)'\\x02'>").pointer()).dereference()['children']))
|
|
ret.append(('childBytes', gdb.Value(thisPtr).cast(gdb.lookup_type(self.trietype + "::SmallNode<(unsigned char)'\\x02'>").pointer()).dereference()['childBytes']))
|
|
|
|
return ret
|
|
|
|
def to_string(self):
|
|
if self.val['v']['_trie'] & int(0x2000):
|
|
if self.nodeSize == 0xC000:
|
|
return 'FatNode = {}'.format(self.val['v'])
|
|
elif self.nodeSize == 0x8000:
|
|
return 'Node8 = {}'.format(self.val['v'])
|
|
elif self.nodeSize == 0x4000:
|
|
return 'Node2 = {}'.format(self.val['v'])
|
|
else:
|
|
if self.nodeSize == 0xC000:
|
|
return 'FatNode without value'
|
|
elif self.nodeSize == 0x8000:
|
|
return 'Node8 without value'
|
|
elif self.nodeSize == 0x4000:
|
|
return 'Node2 without value'
|
|
|
|
return 'Leaf = {}'.format(self.val['v'])
|
|
|
|
|
|
class sdtypePrinter(object):
|
|
def __init__(self, val):
|
|
self.val = val
|
|
|
|
def children(self):
|
|
return [
|
|
('name', self.val['name']),
|
|
('basetype', self.val['basetype']),
|
|
('byteSize', self.val['byteSize']),
|
|
('flags', self.val['flags']),
|
|
]
|
|
|
|
def to_string(self):
|
|
return str(self.val['name'])
|
|
|
|
class sdobjectPrinter(object):
|
|
def __init__(self, val):
|
|
self.val = val
|
|
|
|
def children(self):
|
|
if (self.val['type']['basetype'] == int(gdb.lookup_type('SDBasic')['SDBasic::Array'].enumval) or \
|
|
self.val['type']['basetype'] == int(gdb.lookup_type('SDBasic')['SDBasic::Struct'].enumval)):
|
|
return _childplusextras_iterator([], self.val['data']['children']['elems'], self.val['data']['children']['usedCount'])
|
|
else:
|
|
return [
|
|
('type', self.val['type']),
|
|
('name', self.val['name']),
|
|
('data', self.val['data']),
|
|
]
|
|
|
|
def to_string(self):
|
|
if self.val['type']['flags'] & int(gdb.lookup_type('SDTypeFlags')['SDTypeFlags::HasCustomString'].enumval):
|
|
return '{} = {}'.format(self.val['name'], self.val['data']['str'])
|
|
if self.val['type']['basetype'] == int(gdb.lookup_type('SDBasic')['SDBasic::String'].enumval):
|
|
return '{} = {}'.format(self.val['name'], self.val['data']['str'])
|
|
if self.val['type']['basetype'] == int(gdb.lookup_type('SDBasic')['SDBasic::UnsignedInteger'].enumval):
|
|
return '{} = {}'.format(self.val['name'], self.val['data']['u'])
|
|
if self.val['type']['basetype'] == int(gdb.lookup_type('SDBasic')['SDBasic::SignedInteger'].enumval):
|
|
return '{} = {}'.format(self.val['name'], self.val['data']['i'])
|
|
if self.val['type']['basetype'] == int(gdb.lookup_type('SDBasic')['SDBasic::Float'].enumval):
|
|
return '{} = {}'.format(self.val['name'], self.val['data']['d'])
|
|
if self.val['type']['basetype'] == int(gdb.lookup_type('SDBasic')['SDBasic::Boolean'].enumval):
|
|
return '{} = {}'.format(self.val['name'], self.val['data']['b'])
|
|
if self.val['type']['basetype'] == int(gdb.lookup_type('SDBasic')['SDBasic::Character'].enumval):
|
|
return '{} = {}'.format(self.val['name'], self.val['data']['c'])
|
|
if self.val['type']['basetype'] == int(gdb.lookup_type('SDBasic')['SDBasic::Resource'].enumval):
|
|
return '{} = {}'.format(self.val['name'], self.val['data']['id'])
|
|
if self.val['type']['basetype'] == int(gdb.lookup_type('SDBasic')['SDBasic::Array'].enumval):
|
|
return '{} = {}[]'.format(self.val['name'], self.val['type']['name'])
|
|
return 'SDObject: {} {}'.format(self.val['type']['name'], self.val['name'])
|
|
|
|
|
|
class sdchunkPrinter(object):
|
|
def __init__(self, val):
|
|
self.val = val
|
|
|
|
def children(self):
|
|
return _childplusextras_iterator([('metadata', self.val['metadata'])], self.val['data']['children']['elems'], self.val['data']['children']['usedCount'])
|
|
|
|
def to_string(self):
|
|
return ('SDChunk: {} ({})'.format(self.val['name'], self.val['metadata']['chunkID']))
|
|
|
|
class sdchunkPtrPrinter(sdchunkPrinter):
|
|
def __init__(self, val):
|
|
self.val = val.dereference()
|
|
|
|
class sdobjectPtrPrinter(sdobjectPrinter):
|
|
def __init__(self, val):
|
|
self.val = val.dereference()
|
|
|
|
class rdcbytetrieNodePtrPrinter(rdcbytetrieNodePrinter):
|
|
def __init__(self, val):
|
|
self.val = val.dereference()
|
|
self.nodeSize = self.val['v']['_trie'] & int(0xC000)
|
|
self.trietype = self.val.type.name.replace('::NodeOrLeaf', '')
|
|
|
|
import gdb.printing
|
|
|
|
def register(objfile):
|
|
"""Register the pretty printers within the given objfile."""
|
|
|
|
printer = gdb.printing.RegexpCollectionPrettyPrinter('renderdoc')
|
|
|
|
printer.add_printer('rdcstr', r'^rdcstr$', rdcstrPrinter)
|
|
printer.add_printer('rdcinflexiblestr', r'^rdcinflexiblestr$', rdcinflexiblestrPrinter)
|
|
printer.add_printer('rdcarray', r'^rdcarray<.*>$', rdcarrayPrinter)
|
|
printer.add_printer('rdcpair', r'^rdcpair<.*>$', rdcpairPrinter)
|
|
printer.add_printer('rdcbytetrie', r'^rdcbytetrie<.*>::NodeOrLeaf$', rdcbytetrieNodePrinter)
|
|
|
|
printer.add_printer('SDType', r'^SDType$', sdtypePrinter)
|
|
printer.add_printer('SDObject', r'^SDObject$', sdobjectPrinter)
|
|
printer.add_printer('SDChunk', r'^SDChunk$', sdchunkPrinter)
|
|
|
|
printer.add_printer('SDObjectPtr', r'^SDObject *\*&?$', sdobjectPtrPrinter)
|
|
printer.add_printer('SDChunkPtr', r'^SDChunk *\*&?$', sdchunkPtrPrinter)
|
|
printer.add_printer('rdcbytetriePtr', r'^rdcbytetrie<.*>::NodeOrLeaf *\*&?$', rdcbytetrieNodePtrPrinter)
|
|
|
|
if objfile == None:
|
|
objfile = gdb
|
|
|
|
gdb.printing.register_pretty_printer(objfile, printer)
|
|
|
|
register(gdb.current_objfile())
|