Loading LKM get undefined symbol error - linux-kernel

when i try to load my Linux kernel module i get an error about an undefined symbol (obviously i get a warning during make). In particular i need to use the macro pgd_offset_k in my module (defined in asm/pgtable.h). This is expanded in pgd_offset(&init_mm, (address)). The undefined symbol is init_mm. I have also verified its presence in /proc/kallsyms:
$ cat /proc/kallsyms |grep -w init_mm
c07d49a0 D init_mm
Any ideas?

init_mm is not exported past 2.6.29, on the basis that no out-of-tree code should be using it. Can you not do without pgd_offset_k?

Related

How do I link SDL .a files with GCC?

Not a duplicate; Answers on various forums didn't fix the problem.
I am running GCC through commands and I am getting undefined references from SDL even though it appears like I linked SDL correctly, how do I stop from getting those undefined references ?
I do not get undefined references from mingw, just SDL.
This is my command: (all the libraries are being located by GCC from what I can tell)
gcc main.c ^
-o app.exe ^
-I "C:\__coding\tools\SDL2-2.0.10\x86_64-w64-mingw32\include\SDL2" ^
-L "C:\__coding\tools\MinGW\lib\" ^
-l "libmingw32.a" ^
-L "C:\__coding\tools\SDL2-2.0.10\x86_64-w64-mingw32\lib" ^
-l "libSDL2main.a" ^
-l "libSDL2.a"
This is the output:
C:...\main.c:(.text+0xe): undefined reference to 'SDL_Init'
C:...\main.c:(.text+0x13): undefined reference to 'SDL_Quit'
c:/__coding/tools/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: C:\Users\...\AppData\Local\Temp\ccqsLSRk.o: bad reloc address 0x20 in section '.eh_frame'
c:/__coding/tools/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
main.c includes SDL.h and just runs SDL_Init() and SDL_Quit().
I also get the classic undefined reference to "winmain" when I remove SDL_Init() and SDL_Quit().
Thanks alot.

Getting "cannot find symbol .... while executing load ..." error when trying to run Hello World as a C extension (dll) example

I have used the C code from the following verbatim: https://wiki.tcl-lang.org/page/Hello+World+as+a+C+extension
/*
* hello.c -- A minimal Tcl C extension.
*/
#include <tcl.h>
static int
Hello_Cmd(ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
Tcl_SetObjResult(interp, Tcl_NewStringObj("Hello, World!", -1));
return TCL_OK;
}
/*
* Hello_Init -- Called when Tcl loads your extension.
*/
int DLLEXPORT
Hello_Init(Tcl_Interp *interp)
{
if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) {
return TCL_ERROR;
}
/* changed this to check for an error - GPS */
if (Tcl_PkgProvide(interp, "Hello", "1.0") == TCL_ERROR) {
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "hello", Hello_Cmd, NULL, NULL);
return TCL_OK;
}
My command for compiling is nearly verbatim except for the last character, indicating Tcl version 8.6 rather than 8.4, and it compiles without error:
gcc -shared -o hello.dll -DUSE_TCL_STUBS -I$TCLINC -L$TCLLIB -ltclstub86
Then I created the following Tcl program:
load hello.dll Hello
puts "got here"
But when running it with tclsh get the following error:
cannot find symbol "Hello_Init"
while executing
"load ./hello.dll Hello"
(file "hello.tcl" line 1)
So I am essentially following a couple of suggestions from Donal Fellows answer here: cannot find symbol "Embeddedrcall_Init" The OP there however commented that, like me, the suggestion(s) hadn't resolved their issue. One thing that I didn't try from that answer was "You should have an exported (extern "C") function symbol in your library" -- could that be the difference maker? Shouldn't it have been in the example all along then?
At the suggestion of somebody on comp.lang.tcl I found "DLL Export Viewer" but when I run it against the DLL it reports 0 functions found :( What am I doing wrong?
Could it be an issue with MinGW/gcc on Windows, and I need to bite the bullet and do this with Visual Studio? That's overkill I'd like to avoid if possible.
The core of the problem is that your function Hello_Init is not ending up in the global symbol table exported by the resulting DLL. (Some linkers would put such things in as _Hello_Init instead of Hello_Init; Tcl adapts to them transparently.) The symbol must be there for Tcl's load command to work: without it, there's simply no consistent way to tell your extension code what the Tcl_Interp context handle is (which allows it to make commands, variables, etc.)
(If you'd been working with C++, one of the possible problem is a missing extern "C" whose actual meaning is to turn off name mangling. That's probably not the problem here.)
Since you are on Windows — going by the symbols in your DLL, such as EnterCriticalSection and GetLastError — the problem is probably linked to exactly how you are linking. I'm guessing that Tcl is defining your function to have __declspec(dllexport) (assuming you've not defined STATIC_BUILD, which absolutely should not be used when building a DLL) and yet that's not getting respected. Assuming you're using a modern-enough version of GCC… which you probably are.
I'm also going through the process of how to build tcl extensions in C and had exactly the same problem when working though this same example using tcl 8.6.
i.e. I was compiling using MinGW GCC (64-bit), and used the following:
gcc -shared -o hello.dll -DUSE_TCL_STUBS "-IC:\\ActiveTcl\\include" "-LC:\\ActiveTcl\\lib" -ltclstub86
And like the OP I got no compile error, but when loading the dll at a tclsh prompt tcl complained :
'cannot find symbol "Hello_Init"'
I can't say that I understand, but I was able to find a solution that works thanks to some trial and error, and some information on the tcl wiki here
https://wiki.tcl-lang.org/page/Building+Tcl+DLL%27s+for+Windows
In my case I had to adjust the compiler statement to the following
gcc -shared -o hello.dll hello.c "-IC:\\ActiveTcl\\include" "-LC:\\ActiveTcl\\bin" -ltcl86t
Obviously those file paths are specific to my system, but basically
I had to add an explicit reference to the .c file
I had to include the tcl86t dll library from the tcl bin directory
I had to remove the -DUSE_TCL_STUBS flag ( meaning that the references -LC:\\ActiveTcl\\lib and -ltclstub86 could also be removed)
(attempting to use the -DUSE_TCL_STUBS flag caused the compiler to complain with C:\ActiveTcl\lib/tclstub86.lib: error adding symbols: File format not recognized )
This successfully compiled a dll that I could load, and then call the hello function to print my 'Hello World' message.
Something else I stumbled over, and which wasn't immediately obvious:
reading https://www.tcl.tk/man/tcl8.6/TclCmd/load.htm, tcl epxects to find an 'init' function based on a certain naming convention.
if the C extension does not define a package name then the name of that init function will be derived from the dll filename.
This caused a few problems for me (when compiling via Eclipse IDE), as the dll name was being automatically determined from the eclipse projet name.
For example, if I recompile the same example, but call the .dll something else, eg.
gcc -shared -o helloWorldExenstion.dll hello.c "-IC:\\ActiveTcl\\include" "-LC:\\ActiveTcl\\bin" -ltcl86t
Then at tclsh prompt:
% load helloWorldExtension
cannot find symbol "Helloworldextension_Init"

'libdenpli.so : undefined reference to symbol 'Tcl_InitStubs'

I am getting 'libdenpli.so : undefined reference to symbol 'Tcl_InitStubs' while creating executable.
When I check with nm, I am getting this output:
nm libdenpli.so | grep Tcl_InitStubs
U denaliTcl_InitStubs
I looked at other machine with different platform where it worked fine. And I seen the output with t:
nm libdenpli.so | grep Tcl_InitStubs
<address> t denaliTcl_InitStubs
What is the difference?
As you can see in nm's manpage:
"t" The symbol is in the text (code) section.
"U" The symbol is undefined.
In other words, your libdenpli.so uses the symbol, but does not define it -- you need to link to the library that defines that symbol as well.
Since the other system's library seems to define it, maybe there are differences on how the libraries are supposed to be linked with, due to version, platform, build options, etc. Try to take a look at the documentation of the library to see how you are supposed to link to it.

init_task symbol not found in /proc/kallsyms (kernel 4.5.4-1-ARCH)

I am trying to locate the address of task_struct of a thread. First of all, I need to get the address of task_struct of the init_task, then I iterate the whole list and finally get the task_struct of a specific thread. The task_struct of the init_task can be easily obtained from /proc/kallsyms by the command
grep "\<init_task\>" /proc/kallsyms.
This worked when I use older kernel version (3.12). But when I switched to newer version (4.5), this idea failed at the very beginning. Because the symbol init_task disappears from /proc/kallsyms. But when I checked the source code, I can see that the symbol init_task is exported (http://lxr.free-electrons.com/source/init/init_task.c?v=4.5#L18). Why it doesn't show up in the /proc/kallsyms? Or is there any other approach to get the address of init_task from user space programs?
Try compiling with CONFIG_KALLSYMS_ALL option set. Without it kallsyms seems to include only symbols from .text and init.text sections: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/scripts/link-vmlinux.sh#n152, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/scripts/kallsyms.c#n250

GHCi linking with cross-calling dynlibs fails on OSX

Setting
Compiler: GHC 7.10.3
I must use two dynamic libraries (libpetsc and libslepc), one of which uses functions from the other. When linking my application, I encounter the following error, which mentions one such symbol (KSPConvergedReasons). NB. my own code does not use this symbol.
user specified .o/.so/.DLL could not be loaded
(dlopen($SLEPC_DIR/arch-darwin-c-debug/lib/libslepc.dylib, 5): Symbol
not found: _KSPConvergedReasons
Referenced from: $SLEPC_DIR/arch-darwin-c-debug/lib/libslepc.dylib
Expected in: flat namespace
in $SLEPC_DIR/arch-darwin-c-debug/lib/libslepc.dylib)
Surely enough, nm -u shows _KSPConvergedReasons as an undefined
symbol (see below).
I don't understand the reason of this behaviour since I first compile
with all the relevant PETSc and SLEPc headers and link against both
.dylibs.
NB:
The symbol in question (KSPConvergedReasons) does exist in the callee library (libpetsc):
$ nm ${PETSC_DIR}/${PETSC_ARCH}/lib/libpetsc.3.7.2.dylib | grep KSPConv
000000000110a652 T _KSPConvergedDefault
0000000001109703 T _KSPConvergedDefaultCreate
000000000110b934 T _KSPConvergedDefaultDestroy
0000000001109a96 T _KSPConvergedDefaultSetUIRNorm
000000000110a074 T _KSPConvergedDefaultSetUMIRNorm
000000000106533d T _KSPConvergedLSQR
0000000001743280 D _KSPConvergedReasons
...
Build + link sequence
Build the C code generated from my own library, which in turn uses headers from the two aforementioned libs:
gcc -c -g -w ${SRCDIR}/Internal/InlineC.c -o ${LIBDIR}/InlineC_c.o -I${PETSC_DIR_ARCH}/include -I${PETSC_DIR}/include -I${SLEPC_DIR_ARCH}/include -I${SLEPC_DIR}/include
Link :
stack exec ghci ${SRCDIR}/Spec.hs ${SRCDIR}/Internal/InlineC.hs ${LIBDIR}/InlineC_c.o -- -isrc/ -L${PETSC_DIR_ARCH}/lib -L${SLEPC_DIR_ARCH}/lib -lpetsc -lmpich -lslepc
Question
Why is this happening and how can I fix this?
Thank you in advance for any pointers,
Marco
Undefined symbols in calling dynlib :
$ nm -u libslepc.3.7.1.dylib | grep KSP
_KSPAppendOptionsPrefix
_KSPConvergedReasons
...

Resources