mirror of
https://git.rtems.org/rtems-tools/
synced 2025-05-14 06:29:26 +08:00

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.
298 lines
9.2 KiB
Python
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()
|