how to install debuginfo packages from vmlinux - linux

I am building my own kernel with following options set.
CONFIG_FRAME_POINTER=y
CONFIG_DEBUG_INFO=y
So I assume that the generated vmlinux file will have all the required debuginfo.
I installed that kernel in a machine and put the vmlinux file under /boot/.
However, when I tried to do a perf annotate it does not show the source code along side the assembly code. It only shows the assembly code and c function names not the entire source code(I have tried toggling "s" during annotate).
Here are my perf commands.
#perf record -g -a -e cycles:k sleep 5
#perf report -f -g -s symbol
#perf annotate -f -s <kernel function name> > annotate_<kernel_function>.txt
What am I missing here ? Do I need to install debuginfo packages separately ?
Regards,
Atish

The binrpm-pkg target to build kernel rpm does not generate debuginfo because it disabled generation of debuginfo packages, you can try do this, open scripts/package/mkspec in your kernel source tree, and search for a line echo "%define debug_package %{nil}", comment or remove this line, and try to build again.
The reason is that this line explicitly tell rpmbuild that skip debuginfo packages.
See the link:
https://github.com/torvalds/linux/blob/9256d5a308c95a50c6e85d682492ae1f86a70f9b/scripts/package/mkspec#L45

Related

how to build debuginfo rpm in the kernel 4.19.x

I use the command make rpm-pkg to build debuginfo rpm for kernel(4.19.1), but it didn't work.so I tried to remove #%debug_package{null} in the scripts/package/mkspec and add find_debuginfo.sh xxxx to enable debug module,but after I run the command make rpm-pkg again, I got the debuginfo rpm but it seems abnormal。 the size of the rpm is around 600k which is obviously not correct.
also i found all the 3.10.x version of kernel has the --with=debuginfo parameter to enable the debug module, which is also not work in 4.19.1 version. so i would like to know whether there is any other approach that build the debuginfo rpm.

Linux kernel compile error

I cloned the kernel sources from Linus's github, I made a little modification to the usbhid driver (thats compiles fine as a module, no errors), but if I try to build the whole kernel, I get this error:
AR drivers/gpu/drm/built-in.o
AR drivers/gpu/built-in.o
Makefile:1023: recipe for target 'drivers' failed
make: *** [drivers] Error 2
And thats all nothing specific. What could be the problem?
UPDATE: 9-15-18 This issue is resolved.. The kernel will now compile with the commands I have given below.
Same issue here. 4.19.0-rc3 will not compile on the Threadripper 2990WX. BTW, I am currently running 4.19.0-rc2 with no issues.
These are the commands I used. Please note, I also tried without the LD static flag.
wget https://git.kernel.org/torvalds/t/linux-4.19-rc3.tar.gz && tar -xzf linux-4.19-rc3.tar.gz && cd linux-4.19-rc3 && make -j 64 clean && make -j 64 mrproper && zcat /proc/config.gz >> ./.config && LDFLAGS=--static make -j 64
The issue is in your config file. I have faced the same issue before and and appears to be due to a missing CONFIG option in the .config file generated through make menuconfig.
You need to add these two CONFIG options in your .config file:
CONFIG_EXTRA_FIRMWARE_DIR="lib/firmware"
CONFIG_EXTRA_FIRMWARE="<name_of_firmware_along_with_path>"
In some platforms, the GPU uses firmware that needs to be built-in by stitching it with kernel. This firmware is placed in the directory path provided by CONFIG_EXTRA_FIRMWARE option while building the kernel. And unless we don't provide CONFIG_EXTRA_FIRMWARE_DIR path to tell the kernel where to pick this firmware from, the above build failure occurs.

linking to linux shared libraries

I am trying to install opendkim on amazon linux ec2 instance. When compiling from source I get:
configure: error: no strlcpy/strlcat found
so I installed libbsd from source. once that is installed I can go to the man page of strlcat and strlcpy but I can't access those functions. I verified that the shared libraries are installed. The output of the libbsd install stated to use one of the 4 options:
If you ever happen to want to link against installed libraries in a given directory, LIBDIR, you must either use libtool, and specify the full pathname of the library, or use the `-LLIBDIR' flag during linking and do at least one of the following:
- add LIBDIR to the `LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the `LD_RUN_PATH' environment variable
during linking
- use the `-Wl,-rpath -Wl,LIBDIR' linker flag
- have your system administrator add LIBDIR to `/etc/ld.so.conf'
I ran
export LD_RUN_PATH=/usr/local/lib
export LD_LIBRARY_PATH=/usr/local/lib/
Additionally my /etc/ld.so.conf contains
include ld.so.conf.d/*.conf
and my /etc/ld.so.conf.d/libbsd.conf contains
/usr/local/lib/libbsd
Lastly checking my libbsd library nm -D /usr/local/lib/libbsd.so contains:
000000000000de30 T strlcat
000000000000ded0 T strlcpy
So my questions how do I either, expose strlcat and strlcpy to the command line? Or how to I do the "use the `-Wl,-rpath -Wl,LIBDIR' linker flag" option, or in general what am i doing wrong in linking to shared libraries? Any help is appreciated. Thanks!
So wasn't ever able to link against the libraries but I was able to resolve the dependencies. The binary rpm from centos installed perfectly :
sudo wget http://dl.fedoraproject.org/pub/epel/7/x86_64/l/libbsd-0.6.0-3.el7.x86_64.rpm
sudo yum localinstall ./libbsd-0.6.0-3.el7.x86_64.rpm
sudo wget http://dl.fedoraproject.org/pub/epel/7/x86_64/l/libbsd-devel-0.6.0-3.el7.x86_64.rpm
sudo yum localinstall ./libbsd-devel-0.6.0-3.el7.x86_64.rpm

shared library not found during compilation

So I got several shared libraries that I am trying to permanently install on my Ubuntu system but I am having some difficulty with it.
I want to install the libraries and the headers in a separate folder under /usr/local/lib and /usr/local/include (for example a folder named agony) so it would be clean and removing them would just require that I delete those folders. so it looks something like this:
/usr/local/lib/agony/libbtiGPIO.so
/usr/local/lib/agony/libbtiDSP.so
...
/usr/local/include/agony/GPIO.h
/usr/local/include/agony/DSP.h
...
And I added a file here /etc/ld.so.conf.d/agony.conf which include a line describing the path to the library folder:
$ cat /etc/ld.so.conf.d/agony.conf
/usr/local/lib/agony
and I perform sudo ldconfig to update the library database.
So to double check if the library is found I do ldconfig -p | grep bti* and
I see the following result:
$ ldconfig -p | grep bti
...
libbtiGPIO.so (libc6,x86-64) => /usr/local/lib/agony/libbtiGPIO.so
libbtiDSP.so (libc6,x86-64) => /usr/local/lib/agony/libbtiDSP.so
...
At this point I should be able to use the libraries without specifying the library path. But When I attempt to compile an application without providing the library path (-L) it fails. However, when I supply gcc with the library path ex:
gcc source.c -L /usr/local/lib/agony output -lbtiGPIO -lbtiDSP
it works!!
I don't want to use LD_LIBRARY_PATH environment variable because this library is going to be used everywhere on the system and I don't want other compilers to worry about providing LD_LIBRARY_PATH.
What am I doing wrong here?
At this point I should be able to use the libraries without specifying the library path
Here lies the confusion.
You have built your shared library libbtiGPIO.so (just sticking with that one),
placed it in /usr/local/lib/agony, and updated the ldconfig database accordingly.
The effect of that is when you run a program that has been linked with libbtiGPIO
then the dynamic linker (/lib/x86_64-linux-gnu/ld-2.21.so, or similar) will know where to look
to load that library into the process and you will not need to tell it by setting an LD_LIBRARY_PATH in the environment.
However, you haven't done anything that affects the list of default library
search directories that are hardwired into your build of gcc, that it passes to
the linker (/usr/bin/ld) when you link a program with libbtiGPIO in the first place.
That list of default search directories is what you will find if your do a verbose
build of your program - gcc -v ... - and then pick out the value of LIBRARY_PATH
from the output, e.g.
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/:\
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/:\
/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib/:\
/lib/x86_64-linux-gnu/:\
/lib/../lib/:\
/usr/lib/x86_64-linux-gnu/:\
/usr/lib/../lib/:\
/usr/lib/gcc/x86_64-linux-gnu/5/../../../:\
/lib/:\
/usr/lib
/usr/local/lib/agony is not one of those and to make it one of those you
would have to build gcc from source yourself. Hence, in order to link your
program with libbtiGPIO you still need to tell ld where to find it with
-L/usr/local/lib/agony -lbtiGPIO.
man, you misunderstand the procedure of complier and link.
First, libbtiGPIO.so is a shared link library not a static link library. it is important to know those difference .
Then you need to know something else. changing ld.so.conf.d/*.conf and run sudo ldconfig, it affects the procedure of link. in other words, if you don't add agony.conf and sudo ldconfig, you will receive a error when you run ./a.out rather than gcc source.c -L ...., the gcc command can run successfully even thougth you don't ldconfig.
Finally,if you don't pollute the LD_LIBRARY_PATH environment variable, you have to add -L ... options in your gcc command. What'more, if you don't want to input too many words in your shell frequently, you can learn to use Makefile.

Forcing a binary to use a specific (newer) version of a shared library (.so)

I have an older binary executable (utserver, closed source) that I'm trying to run on a system running Fedora 22.
utserver wants openssl_1.0.0 - F22 provides openssl_1.0.1k
I made two symlinks:
$ sudo ln -s /usr/lib64/libssl.so.1.0.1k /usr/lib64/libssl.so.1.0.0
$ sudo ln -s /usr/lib64/libcrypto.so.1.0.1k /usr/lib64/libcrypto.so.1.0.0
But trying to run utserver complains about library version:
$ ./utserver
./utserver: /lib64/libcrypto.so.1.0.0: version `OPENSSL_1.0.0' not found (required by ./utserver)
./utserver: /lib64/libssl.so.1.0.0: version `OPENSSL_1.0.0' not found (required by ./utserver)
OK, so it's looking for a version string. I edited the utserver ELF to change the string OPENSSL_1.0.0 to OPENSSL_1.0.1 but I get the same error (`OPENSSL_1.0.1' not found)
objdump and readelf both show OPENSSL_1.0.1 present in version area of libssl.so.1.0.1:
$ objdump -p /lib64/libssl.so.1.0.1 | grep OPENSSL
3 0x00 0x066a2b21 OPENSSL_1.0.1
4 0x00 0x02b21533 OPENSSL_1.0.1_EC
0x02b21533 0x00 07 OPENSSL_1.0.1_EC
so now I'm confused as to what utserver is actually checking for. I suspect it's seeing OPENSSL_1.0.1_EC and failing. If I add the _EC in the ELF I get a seg fault, presumably because now my offsets are all wrong.
$ readelf -d ./utserver
readelf: Error: Unable to seek to 0x15da90000000 for string table
readelf: Error: no .dynamic section in the dynamic segment
Dynamic section at offset 0x154fb8 contains 34 entries:
Is there any way to tell ld-linux to force load OPENSSL_1.0.1_EC and/or a reference to modifying ELF offsets? Would be much appreciated.
Yes, I know I can find a version of openssl_1.0.0 packaged somewhere, but that's one library I'd rather not revert if I don't have to.
Is there any way to tell ld-linux to force load OPENSSL_1.0.1_EC
No.
There is a reason why the symbol versions have been changed: the old and new symbols are not ABI-compatible. You must recompile the executable to use the new symbols, or (easier) you must provide libssl.so.1.0.0 (which can be installed and co-exist with already installed libssl.so.1.0.1k).
that's one library I'd rather not revert if I don't have to.
You don't have to revert anything (and reverting will break all the programs that want the new version).
Simply providing the libssl.so.1.0.0 from an old package will make old programs (that require it) use that file, while new programs (which require libssl.so.1.0.1k) will continue to use libssl.so.1.0.1k.
easy fix in debian:
add oldstable/jessie to your /etc/apt/sources.list:
deb http://mi.mirror.garr.it/mirrors/debian/ oldstable main contrib non-free
deb-src http://mi.mirror.garr.it/mirrors/debian/ oldstable main contrib non-free
update your apt db:
sudo apt update
and then simply:
sudo apt install libssl1.0.0/jessie
The libssl1.0.0 Debian package contains the missing libraries (the libcrypto.so.1.0.0 and libssl.so.1.0.0), and can be downloaded from this page: http://security.ubuntu.com/ubuntu/pool/main/o/openssl1.0/ (e.g. for x86 architecture the link would be http://security.ubuntu.com/ubuntu/pool/main/o/openssl1.0/libssl1.0.0_1.0.2n-1ubuntu5.10_amd64.deb).
On a Debian-based system (e.g. Ubuntu), one can install the downloaded package with
sudo dpkg -i ./libssl1.0.0_1.0.2n-1ubuntu5.10_amd64.deb
On a non-Debian system one can (i) extract the content of the package with
ar x libssl1.0.0_1.0.2n-1ubuntu5.10_amd64.deb
(ii) get the required library files, and (iii) place them in a location where the executable in question can find them.

Resources