模块API之each_symbol_section

来源:互联网 发布:各国域名缩写 编辑:程序博客网 时间:2024/06/09 04:33
bool each_symbol_section(bool (*fn)(const struct symsearch *arr,    struct module *owner,    void *data), void *data);函数用于在kernel中所有的symbol的区域执行fn这个函数,目前只有看到在find_symbol 这个函数中使用,用于找到对应的symbolconst struct kernel_symbol *find_symbol(const char *name,struct module **owner,const s32 **crc,bool gplok,bool warn){struct find_symbol_arg fsa;fsa.name = name;fsa.gplok = gplok;fsa.warn = warn;if (each_symbol_section(find_symbol_in_section, &fsa)) {if (owner)*owner = fsa.owner;if (crc)*crc = fsa.crc;return fsa.sym;}pr_debug("Failed to find symbol %s\n", name);return NULL;}其源码分析如下:bool each_symbol_section(bool (*fn)(const struct symsearch *arr,    struct module *owner,    void *data), void *data){struct module *mod;//非模块的symbol的范围static const struct symsearch arr[] = {{ __start___ksymtab, __stop___ksymtab, __start___kcrctab,  NOT_GPL_ONLY, false },{ __start___ksymtab_gpl, __stop___ksymtab_gpl,  __start___kcrctab_gpl,  GPL_ONLY, false },{ __start___ksymtab_gpl_future, __stop___ksymtab_gpl_future,  __start___kcrctab_gpl_future,  WILL_BE_GPL_ONLY, false },#ifdef CONFIG_UNUSED_SYMBOLS{ __start___ksymtab_unused, __stop___ksymtab_unused,  __start___kcrctab_unused,  NOT_GPL_ONLY, true },{ __start___ksymtab_unused_gpl, __stop___ksymtab_unused_gpl,  __start___kcrctab_unused_gpl,  GPL_ONLY, true },#endif};module_assert_mutex_or_preempt();// 首先搜索非模块的symbolif (each_symbol_in_section(arr, ARRAY_SIZE(arr), NULL, fn, data))return true;//模块的symbol的范围list_for_each_entry_rcu(mod, &modules, list) {struct symsearch arr[] = {{ mod->syms, mod->syms + mod->num_syms, mod->crcs,  NOT_GPL_ONLY, false },{ mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,  mod->gpl_crcs,  GPL_ONLY, false },{ mod->gpl_future_syms,  mod->gpl_future_syms + mod->num_gpl_future_syms,  mod->gpl_future_crcs,  WILL_BE_GPL_ONLY, false },#ifdef CONFIG_UNUSED_SYMBOLS{ mod->unused_syms,  mod->unused_syms + mod->num_unused_syms,  mod->unused_crcs,  NOT_GPL_ONLY, true },{ mod->unused_gpl_syms,  mod->unused_gpl_syms + mod->num_unused_gpl_syms,  mod->unused_gpl_crcs,  GPL_ONLY, true },#endif};if (mod->state == MODULE_STATE_UNFORMED)continue;// 搜索模块的symbolif (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data))return true;}return false;}这个函数的实现可以分为两部分,kernel 中的symbol 分别模块的symbol 和 非模块的symbol,其范围分别从两个arr 数组中可以得到。再得到这两种symbol保存的区域后调用each_symbol_in_section 在每种symbol 区域执行fn函数static bool each_symbol_in_section(const struct symsearch *arr,   unsigned int arrsize,   struct module *owner,   bool (*fn)(const struct symsearch *syms,      struct module *owner,      void *data),   void *data){unsigned int j;for (j = 0; j < arrsize; j++) {if (fn(&arr[j], owner, data))return true;}return false;如果fn函数返回ture,则each_symbol_section也返回ture

原创粉丝点击