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

4.104.114.84.9
Last change on this file since cb2f320 was cb2f320, checked in by Joel Sherrill <joel.sherrill@…>, on Mar 5, 2004 at 6:02:41 PM

2004-03-05 Joel Sherrill <joel@…>

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