[EMAIL PROTECTED] said:
>  You need it to dynamically bind to another module if its loaded and
> still be loadable if that module/facility is not present. Its dynamic
> linking for kernel modules  

However, in order for get_module_symbol() to be safe, it needs to 
increase the use count of the module in which it finds the symbol, and the 
corresponding put_module_symbol() function has to be provided. This was 
done in 2.4 a while ago. Patch for 2.2 attached.

Index: kernel/ksyms.c
===================================================================
RCS file: /inst/cvs/linux/kernel/ksyms.c,v
retrieving revision 1.13
diff -u -r1.13 ksyms.c
--- kernel/ksyms.c      2000/10/16 09:43:22     1.13
+++ kernel/ksyms.c      2000/10/19 08:18:08
@@ -81,6 +81,7 @@
 
 #ifdef CONFIG_MODULES
 EXPORT_SYMBOL(get_module_symbol);
+EXPORT_SYMBOL(put_module_symbol);
 #endif
 EXPORT_SYMBOL(get_options);
 
Index: kernel/module.c
===================================================================
RCS file: /inst/cvs/linux/kernel/module.c,v
retrieving revision 1.2
diff -u -r1.2 module.c
--- kernel/module.c     2000/06/07 10:00:30     1.2
+++ kernel/module.c     2000/10/19 08:18:08
@@ -952,7 +952,9 @@
  * Gets the address for a symbol in the given module.  If modname is
  * NULL, it looks for the name in any registered symbol table.  If the
  * modname is an empty string, it looks for the symbol in kernel exported
- * symbol tables.
+ * symbol tables. Increase the usage count of the module in which the
+ * symbol was found - it's the only way we can guarantee that it's still
+ * there by the time our caller actually uses it.
  */
 unsigned long
 get_module_symbol(char *modname, char *symname)
@@ -969,12 +971,29 @@
                                i > 0; --i, ++sym) {
 
                                if (strcmp(sym->name, symname) == 0) {
+                                       __MOD_INC_USE_COUNT(mp);
                                        return sym->value;
                                }
                        }
                }
        }
        return 0;
+}
+
+/* Decrease the use count of the module containing a symbol with the 
+ * address passed.
+ */
+void put_module_symbol(unsigned long addr)
+{
+       struct module *mp;
+
+       for (mp = module_list; mp; mp = mp->next) {
+               if (addr >= (unsigned long)mp &&
+                   addr < (unsigned long)mp + mp->size) {
+                       __MOD_DEC_USE_COUNT(mp);
+                       return;
+               }
+       }
 }
 
 #else          /* CONFIG_MODULES */
Index: include/linux/module.h
===================================================================
RCS file: /inst/cvs/linux/include/linux/module.h,v
retrieving revision 1.3
diff -u -r1.3 module.h
--- include/linux/module.h      2000/09/11 08:34:17     1.3
+++ include/linux/module.h      2000/10/19 08:19:48
@@ -144,8 +144,10 @@
 /* Find a symbol exported by the kernel or another module */
 #ifndef CONFIG_MODULES
 static inline unsigned long get_module_symbol(char *A, char *B) { return 0; };
+static inline void put_module_symbol(unsigned long A) { };
 #else
 extern unsigned long get_module_symbol(char *, char *);
+extern void put_module_symbol(unsigned long);
 #endif
 #if defined(MODULE) && !defined(__GENKSYMS__)
 


--
dwmw2


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/

Reply via email to