模块API之symbol_put_addr

来源:互联网 发布:fm调频发射器软件 编辑:程序博客网 时间:2024/05/29 08:05
void symbol_put_addr(void *addr)的作用是根据addr找到所在的模块,然后将模块的应用计数减1这里有假定addr是一个函数的地址。其源码如下:/* Note this assumes addr is a function, which it currently always is. */void symbol_put_addr(void *addr){struct module *modaddr;//将addr由void 类型转为unsigned long,这里的dereference_function_descriptor 是函数,只是说明addr 必须是函数的地址unsigned long a = (unsigned long)dereference_function_descriptor(addr);//看地址a是否在kernel的text 段,如果是的话,就不是模块symbol了,就没有必要再查找这个地址对应的模块了if (core_kernel_text(a))return;/* * Even though we hold a reference on the module; we still need to * disable preemption in order to safely traverse the data structure. */preempt_disable();//根据地址a找到对应的模块modaddr,然后调用module_put 将模块的引用计数减1modaddr = __module_text_address(a);BUG_ON(!modaddr);module_put(modaddr);preempt_enable();}看看dereference_function_descriptor的实现/* function descriptor handling (if any).  Override * in asm/sections.h */#ifndef dereference_function_descriptor#define dereference_function_descriptor(p) (p)#endif看看如何通过core_kernel_text 判断地址在kernel的text 段static inline int init_kernel_text(unsigned long addr){if (addr >= (unsigned long)_sinittext &&    addr < (unsigned long)_einittext)return 1;return 0;}int notrace core_kernel_text(unsigned long addr){if (addr >= (unsigned long)_stext &&    addr < (unsigned long)_etext)return 1;if (system_state < SYSTEM_RUNNING &&    init_kernel_text(addr))return 1;return 0;}可见只要地址在_stext~_etext,或者当kernel还在没有runing起来的时候在_sinittext~_einittext。这两个范围就算地址是在kernel的text段。

原创粉丝点击