aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
authorAlessio Igor Bogani <abogani@kernel.org>2011-04-20 05:10:52 -0400
committerRusty Russell <rusty@rustcorp.com.au>2011-05-19 03:25:27 -0400
commit403ed27846aa126ecf0b842b5b179c506b9d989c (patch)
treed47ce51b2548c80237e193b99ec159e8ef59470a /kernel/module.c
parent1a94dc35bc5c166d89913dc01a49d27a3c21a455 (diff)
module: Use the binary search for symbols resolution
Takes advantage of the order and locates symbols using binary search. This work was supported by a hardware donation from the CE Linux Forum. Signed-off-by: Alessio Igor Bogani <abogani@kernel.org> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Tested-by: Dirk Behme <dirk.behme@googlemail.com>
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/kernel/module.c b/kernel/module.c
index e8aa462301e7..d1db8eb56ad4 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -57,6 +57,7 @@
57#include <linux/kmemleak.h> 57#include <linux/kmemleak.h>
58#include <linux/jump_label.h> 58#include <linux/jump_label.h>
59#include <linux/pfn.h> 59#include <linux/pfn.h>
60#include <linux/bsearch.h>
60 61
61#define CREATE_TRACE_POINTS 62#define CREATE_TRACE_POINTS
62#include <trace/events/module.h> 63#include <trace/events/module.h>
@@ -363,17 +364,27 @@ static bool check_symbol(const struct symsearch *syms,
363 return true; 364 return true;
364} 365}
365 366
367static int cmp_name(const void *va, const void *vb)
368{
369 const char *a;
370 const struct kernel_symbol *b;
371 a = va; b = vb;
372 return strcmp(a, b->name);
373}
374
366static bool find_symbol_in_section(const struct symsearch *syms, 375static bool find_symbol_in_section(const struct symsearch *syms,
367 struct module *owner, 376 struct module *owner,
368 void *data) 377 void *data)
369{ 378{
370 struct find_symbol_arg *fsa = data; 379 struct find_symbol_arg *fsa = data;
371 unsigned int i; 380 struct kernel_symbol *sym;
381
382 sym = bsearch(fsa->name, syms->start, syms->stop - syms->start,
383 sizeof(struct kernel_symbol), cmp_name);
384
385 if (sym != NULL && check_symbol(syms, owner, sym - syms->start, data))
386 return true;
372 387
373 for (i = 0; i < syms->stop - syms->start; i++) {
374 if (strcmp(syms->start[i].name, fsa->name) == 0)
375 return check_symbol(syms, owner, i, data);
376 }
377 return false; 388 return false;
378} 389}
379 390