Chris Johns 3162858a3a gdb-python: Update so 'rtems task' lists the classic tasks.
This is a first pass at cleaning up the support. To use:

 $ waf configure --prefix=$HOME/development/rtems/4.11
 $ waf build install

Start GDB and break at Init:

 (gdb) py import rtems
 (gdb) rtems task

will list the classic API tasks.
2014-08-26 14:57:57 +10:00

298 lines
9.2 KiB
Python

# RTEMS Tools Project (http://www.rtems.org/)
# Copyright 2010-2014 Chris Johns (chrisj@rtems.org)
# All rights reserved.
#
# This file is part of the RTEMS Tools package in 'rtems-tools'.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
#
# RTEMS Objects Support
#
import gdb
import itertools
import re
class infotables():
"""Manage the object information tables."""
tables_types = {
'internal/time' : ('TOD_Control', '_TOD'),
'internal/wdticks' : ('Chain_Control', '_Watchdog_Ticks_chain'),
'internal/wdseconds' : ('Chain_Control', '_Watchdog_Seconds_chain'),
'classic/tasks' : ('Thread_Control', '_RTEMS_tasks_Information'),
'classic/timers' : ('Timer_Control', '_Timer_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', '_Region_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 '%s/%s' % (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 minimum_id(self, api, _class):
n = self.name(api, _class)
self.load(n)
return int(self.tables[n]['minimum_id'])
def maximum_id(self, api, _class):
n = self.name(api, _class)
self.load(n)
return int(self.tables[n]['maximum_id'])
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()
return self.object_return(api, _class, index)
def object_return(self, api, _class, index=-1):
n = self.name(api, _class)
self.load(n)
table_type = self.tables_types[n]
if api == 'internal':
expr = '(%s) %s' % (table_type[0], table_type[1])
else:
max = self.maximum(api, _class)
if index > max:
raise IndexError('object index out of range (%d)' % (max))
expr = '(%s*) %s.local_table[%d]' % (table_type[0], table_type[1], 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_32_BITS = 1
api_labels = [
'none',
'internal',
'classic',
'posix'
]
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'),
}
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_32_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'
try:
self.name_p = self.name['name_p']
except gdb.Error:
self.is_string = 'no'
else:
if is_string:
self.is_string = 'yes'
else:
self.is_string = 'no'
def __str__(self):
return self.get()
def get(self):
if self.is_string != 'yes':
u32 = int(self.name['name_u32'])
if u32 != 0:
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
if self.is_string == 'xno':
return None
try:
name_p = self.name['name_p']
return str(name_p.dereference())
except gdb.Error:
pass
return None
class control():
"""The Objects_Control structure."""
def __init__(self, object):
self.object = object
self._id = ident(self.object['id'])
self._name = name(self.object['name'],
information.is_string(self._id.api(), self._id._class()))
def node(self):
return self.object['Node']
def id(self):
return self.object['id']
def name(self):
return self._name.get()