source: rtems/c/src/libmisc/monitor/mon-symbols.c @ 48bfd992

4.104.114.84.95
Last change on this file since 48bfd992 was 6fc973e, checked in by Joel Sherrill <joel.sherrill@…>, on 08/18/99 at 16:49:52

Patch from Ralf Corsepius <corsepiu@…>:

Here is another fix, which addresses a few more or less severe bugs in
configuration and unix/posix:

  • Configuration fix: c/src/lib/configure.in didn't handle RDBG correctly
  • Configuration fix: make depend was non-functional in c/src/lib/libc/Makefile.in
  • Configuration fix: stray comment removed from aclocal/target.m4
  • RTEMS fix: termios support for unix/posix now uses the host's headers only (was completely broken).
  • Don't install RTEMS's newlib sys/termios.h for unix (sys/termios.h apparently is a newlib specific header)
  • To be able to compile RTEMS's termios.c with glibc2.1, glibc-2.1 needs USE_MISC, which is a private define from gcc's features.h, being defined only when _BSD_SOURCE of _SVID_SOURCE is defined. RTEMS's termios apparently implements BSD, thus -D_BSD_SOURCE was added to Linux-posix.cfg.
  • Conflicting definitions for USE_MISC and _BSD_SOURCE inside of RTEMS codes removed due to definition of _BSD_SOURCE on the toplevel.

This fix has been tested with linux/posix (primary glibc2.1 native),
linux/posix (secondary libc5 native), sh/gensh1, i386/pc386 and a couple
of other bsp's/CPU.

To apply:

cd <srcdir>
patch -p1 < rtems-rc-19990709-9.diff

and

aclocal -I aclocal && automake && autoconf
cd c/src/lib; autoconf

or

./autogen

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