diff --git a/renderdoc/librenderdoc.so-gdb.py b/renderdoc/librenderdoc.so-gdb.py index 87dd43791..0958ed721 100644 --- a/renderdoc/librenderdoc.so-gdb.py +++ b/renderdoc/librenderdoc.so-gdb.py @@ -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