Location of time.h -> localtime() implemenation in Ubuntu? - c

I am searching for the implementation of localtime() function in time.h. I see that different platforms have different locations for source of c library. I wanted to know the location in Ubuntu 14.04? If by default source is not included in OS, please let me know how to download source or online location of the source.
Thanks.

Check which binary your system uses as libc implementation.
To do so compile a minimal C program and run ldd on it:
ldd a.out
You might get something like this:
linux-vdso.so.1 => (0x00007fff429c6000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f21cdcb7000)
/lib64/ld-linux-x86-64.so.2 (0x00007f21ce05e000)
From this you can pull the info libc is proided by libc6.so.6.
Check which package provides this binary.
Search the package providing the file found under 1.:
dpkg -S libc.so.6
You might get:
libc6-i386: /lib32/libc.so.6
libc6:amd64: /lib/x86_64-linux-gnu/libc.so.6
The above output tells you, that there are two packages providing the file. Here it's the 32 bit and 64 bit implementation.
Decide which one you want and do apt-get source this package's sources.
Assuming the package would be libc6, do
apt-get source libc6
and find thre source in a directory inside the current directory.

Related

How to change the glibc version required by an executable?

ldd MyExecutable | grep libc
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007eff56bd0000)
This executable requires glibc version 2.25 from Ubuntu 18.04. How can I overwrite it do ask for glibc 2.23, which is the one present on ubuntu 16.04?
I'm aware of possible problems, but how can I do it?
To understand why your binary requires GLIBC_2.25, read this answer.
To understand how you can build a binary which requires older GLIBC version, start here.

Debugging modified OpenSSL

I would like to modify OpenSSL code and then debug it in my IDE (QTCreator).
I have downloaded the OpenSSL source code, built it according to ./config with debugging symbols, and deployed it in non-system folder. Still, when I make modifications to the library, the changes are not effective in the debugged program.
For instance, I attempt to modify handshake process and test the results using the s_client app. Nevertheless, the s_client app points to the system version of OpenSSL. Namely, s_client includes <openssl/...> (which is located in /usr/local/...).
I would like it to point to the just installed/modified version of openssl in different folder. There's a catch though. I have figured only one way how to do it, by modifying the original OpenSSL makefile, which is just huge and the task seems overwhelming.
Does anyone has any idea how to approach this issue? Please note that I would like to keep the system version of the OpenSSL operational (symbolic link not suitable).
I run the Ubuntu 16.04 LTS. The output of ldd /my/version/of/openssl is
linux-vdso.so.1 => (0x00007ffd9a3d6000)
libssl.so.1.1 => /usr/local/lib/libssl.so.1.1 (0x00007f04523f8000)
libcrypto.so.1.1 => /usr/local/lib/libcrypto.so.1.1 (0x00007f0451f6a000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f0451d4d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0451983000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f045177f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0452668000)
With the help of the two guys (see comments), I was able to figure out the problem. First, make sure you compile OpenSSL with --prefix and --openssl directories properly set.
Once OpenSSL installed, you need your code (apps of OpenSSL) to be calling/linking your new version of OpenSSL. In QtCreator you can achieve this by setting the LD_LIBRARY_PATH to the directory with the library files libcrypto.so.1 and libssl.so.1. The setting is done in Projects -> Run environment -> (add LD_LIBRARY_PATH into system environment).
Moreover, you can check what libraries are called by the binary manually, by entering the directory with the binary and calling command ldd ./openssl from the terminal. This way, you will see what libraries are called (it should be your own version, not the system libraries). Further, you can set LD_LIBRARY_PATH from terminal, optionally with export command in front of it, to achieve permanent effect (lasting whole terminal session). In total, you could call
export LD_LIBRARY_PATH=/path/to/your/lib.

How to compile readline from source?

When I compile readline into my directory /mypath as instructed (./configure --prefix=/mypath; make; make install) I get the following unresolved symbols in it:
ldd -r /mypath/lib/libreadline.so.6.2
linux-vdso.so.1 => (0x00007ffffb186000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f450c62f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f450cc07000)
undefined symbol: UP (/mypath/lib/libreadline.so.6.2)
undefined symbol: PC (/mypath/lib/libreadline.so.6.2)
undefined symbol: BC (/mypath/lib/libreadline.so.6.2)
When I read the readme-file of readline, this seems to be a feature and not a bug:
`--with-curses'
This tells readline that it can find the termcap library functions
(tgetent, et al.) in the curses library, rather than a separate
termcap library. Readline uses the termcap functions, but does not
link with the termcap or curses library itself, allowing applications
which link with readline the to choose an appropriate library.
This option tells readline to link the example programs with the
curses library rather than libtermcap.
I tried it of course with --with-curses but that did not change anything, which is not surprising because it seems to be a setting that only affects some testing programs in readline.
My distribution (debian) however has a readline without undefined symbols, so it is clearly possible to do.
How to create a readline library without unresolved symbols?
Edit:
I have compiled and installed ncurses into the same directory and I have also tried to configure readline with CFLAGS=" -Wl,-rpath=/mypath" and --enable-static, without success.
Those symbols are defined by libncurses, I think. You can probably confirm this like this:
env LD_PRELOAD=/usr/lib/libncurses.so ldd -r /mypath/lib/libreadline.so.6.2
(I think ldd takes preloads into account when checking symbols, but it may not.)
The build script used by Arch Linux is here. It looks like the trick is to use:
make SHLIB_LIBS=/mypath/libncurses.so
There's also some other adjustments to the -rpath options in a build file, so you might need that also.
The make install step is installing the shared library in some directory, often /usr/local/lib/
You need to make the dynamic loader ld.so(8) aware of that. I would suggest add once /usr/local/lib/ into your /etc/ld.so.conf file then running ldconfig after each installation of new shared libraries inside it. See ldconfig(8), ldd(1)
You could also specify some -Wl,-rpath when linking programs with your version of libreadline.so
And when building a shared library you can link it to other shared libraries. On my Debian the system libreadline is linked to libtinfo:
% ldd /lib/x86_64-linux-gnu/libreadline.so.6
linux-vdso.so.1 (0x00007ffffccf3000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f45cffcc000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f45cfc23000)
/lib64/ld-linux-x86-64.so.2 (0x00007f45d046c000)
You may want to study the source package of your readline6, since it contains the patches to the building procedure.
BTW, my Debian has a libtinfo5 package (obtained with dpkg -S /lib/x86_64-linux-gnu/libtinfo.so.5)

Unable to found -lGL, how to do without symlink?

I'm compiling a shared library, with a -lGL on the ld command. But it can't find the libGL.so on my system. Nvidia package correctly set libraries path in /etc/ld.so.conf.d/.
Even the output of ldconfig -p | grep libGL.so found it:
libGL.so.1 (libc6,x86-64) => /usr/lib/nvidia-current/libGL.so.1
libGL.so.1 (libc6) => /usr/lib32/nvidia-current/libGL.so.1
libGL.so (libc6,x86-64, OS ABI: Linux 2.4.20) => /usr/lib/x86_64-linux-gnu/libGL.so
libGL.so (libc6,x86-64) => /usr/lib/nvidia-current/libGL.so
libGL.so (libc6, OS ABI: Linux 2.4.20) => /usr/lib32/libGL.so
libGL.so (libc6) => /usr/lib32/nvidia-current/libGL.so
I read almost everywhere that to be able to link with it, i have basically 2 solutions:
Link the nvidia libGL.so to a standard /usr/lib location. That seem wrong for anybody what will try to compile an opengl library. Why the linker is not using the ldconfig cache ?
Append manually the -L/usr/lib/nvidia-current to the library search path. Again, wrong, how can i know every path where the library could be found on all the system ?
So my real question is: What is the standard and automatic approach for linking with a library not in a standard location, but location already register with /etc/ld.so.conf ?
/etc/ld.so.conf is used by /lib/ld.so to resolve shared libraries at runtime, it has nothing to do with linking stuff at compile time.
What is the right way to do is just linking to libGL.so in /usr/lib/x86_64-linux-gnu/ and the application will use the nvidia's libGL.so on runtime. This shouldn't be a problem because the OpenGL interface is stable and symbols are the same in both libraries, its the implementation that is different.

Location of C standard library

In the gcc manual it is given that "The C standard library itself
is stored in ‘/usr/lib/libc.a’". I have gcc installed, but could not find libc.a at the said location. Curious to know where is it located.
I find many .so files in /usr/lib location. What are those?
If you are looking for libc.a:
$ gcc --print-file-name=libc.a
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libc.a
A few things:
gcc and glibc are two different things. gcc is the compiler, glibc are the runtime libraries. Pretty much everything needs glibc to run.
.a files are static libraries, .so means shared object and is the Linux equivalent of a DLL
Most things DON'T link against libc.a, they link against libc.so
Hope that clears it up for you. As for the location, it's almost certainly going to be in /usr/lib/libc.a and / or /usr/lib/libc.so. Like I said, the .so one is the more common.
If you are on RPM based Linux (Red Hat/CentOS/Fedora/SUSE) then you would get the location of the installed glibc with
rpm -ql glibc and rpm -ql glibc-devel .
locate libc.a would get you the location. And to see from where it comes do:
rpm -qf /usr/lib/libc.a
Here is what rpm -qi has to tell about these packages
glibc-devel:
The glibc-devel package contains the object files necessary
for developing programs which use the standard C libraries (which are
used by nearly all programs). If you are developing programs which
will use the standard C libraries, your system needs to have these
standard object files available in order to create the
executables.
Install glibc-devel if you are going to develop programs which will
use the standard C libraries
glibc:
The glibc package contains standard libraries which are used by
multiple programs on the system. In order to save disk space and
memory, as well as to make upgrading easier, common system code is
kept in one place and shared between programs. This particular package
contains the most important sets of shared libraries: the standard C
library and the standard math library. Without these two libraries, a
Linux system will not function.
You need to install package for static libraries separately:
glibc-static.i686
On centos 5.8
$ ls -l /usr/lib/libc.a
-rw-r--r-- 1 root root 2442786 Apr 8 2010 /usr/lib/libc.a
$ rpm -qf /usr/lib/libc.a
glibc-devel-2.3.4-2.43.el4_8.3
You also have to have the glibc-devel package install under RedHat distributions.

Resources