File indexing completed on 2025-05-11 08:24:18
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #ifdef HAVE_CONFIG_H
0037 #include "config.h"
0038 #endif
0039
0040 #include <string.h>
0041 #ifdef HAVE_STRINGS_H
0042 #include <strings.h>
0043 #endif
0044
0045 #include <rtems.h>
0046 #include <stdio.h>
0047 #include <stdlib.h>
0048 #include <inttypes.h>
0049
0050 #include <rtems/monitor.h>
0051 #include "symbols.h"
0052
0053
0054 rtems_symbol_table_t *
0055 rtems_symbol_table_create(void)
0056 {
0057 rtems_symbol_table_t *table;
0058
0059 table = (rtems_symbol_table_t *) malloc(sizeof(rtems_symbol_table_t));
0060 memset((void *) table, 0, sizeof(*table));
0061
0062 table->growth_factor = 30;
0063
0064 return table;
0065 }
0066
0067 void
0068 rtems_symbol_table_destroy(rtems_symbol_table_t *table)
0069 {
0070 rtems_symbol_string_block_t *p, *pnext;
0071
0072 if (table)
0073 {
0074 if (table->addresses)
0075 (void) free(table->addresses);
0076 table->addresses = 0;
0077 p = table->string_buffer_head;
0078 while (p)
0079 {
0080 pnext = p->next;
0081 free(p);
0082 p = pnext;
0083 }
0084 table->string_buffer_head = 0;
0085 table->string_buffer_current = 0;
0086
0087 free(table);
0088 }
0089 }
0090
0091 rtems_symbol_t *
0092 rtems_symbol_create(
0093 rtems_symbol_table_t *table,
0094 const char *name,
0095 uint32_t value
0096 )
0097 {
0098 size_t symbol_length;
0099 size_t newsize;
0100 rtems_symbol_t *sp;
0101
0102 symbol_length = strlen(name) + 1;
0103
0104
0105 if (table->next >= table->size)
0106 {
0107 if (table->size == 0)
0108 newsize = 100;
0109 else
0110 newsize = table->size + (table->size / (100 / table->growth_factor));
0111
0112 table->addresses = (rtems_symbol_t *) realloc((void *) table->addresses, newsize * sizeof(rtems_symbol_t));
0113 if (table->addresses == 0)
0114 goto failed;
0115 table->size = newsize;
0116 }
0117
0118 sp = &table->addresses[table->next];
0119 sp->value = value;
0120
0121
0122
0123
0124 if ((table->string_buffer_head == 0) ||
0125 (table->strings_next + symbol_length) >= SYMBOL_STRING_BLOCK_SIZE)
0126 {
0127 rtems_symbol_string_block_t *p;
0128
0129 p = (rtems_symbol_string_block_t *) malloc(sizeof(rtems_symbol_string_block_t));
0130 if (p == 0)
0131 goto failed;
0132 p->next = 0;
0133 if (table->string_buffer_head == 0)
0134 table->string_buffer_head = p;
0135 else
0136 table->string_buffer_current->next = p;
0137 table->string_buffer_current = p;
0138
0139 table->strings_next = 0;
0140 }
0141
0142 sp->name = table->string_buffer_current->buffer + table->strings_next;
0143 (void) strcpy(sp->name, name);
0144
0145 table->strings_next += symbol_length;
0146 table->sorted = 0;
0147 table->next++;
0148
0149 return sp;
0150
0151
0152
0153 failed:
0154 return 0;
0155 }
0156
0157
0158
0159
0160
0161 static int
0162 rtems_symbol_compare(const void *e1,
0163 const void *e2)
0164 {
0165 const rtems_symbol_t *s1, *s2;
0166 s1 = (const rtems_symbol_t *) e1;
0167 s2 = (const rtems_symbol_t *) e2;
0168
0169 if (s1->value < s2->value)
0170 return -1;
0171 if (s1->value > s2->value)
0172 return 1;
0173 return 0;
0174 }
0175
0176
0177
0178
0179
0180
0181 static void
0182 rtems_symbol_sort(rtems_symbol_table_t *table)
0183 {
0184 qsort((void *) table->addresses, (size_t) table->next,
0185 sizeof(rtems_symbol_t), rtems_symbol_compare);
0186 table->sorted = 1;
0187 }
0188
0189
0190
0191
0192
0193
0194
0195
0196 rtems_symbol_t *
0197 rtems_symbol_value_lookup(
0198 rtems_symbol_table_t *table,
0199 uint32_t value
0200 )
0201 {
0202 rtems_symbol_t *sp;
0203 rtems_symbol_t *base;
0204 rtems_symbol_t *best = 0;
0205 uint32_t distance;
0206 uint32_t best_distance = ~0;
0207 uint32_t elements;
0208
0209 if (table == 0)
0210 table = rtems_monitor_symbols;
0211
0212 if ((table == 0) || (table->size == 0))
0213 return 0;
0214
0215 if (table->sorted == 0)
0216 rtems_symbol_sort(table);
0217
0218 base = table->addresses;
0219 elements = table->next;
0220
0221 while (elements)
0222 {
0223 sp = base + (elements / 2);
0224 if (value < sp->value)
0225 elements /= 2;
0226 else if (value > sp->value)
0227 {
0228 distance = value - sp->value;
0229 if (distance < best_distance)
0230 {
0231 best_distance = distance;
0232 best = sp;
0233 }
0234 base = sp + 1;
0235 elements = (elements / 2) - (elements % 2 ? 0 : 1);
0236 }
0237 else
0238 return sp;
0239 }
0240
0241 if (value == base->value)
0242 return base;
0243
0244 return best;
0245 }
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258 const rtems_symbol_t *
0259 rtems_symbol_value_lookup_exact(
0260 rtems_symbol_table_t *table,
0261 uint32_t value
0262 )
0263 {
0264 uint32_t s;
0265 rtems_symbol_t *sp;
0266
0267 if (table == 0)
0268 {
0269 table = rtems_monitor_symbols;
0270 if (table == 0)
0271 return NULL;
0272 }
0273
0274 if (table->sorted)
0275 {
0276 sp = rtems_symbol_value_lookup(table, value);
0277 if ( rtems_symbol_value(sp) == value )
0278 return sp;
0279 else
0280 return NULL;
0281 }
0282
0283 for (s = 0, sp = table->addresses; s < table->next; s++, sp++)
0284 {
0285 if ( sp->value == value )
0286 return sp;
0287 }
0288
0289 return NULL;
0290
0291 }
0292
0293
0294
0295
0296
0297
0298 rtems_symbol_t *
0299 rtems_symbol_name_lookup(
0300 rtems_symbol_table_t *table,
0301 const char *name
0302 )
0303 {
0304 uint32_t s;
0305 rtems_symbol_t *sp;
0306
0307 if (table == 0)
0308 {
0309 table = rtems_monitor_symbols;
0310 if (table == 0)
0311 return NULL;
0312 }
0313
0314 for (s = 0, sp = table->addresses; s < table->next; s++, sp++)
0315 {
0316 if ( strcasecmp(sp->name, name) == 0 )
0317 return sp;
0318 }
0319
0320 return NULL;
0321 }
0322
0323 const void *
0324 rtems_monitor_symbol_next(
0325 void *object_info,
0326 rtems_monitor_symbol_t *canonical RTEMS_UNUSED,
0327 rtems_id *next_id
0328 )
0329 {
0330 rtems_symbol_table_t *table;
0331 uint32_t n = rtems_object_id_get_index(*next_id);
0332
0333 table = *(rtems_symbol_table_t **) object_info;
0334 if (table == 0)
0335 goto failed;
0336
0337 if (n >= table->next)
0338 goto failed;
0339
0340
0341
0342 if (table->sorted == 0)
0343 rtems_symbol_sort(table);
0344
0345 _Objects_Allocator_lock();
0346
0347 *next_id += 1;
0348 return (const void *) (table->addresses + n);
0349
0350 failed:
0351 *next_id = RTEMS_OBJECT_ID_FINAL;
0352 return 0;
0353 }
0354
0355 void
0356 rtems_monitor_symbol_canonical(
0357 rtems_monitor_symbol_t *canonical_symbol,
0358 rtems_symbol_t *sp
0359 )
0360 {
0361 canonical_symbol->value = sp->value;
0362 canonical_symbol->offset = 0;
0363 strncpy(canonical_symbol->name, sp->name, sizeof(canonical_symbol->name)-1);
0364 }
0365
0366
0367 void
0368 rtems_monitor_symbol_canonical_by_name(
0369 rtems_monitor_symbol_t *canonical_symbol,
0370 const char *name
0371 )
0372 {
0373 rtems_symbol_t *sp;
0374
0375 sp = rtems_symbol_name_lookup(0, name);
0376
0377 canonical_symbol->value = sp ? sp->value : 0;
0378
0379 strncpy(canonical_symbol->name, name, sizeof(canonical_symbol->name) - 1);
0380 canonical_symbol->offset = 0;
0381 }
0382
0383 void
0384 rtems_monitor_symbol_canonical_by_value(
0385 rtems_monitor_symbol_t *canonical_symbol,
0386 void *value_void_p
0387 )
0388 {
0389 uintptr_t value = (uintptr_t) value_void_p;
0390 rtems_symbol_t *sp;
0391
0392 sp = rtems_symbol_value_lookup(0, value);
0393 if (sp)
0394 {
0395 canonical_symbol->value = sp->value;
0396 canonical_symbol->offset = value - sp->value;
0397 strncpy(canonical_symbol->name, sp->name, sizeof(canonical_symbol->name)-1);
0398 }
0399 else
0400 {
0401 canonical_symbol->value = value;
0402 canonical_symbol->offset = 0;
0403 canonical_symbol->name[0] = '\0';
0404 }
0405 }
0406
0407
0408 uint32_t
0409 rtems_monitor_symbol_dump(
0410 rtems_monitor_symbol_t *canonical_symbol,
0411 bool verbose
0412 )
0413 {
0414 uint32_t length = 0;
0415
0416
0417
0418
0419
0420
0421 if (canonical_symbol->name[0] && (canonical_symbol->value != 0))
0422 {
0423 if (canonical_symbol->offset == 0)
0424 length += fprintf(stdout,"%.*s",
0425 (int) sizeof(canonical_symbol->name),
0426 canonical_symbol->name);
0427 else
0428 length += fprintf(stdout,"<%.*s+0x%" PRIx32 ">",
0429 (int) sizeof(canonical_symbol->name),
0430 canonical_symbol->name,
0431 canonical_symbol->offset);
0432 if (verbose)
0433 length += fprintf(stdout,
0434 " [0x%" PRIx32 "]", canonical_symbol->value);
0435 }
0436 else
0437 length += fprintf(stdout,"[0x%" PRIx32 "]", canonical_symbol->value);
0438
0439 return length;
0440 }
0441
0442
0443 static void
0444 rtems_monitor_symbol_dump_all(
0445 rtems_symbol_table_t *table,
0446 bool verbose RTEMS_UNUSED
0447 )
0448 {
0449 uint32_t s;
0450 rtems_symbol_t *sp;
0451
0452 if (table == 0)
0453 {
0454 table = rtems_monitor_symbols;
0455 if (table == 0)
0456 return;
0457 }
0458
0459 if (table->sorted == 0)
0460 rtems_symbol_sort(table);
0461
0462 for (s = 0, sp = table->addresses; s < table->next; s++, sp++)
0463 {
0464 rtems_monitor_symbol_t canonical_symbol;
0465
0466 rtems_monitor_symbol_canonical(&canonical_symbol, sp);
0467 rtems_monitor_symbol_dump(&canonical_symbol, true);
0468 fprintf(stdout,"\n");
0469 }
0470 }
0471
0472
0473
0474
0475
0476
0477 void rtems_monitor_symbol_cmd(
0478 int argc,
0479 char **argv,
0480 const rtems_monitor_command_arg_t *command_arg,
0481 bool verbose
0482 )
0483 {
0484 int arg;
0485 rtems_symbol_table_t *table;
0486
0487 table = *command_arg->symbol_table;
0488 if (table == 0)
0489 {
0490 table = rtems_monitor_symbols;
0491 if (table == 0)
0492 return;
0493 }
0494
0495
0496
0497
0498 if (argc == 1)
0499 rtems_monitor_symbol_dump_all(table, verbose);
0500 else
0501 {
0502 rtems_monitor_symbol_t canonical_symbol;
0503
0504 for (arg=1; argv[arg]; arg++)
0505 {
0506 rtems_monitor_symbol_canonical_by_name(&canonical_symbol, argv[arg]);
0507 rtems_monitor_symbol_dump(&canonical_symbol, verbose);
0508 fprintf(stdout,"\n");
0509 }
0510 }
0511 }