source: rtems/cpukit/libmisc/monitor/mon-symbols.c @ 7f6a24ab

4.104.114.84.95
Last change on this file since 7f6a24ab was b06e68ef, checked in by Joel Sherrill <joel.sherrill@…>, on 08/17/95 at 19:51:51

Numerous miscellaneous features incorporated from Tony Bennett
(tbennett@…) including the following major additions:

+ variable length messages
+ named devices
+ debug monitor
+ association tables/variables

  • Property mode set to 100644
File size: 10.7 KB
Line 
1/*
2 *      @(#)symbols.c   1.10 - 95/08/02
3 *     
4 *  $Id$
5 */
6
7/* #define qsort _quicksort */
8
9/*
10 *  File:       symbols.c
11 *
12 *  Description:
13 *    Symbol table manager for the RTEMS monitor.
14 *    These routines may be used by other system resources also.
15 *
16 *
17 *  TODO:
18 */
19
20#include <rtems.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
25#include "monitor.h"
26#include "symbols.h"
27
28
29rtems_symbol_table_t *
30rtems_symbol_table_create()
31{
32    rtems_symbol_table_t *table;
33
34    table = (rtems_symbol_table_t *) malloc(sizeof(rtems_symbol_table_t));
35    memset((void *) table, 0, sizeof(*table));
36
37    table->growth_factor = 30;          /* 30 percent */
38
39    return table;
40}
41
42void
43rtems_symbol_table_destroy(rtems_symbol_table_t *table)
44{
45    rtems_symbol_string_block_t *p, *pnext;
46
47    if (table)
48    {
49        if (table->addresses)
50            (void) free(table->addresses);
51        table->addresses = 0;
52
53        if (table->symbols)
54            (void) free(table->symbols);
55        table->symbols = 0;
56
57        p = table->string_buffer_head;
58        while (p)
59        {
60            pnext = p->next;
61            free(p);
62            p = pnext;
63        }
64        table->string_buffer_head = 0;
65        table->string_buffer_current = 0;
66
67        free(table);
68    }
69}
70
71rtems_symbol_t *
72rtems_symbol_create(
73    rtems_symbol_table_t *table,
74    char                 *name,
75    rtems_unsigned32     value
76    )
77{
78    int symbol_length;
79    size_t newsize;
80    rtems_symbol_t *sp;
81
82    symbol_length = strlen(name) + 1;   /* include '\000' in length */
83
84    /* need to grow the table? */
85    if (table->next >= table->size)
86    {
87        if (table->size == 0)
88            newsize = 100;
89        else
90            newsize = table->size + (table->size / (100 / table->growth_factor));
91
92        table->addresses = (rtems_symbol_t *) realloc((void *) table->addresses, newsize * sizeof(rtems_symbol_t));
93        if (table->addresses == 0)        /* blew it; lost orig */
94            goto failed;
95
96        table->symbols = (rtems_symbol_t *) realloc((void *) table->symbols, newsize * sizeof(rtems_symbol_t));
97        if (table->symbols == 0)        /* blew it; lost orig */
98            goto failed;
99
100        table->size = newsize;
101    }
102
103    sp = &table->addresses[table->next];
104    sp->value = value;
105
106    /* Have to add it to string pool */
107    /* need to grow pool? */
108
109    if ((table->string_buffer_head == 0) ||
110        (table->strings_next + symbol_length) >= SYMBOL_STRING_BLOCK_SIZE)
111    {
112        rtems_symbol_string_block_t *p;
113
114        p = (rtems_symbol_string_block_t *) malloc(sizeof(rtems_symbol_string_block_t));
115        if (p == 0)
116            goto failed;
117        p->next = 0;
118        if (table->string_buffer_head == 0)
119            table->string_buffer_head = p;
120        else
121            table->string_buffer_current->next = p;
122        table->string_buffer_current = p;
123
124        table->strings_next = 0;
125    }
126
127    sp->name = table->string_buffer_current->buffer + table->strings_next;
128    (void) strcpy(sp->name, name);
129
130    table->strings_next += symbol_length;
131
132    table->symbols[table->next] = *sp;
133
134    table->sorted = 0;
135    table->next++;
136
137    return sp;
138
139/* XXX Not sure what to do here.  We've possibly destroyed the initial
140   symbol table due to realloc failure */
141failed:
142    return 0;
143}
144
145/*
146 * Qsort entry point for compare by address
147 */
148
149int
150rtems_symbol_compare(const void *e1,
151                     const void *e2)
152{
153    rtems_symbol_t *s1, *s2;
154    s1 = (rtems_symbol_t *) e1;
155    s2 = (rtems_symbol_t *) e2;
156
157    if (s1->value < s2->value)
158        return -1;
159    if (s1->value > s2->value)
160        return 1;
161    return 0;
162}
163
164/*
165 * Qsort entry point for compare by string name (case independent)
166 */
167
168int
169rtems_symbol_string_compare(const void *e1,
170                            const void *e2)
171{
172    rtems_symbol_t *s1, *s2;
173    s1 = (rtems_symbol_t *) e1;
174    s2 = (rtems_symbol_t *) e2;
175
176    return strcasecmp(s1->name, s2->name);
177}
178
179
180/*
181 * Sort the symbol table using qsort
182 */
183
184void
185rtems_symbol_sort(rtems_symbol_table_t *table)
186{
187#ifdef simhppa
188    printf("Sorting symbols ... ");         /* so slow we need a msg */
189    fflush(stdout);
190#endif
191
192    qsort((void *) table->addresses, (size_t) table->next,
193          sizeof(rtems_symbol_t), rtems_symbol_compare);
194
195    qsort((void *) table->symbols, (size_t) table->next,
196          sizeof(rtems_symbol_t), rtems_symbol_string_compare);
197
198#ifdef simhppa
199    /* so slow we need a msg */
200    printf("done\n");
201#endif
202
203    table->sorted = 1;
204}
205
206/*
207 * Search the symbol table by address
208 * This code based on CYGNUS newlib bsearch, but changed
209 * to allow for finding closest symbol <= key
210 */
211
212rtems_symbol_t *
213rtems_symbol_value_lookup(
214    rtems_symbol_table_t *table,
215    rtems_unsigned32      value
216  )
217{
218    rtems_symbol_t *sp;
219    rtems_symbol_t *base;
220    rtems_symbol_t *best = 0;
221    rtems_unsigned32 distance;
222    rtems_unsigned32 best_distance = ~0;
223    rtems_unsigned32 elements;
224
225    if (table == 0)
226        table = rtems_monitor_symbols;
227
228    if ((table == 0) || (table->size == 0))
229        return 0;
230
231    if (table->sorted == 0)
232        rtems_symbol_sort(table);
233
234    base = table->addresses;
235    elements = table->next;
236
237    while (elements)
238    {
239        sp = base + (elements / 2);
240        if (value < sp->value)
241            elements /= 2;
242        else if (value > sp->value)
243        {
244            distance = value - sp->value;
245            if (distance < best_distance)
246            {
247                best_distance = distance;
248                best = sp;
249            }
250            base = sp + 1;
251            elements = (elements / 2) - (elements % 2 ? 0 : 1);
252        }
253        else
254            return sp;
255    }
256
257    if (value == base->value)
258        return base;
259
260    return best;
261}
262
263/*
264 * Search the symbol table by string name (case independent)
265 */
266
267rtems_symbol_t *
268rtems_symbol_name_lookup(
269    rtems_symbol_table_t *table,
270    char                 *name
271  )
272{
273    rtems_symbol_t *sp = 0;
274    rtems_symbol_t  key;
275
276    if (table == 0)
277        table = rtems_monitor_symbols;
278
279    if ((table == 0) || (name == 0))
280        goto done;
281
282    if (table->sorted == 0)
283        rtems_symbol_sort(table);
284
285    /*
286     * dummy up one for bsearch()
287     */
288
289    key.name = name;
290    key.value = 0;
291
292    sp = (rtems_symbol_t *) bsearch((const void *) &key,
293                                    (const void *) table->symbols,
294                                    (size_t) table->next,
295                                    sizeof(rtems_symbol_t),
296                                    rtems_symbol_string_compare);
297
298done:
299    return sp;
300}
301
302void *
303rtems_monitor_symbol_next(
304    void                   *object_info,
305    rtems_monitor_symbol_t *canonical,
306    rtems_id               *next_id
307)
308{
309    rtems_symbol_table_t *table;
310    int n = rtems_get_index(*next_id);
311
312    table = *(rtems_symbol_table_t **) object_info;
313    if (table == 0)
314        goto failed;
315
316    if (n >= table->next)
317        goto failed;
318
319    /* NOTE: symbols do not have id and name fields */
320     
321    if (table->sorted == 0)
322        rtems_symbol_sort(table);
323
324    _Thread_Disable_dispatch();
325
326    *next_id += 1;
327    return (void *) (table->symbols + n);
328
329failed:
330    *next_id = RTEMS_OBJECT_ID_FINAL;
331    return 0;
332}
333
334void
335rtems_monitor_symbol_canonical(
336    rtems_monitor_symbol_t *canonical_symbol,
337    rtems_symbol_t *sp
338)
339{
340    canonical_symbol->value = sp->value;
341    canonical_symbol->offset = 0;
342    strncpy(canonical_symbol->name, sp->name, sizeof(canonical_symbol->name));
343}
344
345
346void
347rtems_monitor_symbol_canonical_by_name(
348    rtems_monitor_symbol_t *canonical_symbol,
349    char                   *name
350)
351{
352    rtems_symbol_t *sp;
353
354    sp = rtems_symbol_name_lookup(0, name);
355
356    canonical_symbol->value = sp ? sp->value : 0;
357
358    strncpy(canonical_symbol->name, name, sizeof(canonical_symbol->name));
359    canonical_symbol->offset = 0;
360}
361
362void
363rtems_monitor_symbol_canonical_by_value(
364    rtems_monitor_symbol_t *canonical_symbol,
365    void                   *value_void_p
366)
367{
368    unsigned32 value = (unsigned32) value_void_p;
369    rtems_symbol_t *sp;
370
371    sp = rtems_symbol_value_lookup(0, value);
372    if (sp)
373    {
374        canonical_symbol->value = sp->value;
375        canonical_symbol->offset = value - sp->value;
376        strncpy(canonical_symbol->name, sp->name, sizeof(canonical_symbol->name));
377    }
378    else
379    {
380        canonical_symbol->value = value;
381        canonical_symbol->offset = 0;
382        canonical_symbol->name[0] = '\0';
383    }
384}
385
386
387unsigned32
388rtems_monitor_symbol_dump(
389    rtems_monitor_symbol_t *canonical_symbol,
390    boolean                 verbose
391)
392{
393    unsigned32 length = 0;
394
395    /*
396     * print the name if it exists AND if value is non-zero
397     * Ie: don't print some garbage symbol for address 0
398     */
399
400    if (canonical_symbol->name[0] && (canonical_symbol->value != 0))
401    {
402        if (canonical_symbol->offset == 0)
403            length += printf("%.*s",
404                             sizeof(canonical_symbol->name),
405                             canonical_symbol->name);
406        else
407            length += printf("<%.*s+0x%x>",
408                             sizeof(canonical_symbol->name),
409                             canonical_symbol->name,
410                             canonical_symbol->offset);
411        if (verbose)
412            length += printf(" [0x%x]", canonical_symbol->value);
413    }
414    else
415        length += printf("[0x%x]", canonical_symbol->value);
416
417    return length;
418}
419
420
421void
422rtems_monitor_symbol_dump_all(
423    rtems_symbol_table_t *table,
424    boolean               verbose
425)
426{
427    int s;
428    rtems_symbol_t *sp;
429
430    if (table == 0)
431    {
432        table = rtems_monitor_symbols;
433        if (table == 0)
434            return;
435    }
436
437    if (table->sorted == 0)
438        rtems_symbol_sort(table);
439
440    for (s = 0, sp = table->symbols; s < table->next; s++, sp++)
441    {
442        rtems_monitor_symbol_t canonical_symbol;
443
444        rtems_monitor_symbol_canonical(&canonical_symbol, sp);
445        rtems_monitor_symbol_dump(&canonical_symbol, TRUE);
446        printf("\n");
447    }
448}
449
450
451/*
452 * 'symbol' command
453 */
454
455void
456rtems_monitor_symbol_cmd(
457    int        argc,
458    char     **argv,
459    unsigned32 command_arg,
460    boolean    verbose
461)
462{
463    int arg;
464    rtems_symbol_table_t *table;
465
466    table = *(rtems_symbol_table_t **) command_arg;
467    if (table == 0)
468    {
469        table = rtems_monitor_symbols;
470        if (table == 0)
471            return;
472    }
473
474    /*
475     * Use object command to dump out whole symbol table
476     */
477    if (argc == 1)
478        rtems_monitor_symbol_dump_all(table, verbose);
479    else
480    {
481        rtems_monitor_symbol_t canonical_symbol;
482
483        for (arg=1; argv[arg]; arg++)
484        {
485            rtems_monitor_symbol_canonical_by_name(&canonical_symbol, argv[arg]);
486            rtems_monitor_symbol_dump(&canonical_symbol, verbose);
487            printf("\n");
488        }
489    }
490}
Note: See TracBrowser for help on using the repository browser.