source: rtems/c/src/libmisc/monitor/mon-symbols.c @ 5a36154a

4.104.114.84.95
Last change on this file since 5a36154a was e6424462, checked in by Joel Sherrill <joel.sherrill@…>, on 03/06/96 at 21:37:43

As part of reducing visibility into rtems and hiding the .inl files
from the application code, this file required more visibility than
is given by default to application code.

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