source: rtems/cpukit/libmisc/monitor/mon-symbols.c @ 4e58d80

4.104.114.84.95
Last change on this file since 4e58d80 was 637df35, checked in by Joel Sherrill <joel.sherrill@…>, on 07/12/95 at 19:47:25

Ada95, gnat, go32

  • Property mode set to 100644
File size: 7.2 KB
Line 
1/*
2 *      @(#)symbols.c   1.3 - 95/04/24
3 *     
4 */
5
6/* #define qsort _quicksort */
7
8/*
9 *  File:       symbols.c
10 *
11 *  Description:
12 *    Symbol table manager for the RTEMS monitor.
13 *    These routines may be used by other system resources also.
14 *
15 *
16 *  TODO:
17 */
18
19#include <rtems.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23
24#include "symbols.h"
25
26extern rtems_symbol_table_t *rtems_monitor_symbols;
27
28#ifdef RTEMS_DEBUG
29#define CHK_ADR_PTR(p)  \
30do { \
31    if (((p) < rtems_monitor_symbols->addresses) || \
32        ((p) >= (rtems_monitor_symbols->addresses + rtems_monitor_symbols->next))) \
33    { \
34        printf("bad address pointer %p\n", (p)); \
35        rtems_fatal_error_occurred(RTEMS_INVALID_ADDRESS); \
36    } \
37} while (0)
38
39#define CHK_NAME_PTR(p) \
40do { \
41    if (((p) < rtems_monitor_symbols->symbols) || \
42        ((p) >= (rtems_monitor_symbols->symbols + rtems_monitor_symbols->next))) \
43    { \
44        printf("bad symbol pointer %p\n", (p)); \
45        rtems_fatal_error_occurred(RTEMS_INVALID_ADDRESS); \
46    } \
47} while (0)
48#else
49#define CHK_ADR_PTR(p)
50#define CHK_NAME_PTR(p)
51#endif
52
53rtems_symbol_table_t *
54rtems_symbol_table_create()
55{
56    rtems_symbol_table_t *table;
57
58    table = (rtems_symbol_table_t *) malloc(sizeof(rtems_symbol_table_t));
59    memset((void *) table, 0, sizeof(*table));
60
61    table->growth_factor = 30;          /* 30 percent */
62
63    return table;
64}
65
66void
67rtems_symbol_table_destroy(rtems_symbol_table_t *table)
68{
69    rtems_symbol_string_block_t *p, *pnext;
70
71    if (table)
72    {
73        if (table->addresses)
74            (void) free(table->addresses);
75        table->addresses = 0;
76
77        if (table->symbols)
78            (void) free(table->symbols);
79        table->symbols = 0;
80
81        p = table->string_buffer_head;
82        while (p)
83        {
84            pnext = p->next;
85            free(p);
86            p = pnext;
87        }
88        table->string_buffer_head = 0;
89        table->string_buffer_current = 0;
90
91        free(table);
92    }
93}
94
95rtems_symbol_t *
96rtems_symbol_create(
97    rtems_symbol_table_t *table,
98    char                 *name,
99    rtems_unsigned32     value
100    )
101{
102    int symbol_length;
103    size_t newsize;
104    rtems_symbol_t *sp;
105
106    symbol_length = strlen(name) + 1;   /* include '\000' in length */
107
108    /* need to grow the table? */
109    if (table->next >= table->size)
110    {
111        if (table->size == 0)
112            newsize = 100;
113        else
114            newsize = table->size + (table->size / (100 / table->growth_factor));
115
116        table->addresses = (rtems_symbol_t *) realloc((void *) table->addresses, newsize * sizeof(rtems_symbol_t));
117        if (table->addresses == 0)        /* blew it; lost orig */
118            goto failed;
119
120        table->symbols = (rtems_symbol_t *) realloc((void *) table->symbols, newsize * sizeof(rtems_symbol_t));
121        if (table->symbols == 0)        /* blew it; lost orig */
122            goto failed;
123
124        table->size = newsize;
125    }
126
127    sp = &table->addresses[table->next];
128    sp->value = value;
129
130    /* Have to add it to string pool */
131    /* need to grow pool? */
132
133    if ((table->string_buffer_head == 0) ||
134        (table->strings_next + symbol_length) >= SYMBOL_STRING_BLOCK_SIZE)
135    {
136        rtems_symbol_string_block_t *p;
137
138        p = (rtems_symbol_string_block_t *) malloc(sizeof(rtems_symbol_string_block_t));
139        if (p == 0)
140            goto failed;
141        p->next = 0;
142        if (table->string_buffer_head == 0)
143            table->string_buffer_head = p;
144        else
145            table->string_buffer_current->next = p;
146        table->string_buffer_current = p;
147
148        table->strings_next = 0;
149    }
150
151    sp->name = table->string_buffer_current->buffer + table->strings_next;
152    (void) strcpy(sp->name, name);
153
154    table->strings_next += symbol_length;
155
156    table->symbols[table->next] = *sp;
157
158    table->sorted = 0;
159    table->next++;
160
161    return sp;
162
163/* XXX Not sure what to do here.  We've possibly destroyed the initial
164   symbol table due to realloc failure */
165failed:
166    return 0;
167}
168
169/*
170 * Qsort entry point for compare by address
171 */
172
173int
174rtems_symbol_compare(const void *e1,
175                     const void *e2)
176{
177    rtems_symbol_t *s1, *s2;
178    s1 = (rtems_symbol_t *) e1;
179    s2 = (rtems_symbol_t *) e2;
180
181    CHK_ADR_PTR(s1);
182    CHK_ADR_PTR(s2);
183
184    if (s1->value < s2->value)
185        return -1;
186    if (s1->value > s2->value)
187        return 1;
188    return 0;
189}
190
191/*
192 * Qsort entry point for compare by string name (case independent)
193 */
194
195int
196rtems_symbol_string_compare(const void *e1,
197                            const void *e2)
198{
199    rtems_symbol_t *s1, *s2;
200    s1 = (rtems_symbol_t *) e1;
201    s2 = (rtems_symbol_t *) e2;
202
203    CHK_NAME_PTR(s1);
204    CHK_NAME_PTR(s2);
205
206    return strcasecmp(s1->name, s2->name);
207}
208
209
210/*
211 * Sort the symbol table using qsort
212 */
213
214void
215rtems_symbol_sort(rtems_symbol_table_t *table)
216{
217#ifdef simhppa
218    printf("Sorting symbols ... ");         /* so slow we need a msg */
219    fflush(stdout);
220#endif
221
222    qsort((void *) table->addresses, (size_t) table->next,
223          sizeof(rtems_symbol_t), rtems_symbol_compare);
224
225    qsort((void *) table->symbols, (size_t) table->next,
226          sizeof(rtems_symbol_t), rtems_symbol_string_compare);
227
228#ifdef simhppa
229    /* so slow we need a msg */
230    printf("done\n");
231#endif
232
233    table->sorted = 1;
234}
235
236/*
237 * Search the symbol table by address
238 * This code based on CYGNUS newlib bsearch, but changed
239 * to allow for finding closest symbol <= key
240 */
241
242rtems_symbol_t *
243rtems_symbol_value_lookup(
244    rtems_symbol_table_t *table,
245    rtems_unsigned32      value
246  )
247{
248    rtems_symbol_t *sp;
249    rtems_symbol_t *base;
250    rtems_symbol_t *best = 0;
251    rtems_unsigned32 distance;
252    rtems_unsigned32 best_distance = ~0;
253    rtems_unsigned32 elements;
254
255    if ((table == 0) || (table->size == 0))
256        return 0;
257
258    if (table->sorted == 0)
259        rtems_symbol_sort(table);
260
261    base = table->addresses;
262    elements = table->next;
263
264    while (elements)
265    {
266        sp = base + (elements / 2);
267        if (value < sp->value)
268            elements /= 2;
269        else if (value > sp->value)
270        {
271            distance = value - sp->value;
272            if (distance < best_distance)
273            {
274                best_distance = distance;
275                best = sp;
276            }
277            base = sp + 1;
278            elements = (elements / 2) - (elements % 2 ? 0 : 1);
279        }
280        else
281            return sp;
282    }
283
284    if (value == base->value)
285        return base;
286
287    return best;
288}
289
290/*
291 * Search the symbol table by string name (case independent)
292 */
293
294rtems_symbol_t *
295rtems_symbol_name_lookup(
296    rtems_symbol_table_t *table,
297    char                 *name
298  )
299{
300    rtems_symbol_t *sp = 0;
301    rtems_symbol_t  key;
302
303    if ((table == 0) || (name == 0))
304        goto done;
305
306    if (table->sorted == 0)
307    {
308        rtems_symbol_sort(table);
309    }
310
311    /*
312     * dummy up one for bsearch()
313     */
314
315    key.name = name;
316    key.value = 0;
317
318    sp = (rtems_symbol_t *) bsearch((const void *) &key,
319                                    (const void *) table->symbols,
320                                    (size_t) table->next,
321                                    sizeof(rtems_symbol_t),
322                                    rtems_symbol_string_compare);
323
324done:
325    return sp;
326}
327
Note: See TracBrowser for help on using the repository browser.