2 * symbols.c - stp symbol and module functions
4 * Copyright (C) Red Hat Inc, 2006-2008
6 * This file is part of systemtap, and is free software. You can
7 * redistribute it and/or modify it under the terms of the GNU General
8 * Public License (GPL); either version 2, or (at your option) any
11 * The u32_swap(), generic_swap(), and sort() functions were adapted from
12 * lib/sort.c of kernel 2.6.22-rc5. It was written by Matt Mackall.
19 static char *_stp_symbol_data
= NULL
;
20 static int _stp_symbol_state
= 0;
21 static char *_stp_module_data
= NULL
;
22 static int _stp_module_state
= 0;
25 /* these are all the symbol types we are interested in */
26 static int _stp_sym_type_ok(int type
)
38 /* From a module struct, scan the symtab and figure out how much space */
39 /* we need to store all the parts we are interested in */
40 static unsigned _stp_get_sym_sizes(struct module
*m
, unsigned *dsize
)
43 unsigned num
= 0, datasize
= 0;
44 for (i
=0; i
< m
->num_symtab
; i
++) {
45 char *str
= (char *)(m
->strtab
+ m
->symtab
[i
].st_name
);
46 if (*str
!= '\0' && _stp_sym_type_ok(m
->symtab
[i
].st_info
)) {
47 datasize
+= strlen(str
)+1;
55 /* allocate space for a module and symbols */
56 static struct _stp_module
* _stp_alloc_module(unsigned num
, unsigned datasize
, unsigned unwindsize
)
58 struct _stp_module
*mod
= (struct _stp_module
*)_stp_kzalloc(sizeof(struct _stp_module
));
62 mod
->symbols
= (struct _stp_symbol
*)_stp_kmalloc(num
* sizeof(struct _stp_symbol
));
63 if (mod
->symbols
== NULL
) {
64 mod
->symbols
= (struct _stp_symbol
*)_stp_vmalloc(num
* sizeof(struct _stp_symbol
));
65 if (mod
->symbols
== NULL
)
70 mod
->symbol_data
= _stp_kmalloc(datasize
);
71 if (mod
->symbol_data
== NULL
) {
72 mod
->symbol_data
= _stp_vmalloc(datasize
);
73 if (mod
->symbol_data
== NULL
)
78 mod
->unwind_data
= _stp_kmalloc(unwindsize
);
79 if (mod
->unwind_data
== NULL
) {
80 mod
->unwind_data
= _stp_vmalloc(unwindsize
);
81 if (mod
->unwind_data
== NULL
)
86 mod
->num_symbols
= num
;
92 if (mod
->allocated
& 1)
93 _stp_vfree(mod
->symbols
);
95 _stp_kfree(mod
->symbols
);
98 if (mod
->symbol_data
) {
99 if (mod
->allocated
& 2)
100 _stp_vfree(mod
->symbol_data
);
102 _stp_kfree(mod
->symbol_data
);
103 mod
->symbol_data
= NULL
;
107 if (mod
->allocated
& 1)
108 _stp_vfree(mod
->symbols
);
110 _stp_kfree(mod
->symbols
);
118 static struct _stp_module
* _stp_alloc_module_from_module (struct module
*m
, uint32_t unwind_len
)
120 unsigned datasize
, num
= _stp_get_sym_sizes(m
, &datasize
);
121 return _stp_alloc_module(num
, datasize
, unwind_len
);
124 static void _stp_free_module(struct _stp_module
*mod
)
126 /* The module write lock is held. Any prior readers of this */
127 /* module's data will have read locks and need to finish before */
128 /* the memory is freed. */
129 write_lock(&mod
->lock
);
130 write_unlock(&mod
->lock
); /* there will be no more readers */
132 /* free symbol memory */
134 if (mod
->allocated
& 1)
135 _stp_vfree(mod
->symbols
);
137 _stp_kfree(mod
->symbols
);
140 if (mod
->symbol_data
) {
141 if (mod
->allocated
& 2)
142 _stp_vfree(mod
->symbol_data
);
144 _stp_kfree(mod
->symbol_data
);
145 mod
->symbol_data
= NULL
;
148 if (mod
->unwind_data
) {
149 if (mod
->allocated
& 4)
150 _stp_vfree(mod
->unwind_data
);
152 _stp_kfree(mod
->unwind_data
);
153 mod
->unwind_data
= NULL
;
157 _stp_kfree(mod
->sections
);
158 mod
->sections
= NULL
;
161 /* free module memory */
165 /* Delete a module and free its memory. */
166 /* The module lock should already be held before calling this. */
167 static void _stp_del_module(struct _stp_module
*mod
)
171 // kbug(DEBUG_SYMBOLS, "deleting %s\n", mod->name);
173 /* signal relocation code to clear its cache */
174 _stp_module_relocate((char *)-1, NULL
, 0);
176 /* remove module from the arrays */
177 for (num
= 0; num
< _stp_num_modules
; num
++) {
178 if (_stp_modules
[num
] == mod
)
181 if (num
>= _stp_num_modules
)
184 for (i
= num
; i
< _stp_num_modules
-1; i
++)
185 _stp_modules
[i
] = _stp_modules
[i
+1];
187 for (num
= 0; num
< _stp_num_modules
; num
++) {
188 if (_stp_modules_by_addr
[num
] == mod
)
191 for (i
= num
; i
< _stp_num_modules
-1; i
++)
192 _stp_modules_by_addr
[i
] = _stp_modules_by_addr
[i
+1];
196 _stp_free_module(mod
);
199 static void _stp_free_modules(void)
204 /* This only happens when the systemtap module unloads */
205 /* so there is no need for locks. */
206 for (i
= _stp_num_modules
- 1; i
>= 0; i
--)
207 _stp_del_module(_stp_modules
[i
]);
210 static unsigned long _stp_kallsyms_lookup_name(const char *name
);
212 /* process the KERNEL symbols */
213 static int _stp_do_symbols(const char __user
*buf
, int count
)
215 struct _stp_symbol
*s
;
216 unsigned datasize
, num
, unwindsize
;
219 switch (_stp_symbol_state
) {
221 if (count
!= sizeof(struct _stp_msg_symbol_hdr
)) {
222 errk("count=%d\n", count
);
225 if (get_user(num
, (unsigned __user
*)buf
))
227 if (get_user(datasize
, (unsigned __user
*)(buf
+4)))
229 if (get_user(unwindsize
, (unsigned __user
*)(buf
+8)))
231 dbug(DEBUG_UNWIND
, "num=%d datasize=%d unwindsize=%d\n", num
, datasize
, unwindsize
);
233 _stp_modules
[0] = _stp_alloc_module(num
, datasize
, unwindsize
);
234 if (_stp_modules
[0] == NULL
) {
235 errk("cannot allocate memory\n");
238 rwlock_init(&_stp_modules
[0]->lock
);
239 _stp_symbol_state
= 1;
242 dbug(DEBUG_SYMBOLS
, "got stap_symbols, count=%d\n", count
);
243 if (copy_from_user ((char *)_stp_modules
[0]->symbols
, buf
, count
))
245 _stp_symbol_state
= 2;
248 dbug(DEBUG_SYMBOLS
, "got symbol data, count=%d buf=%p\n", count
, buf
);
249 if (copy_from_user (_stp_modules
[0]->symbol_data
, buf
, count
))
251 _stp_num_modules
= 1;
253 s
= _stp_modules
[0]->symbols
;
254 for (i
= 0; i
< _stp_modules
[0]->num_symbols
; i
++)
255 s
[i
].symbol
+= (long)_stp_modules
[0]->symbol_data
;
257 _stp_symbol_state
= 3;
258 /* NB: this mapping is used by kernel/_stext pseudo-relocations. */
259 _stp_modules
[0]->text
= _stp_kallsyms_lookup_name("_stext");
260 _stp_modules
[0]->data
= _stp_kallsyms_lookup_name("_etext");
261 _stp_modules
[0]->text_size
= _stp_modules
[0]->data
- _stp_modules
[0]->text
;
262 _stp_modules_by_addr
[0] = _stp_modules
[0];
263 dbug(DEBUG_SYMBOLS
, "Got kernel symbols. text=%p len=%u\n",
264 (int64_t)_stp_modules
[0]->text
, _stp_modules
[0]->text_size
);
267 dbug(DEBUG_UNWIND
, "got unwind data, count=%d\n", count
);
268 _stp_symbol_state
= 4;
269 if (copy_from_user (_stp_modules
[0]->unwind_data
, buf
, count
)) {
270 _dbug("cfu failed\n");
273 _stp_modules
[0]->unwind_data_len
= count
;
276 errk("unexpected symbol data of size %d.\n", count
);
281 static int _stp_compare_addr(const void *p1
, const void *p2
)
283 struct _stp_symbol
*s1
= (struct _stp_symbol
*)p1
;
284 struct _stp_symbol
*s2
= (struct _stp_symbol
*)p2
;
285 if (s1
->addr
== s2
->addr
) return 0;
286 if (s1
->addr
< s2
->addr
) return -1;
290 static void _stp_swap_symbol(void *x
, void *y
, int size
)
292 struct _stp_symbol
*a
= (struct _stp_symbol
*)x
;
293 struct _stp_symbol
*b
= (struct _stp_symbol
*)y
;
294 unsigned long addr
= a
->addr
;
295 const char *symbol
= a
->symbol
;
297 a
->symbol
= b
->symbol
;
302 static void u32_swap(void *a
, void *b
, int size
)
305 *(u32
*)a
= *(u32
*)b
;
309 static void generic_swap(void *a
, void *b
, int size
)
313 *(char *)a
++ = *(char *)b
;
315 } while (--size
> 0);
319 * sort - sort an array of elements
320 * @base: pointer to data to sort
321 * @num: number of elements
322 * @size: size of each element
323 * @cmp: pointer to comparison function
324 * @swap: pointer to swap function or NULL
326 * This function does a heapsort on the given array. You may provide a
327 * swap function optimized to your element type.
329 * Sorting time is O(n log n) both on average and worst-case. While
330 * qsort is about 20% faster on average, it suffers from exploitable
331 * O(n*n) worst-case behavior and extra memory requirements that make
332 * it less suitable for kernel use.
334 void _stp_sort(void *base
, size_t num
, size_t size
,
335 int (*cmp
)(const void *, const void *),
336 void (*swap
)(void *, void *, int size
))
338 /* pre-scale counters for performance */
339 int i
= (num
/2 - 1) * size
, n
= num
* size
, c
, r
;
342 swap
= (size
== 4 ? u32_swap
: generic_swap
);
345 for ( ; i
>= 0; i
-= size
) {
346 for (r
= i
; r
* 2 + size
< n
; r
= c
) {
348 if (c
< n
- size
&& cmp(base
+ c
, base
+ c
+ size
) < 0)
350 if (cmp(base
+ r
, base
+ c
) >= 0)
352 swap(base
+ r
, base
+ c
, size
);
357 for (i
= n
- size
; i
>= 0; i
-= size
) {
358 swap(base
, base
+ i
, size
);
359 for (r
= 0; r
* 2 + size
< i
; r
= c
) {
361 if (c
< i
- size
&& cmp(base
+ c
, base
+ c
+ size
) < 0)
363 if (cmp(base
+ r
, base
+ c
) >= 0)
365 swap(base
+ r
, base
+ c
, size
);
370 /* Create a new _stp_module and load the symbols */
371 static struct _stp_module
*_stp_load_module_symbols (struct _stp_module
*imod
, uint32_t unwind_len
)
374 struct module
*m
= (struct module
*)imod
->module
;
375 struct _stp_module
*mod
= NULL
;
379 kbug(DEBUG_SYMBOLS
, "imod->module is NULL\n");
382 if (try_module_get(m
)) {
384 mod
= _stp_alloc_module_from_module(m
, unwind_len
);
387 errk("failed to allocate memory for module.\n");
391 strlcpy(mod
->name
, imod
->name
, STP_MODULE_NAME_LEN
);
392 mod
->module
= imod
->module
;
393 mod
->text
= imod
->text
;
394 mod
->data
= imod
->data
;
395 mod
->num_sections
= imod
->num_sections
;
396 mod
->sections
= imod
->sections
;
397 mod
->text_size
= m
->core_text_size
;
398 rwlock_init(&mod
->lock
);
400 /* now copy all the symbols we are interested in */
401 dataptr
= mod
->symbol_data
;
402 for (i
=0; i
< m
->num_symtab
; i
++) {
403 char *str
= (char *)(m
->strtab
+ m
->symtab
[i
].st_name
);
404 if (*str
!= '\0' && _stp_sym_type_ok(m
->symtab
[i
].st_info
)) {
405 mod
->symbols
[num
].symbol
= dataptr
;
406 mod
->symbols
[num
].addr
= m
->symtab
[i
].st_value
;
407 while (*str
) *dataptr
++ = *str
++;
414 /* sort symbols by address */
415 _stp_sort (mod
->symbols
, num
, sizeof(struct _stp_symbol
), _stp_compare_addr
, _stp_swap_symbol
);
420 /* Remove any old module info from our database */
421 static void _stp_module_exists_delete (struct _stp_module
*mod
)
425 /* remove any old modules with the same name */
426 for (num
= 1; num
< _stp_num_modules
; num
++) {
427 if (strcmp(_stp_modules
[num
]->name
, mod
->name
) == 0) {
428 dbug(DEBUG_SYMBOLS
, "found existing module with name %s. Deleting.\n", mod
->name
);
429 _stp_del_module(_stp_modules
[num
]);
434 /* remove modules with overlapping addresses */
435 for (num
= 1; num
< _stp_num_modules
; num
++) {
436 if (mod
->text
+ mod
->text_size
< _stp_modules_by_addr
[num
]->text
)
438 if (mod
->text
< _stp_modules_by_addr
[num
]->text
439 + _stp_modules_by_addr
[num
]->text_size
) {
440 dbug(DEBUG_SYMBOLS
, "New module %s overlaps with old module %s. Deleting old.\n",
441 mod
->name
, _stp_modules_by_addr
[num
]->name
);
442 _stp_del_module(_stp_modules_by_addr
[num
]);
448 static int _stp_ins_module(struct _stp_module
*mod
)
450 int i
, num
, res
, ret
= 0;
453 // kbug(DEBUG_SYMBOLS, "insert %s\n", mod->name);
457 _stp_module_exists_delete(mod
);
459 /* check for overflow */
460 if (_stp_num_modules
== STP_MAX_MODULES
) {
461 errk("Exceeded the limit of %d modules\n", STP_MAX_MODULES
);
466 /* insert alphabetically in _stp_modules[] */
467 for (num
= 1; num
< _stp_num_modules
; num
++)
468 if (strcmp(_stp_modules
[num
]->name
, mod
->name
) > 0)
470 for (i
= _stp_num_modules
; i
> num
; i
--)
471 _stp_modules
[i
] = _stp_modules
[i
-1];
472 _stp_modules
[num
] = mod
;
474 /* insert by text address in _stp_modules_by_addr[] */
475 for (num
= 1; num
< _stp_num_modules
; num
++)
476 if (mod
->text
< _stp_modules_by_addr
[num
]->text
)
478 for (i
= _stp_num_modules
; i
> num
; i
--)
479 _stp_modules_by_addr
[i
] = _stp_modules_by_addr
[i
-1];
480 _stp_modules_by_addr
[num
] = mod
;
490 /* Called from procfs.c when a STP_MODULE msg is received */
491 static int _stp_do_module(const char __user
*buf
, int count
)
493 struct _stp_msg_module tmpmod
;
494 struct _stp_module mod
, *m
;
495 unsigned i
, section_len
;
497 if (count
< (int)sizeof(tmpmod
)) {
498 errk("expected %d and got %d\n", (int)sizeof(tmpmod
), count
);
501 if (copy_from_user ((char *)&tmpmod
, buf
, sizeof(tmpmod
)))
504 section_len
= count
- sizeof(tmpmod
) - tmpmod
.unwind_len
;
505 if (section_len
<= 0) {
506 errk("section_len = %d\n", section_len
);
509 dbug(DEBUG_SYMBOLS
, "Got module %s, count=%d section_len=%d unwind_len=%d\n",
510 tmpmod
.name
, count
, section_len
, tmpmod
.unwind_len
);
512 strcpy(mod
.name
, tmpmod
.name
);
513 mod
.module
= tmpmod
.module
;
514 mod
.text
= tmpmod
.text
;
515 mod
.data
= tmpmod
.data
;
516 mod
.num_sections
= tmpmod
.num_sections
;
518 /* copy in section data */
519 mod
.sections
= _stp_kmalloc(section_len
);
520 if (mod
.sections
== NULL
) {
521 errk("unable to allocate memory.\n");
524 if (copy_from_user ((char *)mod
.sections
, buf
+sizeof(tmpmod
), section_len
)) {
525 _stp_kfree(mod
.sections
);
528 for (i
= 0; i
< mod
.num_sections
; i
++) {
529 mod
.sections
[i
].symbol
=
530 (char *)((long)mod
.sections
[i
].symbol
531 + (long)((long)mod
.sections
+ mod
.num_sections
* sizeof(struct _stp_symbol
)));
535 for (i
= 0; i
< mod
.num_sections
; i
++)
536 _dbug("section %d (stored at %p): %s %lx\n", i
, &mod
.sections
[i
], mod
.sections
[i
].symbol
, mod
.sections
[i
].addr
);
539 /* load symbols from tmpmod.module to mod */
540 m
= _stp_load_module_symbols(&mod
, tmpmod
.unwind_len
);
542 _stp_kfree(mod
.sections
);
546 dbug(DEBUG_SYMBOLS
, "module %s loaded. Text=%p text_size=%u\n", m
->name
, (int64_t)m
->text
, m
->text_size
);
547 /* finally copy unwind info */
548 if (copy_from_user (m
->unwind_data
, buf
+sizeof(tmpmod
)+section_len
, tmpmod
.unwind_len
)) {
550 _stp_kfree(mod
.sections
);
553 m
->unwind_data_len
= tmpmod
.unwind_len
;
555 if (_stp_ins_module(m
) < 0) {
563 static int _stp_ctl_send (int type
, void *data
, int len
);
565 static int _stp_module_load_notify(struct notifier_block
* self
, unsigned long val
, void * data
)
567 struct module
*mod
= (struct module
*)data
;
568 struct _stp_module rmod
;
571 case MODULE_STATE_COMING
:
572 dbug(DEBUG_SYMBOLS
, "module %s load notify\n", mod
->name
);
573 strlcpy(rmod
.name
, mod
->name
, STP_MODULE_NAME_LEN
);
574 _stp_ctl_send(STP_MODULE
, &rmod
, sizeof(struct _stp_module
));
577 errk("module loaded? val=%ld\n", val
);
582 static struct notifier_block _stp_module_load_nb
= {
583 .notifier_call
= _stp_module_load_notify
,
586 #endif /* _SYMBOLS_C_ */