模块API之lookup_module_symbol_name

来源:互联网 发布:it职业培训 编辑:程序博客网 时间:2024/06/09 07:25
int lookup_module_symbol_name(unsigned long addr, char *symname) 用于返回addr 对应symbol的name使用的例子如下:int lookup_symbol_name(unsigned long addr, char *symname){symname[0] = '\0';symname[KSYM_NAME_LEN - 1] = '\0';if (is_ksym_addr(addr)) {unsigned long pos;pos = get_symbol_pos(addr, NULL, NULL);/* Grab name */kallsyms_expand_symbol(get_symbol_offset(pos),       symname, KSYM_NAME_LEN);return 0;}/* See if it's in a module. */return lookup_module_symbol_name(addr, symname);}其源码分享如下:int lookup_module_symbol_name(unsigned long addr, char *symname){struct module *mod;//在查找modules 这个list的时候,一定要用preempt_disable()/preempt_enable()来禁止内核抢占preempt_disable();list_for_each_entry_rcu(mod, &modules, list) {// 只查找活动的模块,因此如果模块的state等于MODULE_STATE_UNFORMED就跳过这个模块if (mod->state == MODULE_STATE_UNFORMED)continue;//查看这个地址是否在模块的init和core 段中if (within_module(addr, mod)) {const char *sym;//得到这个地址对应的symbol,get_ksymbol 之前的博文分析过,除了能返回当前addr对应的symbol外,还能返回size和offset,由于这里我们用不到,因此直接传NULLsym = get_ksymbol(mod, addr, NULL, NULL);if (!sym)goto out;//由于get_ksymbol得到的symbol是在module的init和core 段,因此通过strlcpy 将这个子串copy到用户的buffer symname 中.strlcpy(symname, sym, KSYM_NAME_LEN);preempt_enable();return 0;}}out:preempt_enable();return -ERANGE;}