Bug Summary

File:/home/joel/rtems-4.11-work/build/rtems/c/src/../../cpukit/libmisc/monitor/mon-symbols.c
Location:line 128, column 5
Description:Allocated memory never released. Potential memory leak

Annotated Source Code

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