diff options
author | Dhananjay Balan <mb.dhananjay@gmail.com> | 2013-06-17 22:40:17 +0530 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2014-08-25 09:52:40 +1000 |
commit | 56a70aec5536a568fe302a3c84b349fcf17db2fa (patch) | |
tree | 0f1043e21f214f7e3b3d1063f446073980859c15 /tools/gdb/python/objects.py | |
parent | Initial commit (diff) | |
download | rtems-tools-56a70aec5536a568fe302a3c84b349fcf17db2fa.tar.bz2 |
Intial commit.
Chris's intial work on the extenstions.
Diffstat (limited to 'tools/gdb/python/objects.py')
-rw-r--r-- | tools/gdb/python/objects.py | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/tools/gdb/python/objects.py b/tools/gdb/python/objects.py new file mode 100644 index 0000000..22d2b2c --- /dev/null +++ b/tools/gdb/python/objects.py @@ -0,0 +1,357 @@ +# +# RTEMS Objects Support +# Copyright 2010 Chris Johns (chrisj@rtems.org) +# +# $Id$ +# + +import gdb +import itertools +import re + +class infotables: + """Manage the object information tables.""" + + tables_types = { + 'classic/tasks' : ('Thread_Control', '_RTEMS_tasks_Information'), + 'classic/timers' : ('Timer_Control', '_Timers_Information'), + 'classic/semaphores' : ('Semaphore_Control', '_Semaphore_Information'), + 'classic/message_queues' : ('Message_queue_Control', '_Message_queue_Information'), + 'classic/partitions' : ('Partition_Control', '_Partition_Information'), + 'classic/regions' : ('Region_Control', '_Regions_Information'), + 'classic/ports' : ('Port_Control', '_Port_Information'), + 'classic/periods' : ('Period_Control', '_Period_Information'), + 'classic/extensions' : ('Extension_Control', '_Extension_Information'), + 'classic/barriers' : ('Barrier_Control', '_Barrier_Information') + } + + def __init__(self): + self.invalidate() + + def invalidate(self): + self.tables = {} + + def name(self, api, _class): + return api + '/' + _class + + def load(self, n): + if n in self.tables_types: + if n not in self.tables: + self.tables[n] = gdb.parse_and_eval(self.tables_types[n][1]) + + def get(self, api, _class): + n = self.name(api, _class) + self.load(n) + if n in self.tables: + return self.tables[n] + return None + + def maximum(self, api, _class): + n = self.name(api, _class) + self.load(n) + return int(self.tables[n]['maximum']) + + def object(self, id): + if type(id) == gdb.Value: + id = ident(id) + if type(id) == tuple: + api = id[0] + _class = id[1] + index = id[2] + else: + api = id.api() + _class = id._class() + index = id.index() + n = self.name(api, _class) + self.load(n) + max = self.maximum(api, _class) + if index >= max: + raise IndexError('object index out of range (%d)' % (max)) + table_type = self.tables_types[n] + expr = '(' + table_type[0] + '*)' + \ + table_type[1] + '.local_table[' + str(index) + ']' + return gdb.parse_and_eval(expr) + + def is_string(self, api, _class): + n = self.name(api, _class) + self.load(n) + if n in self.tables: + if self.tables[n]['is_string']: + return True + return False + +# +# Global info tables. These are global in the target. +# +information = infotables() + +class ident: + "An RTEMS object id with support for its bit fields." + + bits = [ + { 'index': (0, 15), + 'node': (0, 0), + 'api': (8, 10), + 'class': (11, 15) }, + { 'index': (0, 15), + 'node': (16, 23), + 'api': (24, 26), + 'class': (27, 31) } + ] + + OBJECT_16_BITS = 0 + OBJECT_31_BITS = 1 + + api_labels = [ + 'none', + 'internal', + 'classic', + 'posix', + 'itron' + ] + + class_labels = { + 'internal' : ('threads', + 'mutexes'), + 'classic' : ('none', + 'tasks', + 'timers', + 'semaphores', + 'message_queues', + 'partitions', + 'regions', + 'ports', + 'periods', + 'extensions', + 'barriers'), + 'posix' : ('none', + 'threads', + 'keys', + 'interrupts', + 'message_queue_fds', + 'message_queues', + 'mutexes', + 'semaphores', + 'condition_variables', + 'timers', + 'barriers', + 'spinlocks', + 'rwlocks'), + 'itron' : ('none', + 'tasks', + 'eventflags', + 'mailboxes', + 'message_buffers', + 'ports', + 'semaphores', + 'variable_memory_pools', + 'fixed_memory_pools') + } + + def __init__(self, id): + if type(id) != gdb.Value and type(id) != int and type(id) != unicode: + raise TypeError('%s: must be gdb.Value, int, unicoded int' % (type(id))) + if type(id) == int: + id = gdb.Value(id) + self.id = id + if self.id.type.sizeof == 2: + self.idSize = self.OBJECT_16_BITS + else: + self.idSize = self.OBJECT_31_BITS + + def get(self, field): + if field in self.bits[self.idSize]: + bits = self.bits[self.idSize][field] + if bits[1] > 0: + return (int(self.id) >> bits[0]) & ((1 << (bits[1] - bits[0] + 1)) - 1) + return 0 + + def value(self): + return int(self.id) + + def index(self): + return self.get('index') + + def node(self): + return self.get('node') + + def api_val(self): + return self.get('api') + + def class_val(self): + return self.get('class') + + def api(self): + api = self.api_val() + if api < len(self.api_labels): + return self.api_labels[api] + return 'none' + + def _class(self): + api = self.api() + if api == 'none': + return 'invalid' + _class = self.class_val() + if _class < len(self.class_labels[api]): + return self.class_labels[api][_class] + return 'invalid' + + def valid(self): + return self.api() != 'none' and self._class() != 'invalid' + +class name: + """The Objects_Name can either be told what the name is or can take a + guess.""" + + def __init__(self, name, is_string = None): + self.name = name + if is_string == None: + self.is_string = 'auto' + else: + if is_string: + self.is_string = 'yes' + else: + self.is_string = 'no' + + def __str__(self): + if self.is_string != 'yes': + u32 = int(self.name['name_u32']) + s = chr((u32 >> 24) & 0xff) + \ + chr((u32 >> 16) & 0xff) + chr((u32 >> 8) & 0xff) + \ + chr(u32 & 0xff) + for c in range(0,4): + if s[c] < ' ' or s[c] > '~': + s = None + break + if s: + return s + return str(self.name['name_p'].dereference()) + +class control: + """The Objects_Control structure.""" + + def __init__(self, object): + self.object = object + self._id = ident(self.object['id']) + + def node(self): + return self.object['Node'] + + def id(self): + return self.object['id'] + + def name(self): + is_string = information.is_string(self._id.api(), self._id._class()) + return str(name(self.object['name'], is_string)) + +class id_printer: + """Print an object given the ID. Print using the struct display hint and an + iterator.""" + + class iterator: + """Use an iterator for each field expanded from the id so GDB output + is formatted correctly.""" + + def __init__(self, id): + self.id = id + self.count = 0 + + def __iter__(self): + return self + + def next(self): + self.count += 1 + if self.count == 1: + return int(self.id.value()) + elif self.count == 2: + return self.id.node() + elif self.count == 3: + return self.id.api() + elif self.count == 4: + return self.id._class() + elif self.count == 5: + return self.id.index() + raise StopIteration + + def __init__(self, id): + self.id = ident(id) + + def to_string(self): + return '' + + @staticmethod + def key(i): + if i == 0: + return 'id' + elif i == 1: + return 'node' + elif i == 2: + return 'api' + elif i == 3: + return 'class' + elif i == 4: + return 'index' + return 'bad' + + def children(self): + counter = itertools.imap (self.key, itertools.count()) + return itertools.izip (counter, self.iterator(self.id)) + + def display_hint (self): + return 'struct' + +class name_printer: + """Pretty printer for an object's name. It has to guess the type as no + information is available to help determine it.""" + + def __init__(self, name): + self.name = name(name) + + def to_string(self): + return gdb.Value(str(self.name)) + +class control_printer: + + class iterator: + """Use an iterator for each field expanded from the id so GDB output + is formatted correctly.""" + + def __init__(self, object): + self.object = object + self.count = 0 + + def __iter__(self): + return self + + def next(self): + self.count += 1 + if self.count == 1: + return self.object.node() + elif self.count == 2: + return self.object.id() + elif self.count == 3: + return self.object.name() + raise StopIteration + + def to_string(self): + return '' + + def __init__(self, object): + self.object = control(object) + + @staticmethod + def key(i): + if i == 0: + return 'Node' + elif i == 1: + return 'id' + elif i == 2: + return 'name' + return 'bad' + + def children(self): + counter = itertools.imap (self.key, itertools.count()) + return itertools.izip (counter, self.iterator(self.object)) + + def display_hint (self): + return 'struct' |