0

We have written a number of kernel modules and many with exported symbols that all work fine except for 2 symbols (which is baffling). We have exported them as all the others but the 2 symbols are not globally exported once they are inserted into the kernel.

In our C code we have (in wdt.ko):

EXPORT_SYMBOL(WDT_Enable);
EXPORT_SYMBOL(WDT_Disable);

If we run nm on the generated kernel object, they appear correctly:

nm wdt.ko | grep WDT
00000000 T WDT_Enable
00000000 T WDT_Disable

This should mean that those symbols are globally exported. Once we insmod the kernel object:

# insmod wdt.ko
# insmod apphandler.ko
apphandler: Unknown symbol WDT_Enable
apphandler: Unknown symbol WDT_Disable

If we look at the kallsyms:

# cat /proc/kallsyms | grep WDT
c12504dc t WDT_Enable  [wdt]
c12502d8 t WDT_Disable [wdt]

Once they are inside the kernel, they are not global.

We have confirmed that correct file is being inserted into the kernel and that the functions are visible in the same module, but we cannot explain why the symbols suddenly become local and not global like nm suggests.

Does anyone know where our error might be?

m.s.
  • 16,063
  • 7
  • 53
  • 88
user626201
  • 1,623
  • 3
  • 19
  • 36
  • Global *visibility*, shown by `nm` and `/proc/kallsyms`, doesn't mean *availability* for other modules, which is controlled by `EXPORT_SYMBOL`, see e.g. this [answer](http://stackoverflow.com/a/32968237/3440745). Also, for make symbols, defined by one module, being available in another one, `EXPORT_SYMBOL` alone is insufficient. You need either build both modules in the same directory, or use `KBUILD_EXTRA_SYMBOLS` variable in the makefile for the second module: http://stackoverflow.com/a/32949236/3440745. – Tsyvarev Oct 26 '15 at 10:12
  • Yes - agreed with your comments, and as mentioned, our other symbols were all working. Our one C file where WDT was being defined did not include the header file below. We do build all the modules in the same place and we have a "common" build makefile template for each one. – user626201 Oct 26 '15 at 14:02

1 Answers1

1

Ok - shortly after posting the question we noticed that our include paths were missing the module include:

#include <linux/module.h>

The code seemed to compile file without the #include being included and the compiler did not generate errors or complaints but the net effect was that the symbols where not available to subsequent modules.

Since including the header file the symbols indicated above are available to modules and the kernel is able to resolve and execute the code.

user626201
  • 1,623
  • 3
  • 19
  • 36
  • Add this information into your question post (via editing) instead of posting it as an answer (because it is not an answer actually). – Tsyvarev Oct 26 '15 at 09:57
  • Unfortunately it really did resolve our issue. I can't really explain why leaving out the header caused the effect, but including it made the symbols perform as advertised. There were no other changes made other than `#include` – user626201 Oct 26 '15 at 14:04
  • It might work due to the additional cycle of recompilation. Try to remove and reproduce. – 0andriy Oct 26 '15 at 15:47
  • If this modification fixes the problem, what words `but had the above effect` mean? – Tsyvarev Oct 26 '15 at 18:12
  • There were many many many many many many recompilation cycles, and deleting, restoring, reverting, etc. before this question. The above effect was not being able to have the symbols available (i.e. the insmod error). After the `#include` the module inserted correctly and the functions where called correctly. – user626201 Oct 27 '15 at 05:59