OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [libmisc/] [monitor/] [mon-symbols.c] - Blame information for rev 279

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.