why symbol exported from linux kernel cannot be used by module? - linux

I define a variablity in kernel .c file,for example socket.c,and export it as follows:
int abcdefg;
EXPORT_SYMBOL(abcdefg);
Then compiles it with "sudo make bzImage" and reboot.But when I use it in my own module,when insmod the module ,it says "Unknown symbol in module".
So I go to see the symbol list. When use
cat /proc/kallsyms | grep "abcdefg"
there is nothing.
When use
nm vmlinux | grep "abcdefg"
there is c1d2b700 B abcdefg
How should I do to use the symbol in my own module?
https://i.stack.imgur.com/Zv5SM.png

It sounds like you're not actually running the new kernel. – Jonathon Reinhart
Yes,you are right! I forget to update the kernel with "make install". – jenny

Related

How to determine the configuration of gcc from a bash script?

I have a bash script that compiles a program as well on older versions of Ubuntu (14.04.x and 16.04.x) than on the last one (18.04.x) and on other distributions (Arch, CentOS, Debian, Fedora, etc.) and therefore... with different gcc settings.
Then, to obtain an executable that can be launched (among other ways) by a double click, I must compile this program without the "-no-pie" option with older versions of gcc setting (Ubuntu 14.04.x and 16.04.x) when I have to use this option "=no-pie" for the new version of the gcc 7.3 setting (on Ubuntu 18.04.x).
The problem is that on the last Ubuntu release (18.04.x) and its derivatives (Kubuntu, Xbuntu, etc. and maybe with other distributions) with the new configuration of gcc (7.3) having the option "--enable-default-pie", if I compile my program without the option "-no-pie", the result is that the file created is an executable which is of the "shared library" type which can not be launched by a double click.
My question is either:
a) Is there a command that allows me to determine from a bash script if gcc is configured with the "--enable-default-pie" setting?
b) if not, is there a command that allows me to determine from a bash script if the compiled file is of the "shared library" or "executable" type?
For this second option, a solution could be how to save the response of "gcc -v" in a .txt file and check if there is the "--enable-default-pie" string but I've absolutely no clue how to do it.
If I there is not an answer to my first option, the second option (it is true less elegant but just as effective) would allow me to compile my program first without the "-no-pie" option, then check the status of such a created executable and if the result is a "shared library", of restart this compilation this time using the option "-no-pie" for, in one case as in the other, get an executable that can be launched by a double click whatever the setting of gcc may be.
Thank you in advance for your time, ideas and suggestions.
Best regards.
The recommend way to check for PIE support is to compile C code like this
#if defined __PIC__ || defined __pic__ || defined PIC || defined pic
# error PIC is default.
#endif
with the requested compiler flags and check whether there is an error. If you need special treatment for PIE, this will recognize PIE if it has been specified through the CC or CFLAGS variables, even if is not immediately apparent there. For example, for technical reasons, Fedora hides the PIE flags behind a -specs argument.
Yes, you can check GCC build options with gcc -v or gcc -###
In order to have pretty print you can use:
gcc -### -E 2>&1 | grep "Configured with" | sed 's/--/\n--/g'
So bash oneliner to say you have pie or not may be:
if [[ -n "`gcc -v -E 2>&1 | grep 'Configured with' | sed 's/--/\n--/g' | grep enable-default-spie`" ]]; then echo "PIE DEFAULT"; else echo "PIE NOT DEFAULT"; fi
To check file type just use file command, eg.:
file /usr/bin/x86_64-linux-gnu-gcc-7
/usr/bin/x86_64-linux-gnu-gcc-7: ELF 64-bit LSB executable,
x86-64, version 1 (SYSV), dynamically linked, interpreter
/lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0,
BuildID[sha1]=02ac46ba938c15f55f6fab165133e0f527bc2197, stripped
file /usr/lib/libchm.so.1.0.0
/usr/lib/libchm.so.1.0.0: ELF 64-bit LSB shared object, x86-64,
version 1 (SYSV), dynamically linked,
BuildID[sha1]=7c603d9a0771b5bfd5b869b4446e2f78ef13802a, stripped
File type function
function whatfile { file $1 -i | grep application | sed 's/^.*application\/x-//g;s/,.*$//g'; }
Example output:
aaa#xxx:~ $ whatfile /boot/grub/grub.conf
aaa#xxx:~ $ whatfile /usr/lib/libnss3.so
sharedlib
aaa#xxx:~ $ whatfile /bin/zcat
executable
Unfortunately, comments don't allow CR+LF (to show pre-formatted text).
Below is my formatted translation of your gcc setting command:
check_gcc_setting()
{
if [ -n "`gcc -v -E 2>&1 | grep 'Configured with' | sed 's/--/\n--/g' | grep enable-default-pie`" ]
then
GCC_SETTING="1"
else
GCC_SETTING="0"
fi
read -p "The gcc setting is $GCC_SETTING " GCCRESULT
}
Below is the result:
whatfile { file $1 -i | grep application | sed 's/^.*application\/x-//g;s/,.*$//g'; }
-bash: syntax error near unexpected token `}'

linux kallsyms R symbol not showing

I wan't to find the kernel address of system call table.
I usually do this by grepping sys_call
but in one system, I can see the address
but in other, it doesn't show the entry.
root#ubuntu:~# cat /proc/kallsyms | grep sys_call
ffffffff8122aa90 t proc_sys_call_handler
ffffffff81726432 t ret_from_sys_call
ffffffff81726644 T int_ret_from_sys_call
ffffffff81728146 t sysexit_from_sys_call
ffffffff81728386 t sysretl_from_sys_call
ffffffff8172858e t ia32_ret_from_sys_call
**ffffffff81801400 R sys_call_table**
ffffffff81809cc0 R ia32_sys_call_table
root#ubuntu:~#
no system call table... why not showing the R type symbol??
/ $ cat /proc/kallsyms | grep sys_call
ffffffff8119c230 t proc_sys_call_handler
ffffffff817a1a57 t ret_from_sys_call
ffffffff817a1c50 T int_ret_from_sys_call
ffffffff817a2cb8 t sysexit_from_sys_call
ffffffff817a2ed8 t sysretl_from_sys_call
ffffffff817a30be t ia32_ret_from_sys_call
/ $
/ $
in what case does this could happen?
some advice would be nice
thank you
You should look into the version of the kernel in both cases, check with uname -r.
This was initially exported in the earlier versions of the kernel 2.4.x. This initially had "EXPORT_SYMBOL(sys_call_table);" line from linux/kernel/ksyms.c for
sys_call_table from being exported properly and later was made static and removed IMU.
Now this has been exported again in of some of latest kernels (in some version > 3.3.x). I would recommend digging into the LXR to check out the details.
You need to check whether your current kernel is compiled with the option CONFIG_KALLSYMS_ALL=y

multi function symbols in ELF library file

When i dump symbols in libmpich.a, i got this:
$ nm /usr/MPICH-install/lib/libmpich.a | grep PMPI_File_open
00000000 T PMPI_File_open
U PMPI_File_open
Can anyone explain this, thx.
Can anyone explain this
The libmpich.a contains at least two object files. One of these defines the function (T). The other one references it (U).
You can see this by running:
nm -A /usr/MPICH-install/lib/libmpich.a | grep PMPI_File_open

Location of Linux Kernel Module

Is there any utiliy, that shows where the location of the module I have loaded.
If you want to know the base memory address for a module in the kernel's virtual address space, it can be found as the last field in /proc/modules; search for the module in question:
$ grep '^ext3' /proc/modules
ext3 125513 1 - Live 0xf88ce000
If you want to know the file path it was loaded from, the original path is not actually stored anywhere, but you can ask modprobe to search for the module again and display the path using modprobe -l:
$ /sbin/modprobe -l ext3
/lib/modules/2.6.18-194.el5PAE/kernel/fs/ext3/ext3.ko
Assuming you haven't changed anything in the module search path in the intervening time, this should give you the original load path.
EDIT:
As of 2015, the information isn't correct (not only that ext4 doesn't exist as a kernel module). Get information about the module, including the path of the image with:
modinfo floppy
No. This information is not retained when the module is loaded.
The information above isn't correct, for 2015.
modinfo will now give you information about the module. for example:
modinfo floppy

ld cannot find library that is installed

I'm sitting on an OpenSuse 11.1 x64 Box and I have a module that uses sigc++. When linking like this:
g++ [a lot of o's, L's and l's] -lsigc-2.0
I get
/usr/lib64/gcc/x86_64-suse-linux/4.3/../../../../x86_64-suse-linux/bin/ld: cannot find -lsigc-2.0
However the library is there.
In the filesystem:
$ sudo find / -name "libsigc-2.0*"
/usr/lib64/libsigc-2.0.so.0.0.0
/usr/lib64/libsigc-2.0.so.0
/usr/lib64/libsigc-2.0.so
In ld.so.conf I have:
/usr/lib64
And when invoking ldconfig:
$ ldconfig -v | grep sigc
libsigc-2.0.so.0 -> libsigc-2.0.so.0.0.0
Why?
I'm so dumb. It's an old codebase and just before the -lsigc-2.0 statement I had a
-Wl,-Bstatic
Obviously, there are no static librarys for libsigc (anymore).
It is possible that libsigc-2.0.so was linked with an SONAME other than libsigc-2.0.
objdump -p /usr/lib64/libsigc-2.0.so | grep SONAME
If you see something unexpected, e.g. libsigc, you may need to create an additional symlink with that name.

Resources