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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [c/] [src/] [libmisc/] [monitor/] [mon-symbols.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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