source: rtems-tools/tools/gdb/python/objects.py @ b117be8

4.104.115
Last change on this file since b117be8 was 3162858, checked in by Chris Johns <chrisj@…>, on 08/26/14 at 04:57:57

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.

  • Property mode set to 100644
File size: 9.2 KB
Line 
1# RTEMS Tools Project (http://www.rtems.org/)
2# Copyright 2010-2014 Chris Johns (chrisj@rtems.org)
3# All rights reserved.
4#
5# This file is part of the RTEMS Tools package in 'rtems-tools'.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions are met:
9#
10# 1. Redistributions of source code must retain the above copyright notice,
11# this list of conditions and the following disclaimer.
12#
13# 2. Redistributions in binary form must reproduce the above copyright notice,
14# this list of conditions and the following disclaimer in the documentation
15# and/or other materials provided with the distribution.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27# POSSIBILITY OF SUCH DAMAGE.
28#
29
30#
31# RTEMS Objects Support
32#
33
34import gdb
35import itertools
36import re
37
38class infotables():
39    """Manage the object information tables."""
40
41    tables_types = {
42        'internal/time'          : ('TOD_Control',           '_TOD'),
43        'internal/wdticks'       : ('Chain_Control',        '_Watchdog_Ticks_chain'),
44        'internal/wdseconds'     : ('Chain_Control',        '_Watchdog_Seconds_chain'),
45
46        'classic/tasks'          : ('Thread_Control',        '_RTEMS_tasks_Information'),
47        'classic/timers'         : ('Timer_Control',         '_Timer_Information'),
48        'classic/semaphores'     : ('Semaphore_Control',     '_Semaphore_Information'),
49        'classic/message_queues' : ('Message_queue_Control', '_Message_queue_Information'),
50        'classic/partitions'     : ('Partition_Control',     '_Partition_Information'),
51        'classic/regions'        : ('Region_Control',        '_Region_Information'),
52        'classic/ports'          : ('Port_Control',          '_Port_Information'),
53        'classic/periods'        : ('Period_Control',        '_Period_Information'),
54        'classic/extensions'     : ('Extension_Control',     '_Extension_Information'),
55        'classic/barriers'       : ('Barrier_Control',       '_Barrier_Information')
56        }
57
58    def __init__(self):
59        self.invalidate()
60
61    def invalidate(self):
62        self.tables = {}
63
64    def name(self, api, _class):
65        return '%s/%s' % (api, _class)
66
67    def load(self, n):
68        if n in self.tables_types:
69            if n not in self.tables:
70                self.tables[n] = gdb.parse_and_eval(self.tables_types[n][1])
71
72    def get(self, api, _class):
73        n = self.name(api, _class)
74        self.load(n)
75        if n in self.tables:
76            return self.tables[n]
77        return None
78
79    def minimum_id(self, api, _class):
80        n = self.name(api, _class)
81        self.load(n)
82        return int(self.tables[n]['minimum_id'])
83
84    def maximum_id(self, api, _class):
85        n = self.name(api, _class)
86        self.load(n)
87        return int(self.tables[n]['maximum_id'])
88
89    def maximum(self, api, _class):
90        n = self.name(api, _class)
91        self.load(n)
92        return int(self.tables[n]['maximum'])
93
94    def object(self, id):
95        if type(id) == gdb.Value:
96            id = ident(id)
97        if type(id) == tuple:
98            api = id[0]
99            _class = id[1]
100            index = id[2]
101        else:
102            api = id.api()
103            _class = id._class()
104            index = id.index()
105        return self.object_return(api, _class, index)
106
107    def object_return(self, api, _class, index=-1):
108        n = self.name(api, _class)
109        self.load(n)
110        table_type = self.tables_types[n]
111        if api == 'internal':
112            expr = '(%s) %s' % (table_type[0], table_type[1])
113        else:
114            max = self.maximum(api, _class)
115            if index > max:
116                raise IndexError('object index out of range (%d)' % (max))
117            expr = '(%s*) %s.local_table[%d]' % (table_type[0], table_type[1], index)
118        return gdb.parse_and_eval(expr)
119
120    def is_string(self, api, _class):
121        n = self.name(api, _class)
122        self.load(n)
123        if n in self.tables:
124            if self.tables[n]['is_string']:
125                return True
126        return False
127
128#
129# Global info tables. These are global in the target.
130#
131information = infotables()
132
133class ident():
134    "An RTEMS object id with support for its bit fields."
135
136    bits = [
137        { 'index': (0, 15),
138          'node':  (0, 0),
139          'api':   (8, 10),
140          'class': (11, 15) },
141        { 'index': (0, 15),
142          'node':  (16, 23),
143          'api':   (24, 26),
144          'class': (27, 31) }
145        ]
146
147    OBJECT_16_BITS = 0
148    OBJECT_32_BITS = 1
149
150    api_labels = [
151        'none',
152        'internal',
153        'classic',
154        'posix'
155        ]
156
157    class_labels = {
158        'internal' : ('threads',
159                      'mutexes'),
160        'classic' : ('none',
161                     'tasks',
162                     'timers',
163                     'semaphores',
164                     'message_queues',
165                     'partitions',
166                     'regions',
167                     'ports',
168                     'periods',
169                     'extensions',
170                     'barriers'),
171        'posix' : ('none',
172                   'threads',
173                   'keys',
174                   'interrupts',
175                   'message_queue_fds',
176                   'message_queues',
177                   'mutexes',
178                   'semaphores',
179                   'condition_variables',
180                   'timers',
181                   'barriers',
182                   'spinlocks',
183                   'rwlocks'),
184        }
185
186    def __init__(self, id):
187        if type(id) != gdb.Value and type(id) != int and type(id) != unicode:
188            raise TypeError('%s: must be gdb.Value, int, unicoded int' % (type(id)))
189        if type(id) == int:
190            id = gdb.Value(id)
191        self.id = id
192        if self.id.type.sizeof == 2:
193            self.idSize = self.OBJECT_16_BITS
194        else:
195            self.idSize = self.OBJECT_32_BITS
196
197    def get(self, field):
198        if field in self.bits[self.idSize]:
199            bits = self.bits[self.idSize][field]
200            if bits[1] > 0:
201                return (int(self.id) >> bits[0]) & ((1 << (bits[1] - bits[0] + 1)) - 1)
202        return 0
203
204    def value(self):
205        return int(self.id)
206
207    def index(self):
208        return self.get('index')
209
210    def node(self):
211        return self.get('node')
212
213    def api_val(self):
214        return self.get('api')
215
216    def class_val(self):
217        return self.get('class')
218
219    def api(self):
220        api = self.api_val()
221        if api < len(self.api_labels):
222            return self.api_labels[api]
223        return 'none'
224
225    def _class(self):
226        api = self.api()
227        if api == 'none':
228            return 'invalid'
229        _class = self.class_val()
230        if _class < len(self.class_labels[api]):
231            return self.class_labels[api][_class]
232        return 'invalid'
233
234    def valid(self):
235        return self.api() != 'none' and self._class() != 'invalid'
236
237class name():
238    """The Objects_Name can either be told what the name is or can take a
239    guess."""
240
241    def __init__(self, name, is_string = None):
242        self.name = name
243        if is_string == None:
244            self.is_string = 'auto'
245            try:
246                self.name_p = self.name['name_p']
247            except gdb.Error:
248                self.is_string = 'no'
249        else:
250            if is_string:
251                self.is_string = 'yes'
252            else:
253                self.is_string = 'no'
254
255    def __str__(self):
256        return self.get()
257
258    def get(self):
259        if self.is_string != 'yes':
260            u32 = int(self.name['name_u32'])
261            if u32 != 0:
262                s = chr((u32 >> 24) & 0xff) + \
263                    chr((u32 >> 16) & 0xff) + \
264                    chr((u32 >> 8) & 0xff) + \
265                    chr(u32 & 0xff)
266                for c in range(0, 4):
267                    if s[c] < ' ' or s[c] > '~':
268                        s = None
269                        break
270                if s:
271                    return s
272            if self.is_string == 'xno':
273                return None
274        try:
275            name_p = self.name['name_p']
276            return str(name_p.dereference())
277        except gdb.Error:
278            pass
279        return None
280
281class control():
282    """The Objects_Control structure."""
283
284    def __init__(self, object):
285        self.object = object
286        self._id = ident(self.object['id'])
287        self._name = name(self.object['name'],
288                          information.is_string(self._id.api(), self._id._class()))
289
290    def node(self):
291        return self.object['Node']
292
293    def id(self):
294        return self.object['id']
295
296    def name(self):
297        return self._name.get()
Note: See TracBrowser for help on using the repository browser.