mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 01:20:42 +00:00
Try to improve linux pretty printers as much as possible
* These are not as good as natvis but better than nothing... maybe
This commit is contained in:
@@ -1,42 +1,56 @@
|
||||
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'] & 0xC000000000000000:
|
||||
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 rdcarrayPrinter(object):
|
||||
class _iterator():
|
||||
def __init__(self, value_type, elems, usedCount):
|
||||
self.value_type = value_type
|
||||
self.elems = elems
|
||||
self.usedCount = usedCount
|
||||
self.i = 0
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
if self.i >= self.usedCount:
|
||||
raise StopIteration
|
||||
ret = ('[{}]'.format(self.i), self.elems[self.i])
|
||||
|
||||
self.i = self.i + 1
|
||||
return ret
|
||||
|
||||
class rdcinflexiblestrPrinter(object):
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
self.value_type = self.val.type.template_argument(0)
|
||||
|
||||
|
||||
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 self._iterator(self.value_type, self.val['elems'], self.val['usedCount'])
|
||||
return _childplusextras_iterator([], self.val['elems'], self.val['usedCount'])
|
||||
|
||||
def to_string(self):
|
||||
return None
|
||||
@@ -44,6 +58,142 @@ class rdcarrayPrinter(object):
|
||||
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):
|
||||
@@ -52,7 +202,18 @@ def register(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
|
||||
|
||||
Reference in New Issue
Block a user