ELF is a binary format designed to support dynamic objects and shared libraries. On older COFF and ECOFF systems, dynamic support and shared libraries were not naturally supported by the underlying format, leading to dynamic implementations that were at times complex, quirky, and slow.
You probably left off the --export-dynamic option when linking the application. This is required only if arbitrary symbols in the program might be needed by the dynamically loaded module, for example, if a program intends to make run-time decisions to dynamically load modules it was never linked with. Note, when running cc(1) instead of ld(1) this will be specified as -Wl,--export-dynamic.
ld.so.conf
! (top)
Ideally, there is no need for ldconfig or for
/etc/ld.so.conf
,
since ELF provides good and predictable (read portable) mechanism
to locate shared libraries. Unfortunately there are still a few
corner cases (like wanting to run setuid binaries that you don't
have the source for, that want shared libraries to be installed
somewhere you don't like). For those corner cases, you'll find that
creating an /etc/ld.so.conf
file, will
still work. Read on though
about other ways of doing this and why it is not a good idea. The
next section discusses the ELF mechanisms for locating shared
libraries.
An ELF program needs to know the directory and the filename required to mmap(2) its shared libraries. Encoded within the file name is version information. There are one set of mechanisms for the directories and a different mechanism for the file names.
Although rarely used, the optional
LD_LIBRARY_PATH
environment variable specifies
a colon-separated search path. This can be used in wrapper
scripts as needed for misconfigured applications. It is
ignored for setuid binaries.
There is a built-in search path in the run-time loader:
ld.elf_so
. On many systems this path
consists only of /usr/lib
; although on
NetBSD versions prior to 1.4 it also searched
/usr/local/lib
.
The primary directory locating mechanism is the ``rpath'' search list contained within the executable image. This search list is set with the -R directive to ld(1). The POSIX syntax for passing ld(1) options through the compiler front end is:
-Wl, option,option,...
For example: -Wl,-R/usr/something/lib
.
Multiple -R directives can be
given to a single application to create a shared library
search path.
This directive is also known as -rpath. Using -R has the advantage of working in older versions of NetBSD as well.
When shared libraries are created, the -soname directive is used to record
the major version number of the library in the internal
DT_SONAME
field. The actual library is installed
as, for example,
libgizmo.so.4.2
(the actual file)
libgizmo.so.4
(symbolic link)
libgizmo.so
(symbolic link)
The idea is that Makefiles will want to link against only the plain .so file. (Who would want to go around changing all the Makefiles just because a new library version was installed?) Once linked, however, the program does want to be aware of the major version but does not want to deal with the minor version.
Consequently, the library itself knows that it is
libgizmo.so.4
because a -soname libgizmo.so.4
directive was used when it was created. The program knows
it got major version 4 because the linker copied the
libgizmo.so.4
DT_SONAME
string
out of the library and saved it in the executable.
You don't say -soname libgizmo.so
,
because then the program would use the latest major number
and would break if that ever changed. (The major number only
changes if the new library is incompatible.)
You don't say -soname libgizmo.so.4.2
,
because then the installation of a compatible change that
bumps the minor number would unnecessarily break the linked
images.
To compile f.c
and make an installable
shared library out of it:
cc -O -Werror -c -fpic -DPIC f.c -o f.so ar cq libf_pic.a `NM=nm lorder f.so | tsort -q` ld -x -shared -R/my/directory/lib -soname libf.so.4 -o \ libf.so.4.9 /usr/lib/crtbeginS.o --whole-archive \ libf_pic.a /usr/lib/crtendS.o |
There is another way:
% cat Makefile
LIB=f
SRCS=f.c
.include <bsd.lib.mk>
% cat shlib_version
major=4
minor=9
% make
You can disable some of the |
And there is another way:
libtool
- Thelibtool
package is a large shell script used to manage shared and static libraries in a platform-independent fashion. There is a NetBSDdevel/libtool
package and even alibtool
home page.
At first glance, it might seem reasonable, why shouldn't
people be able to move things around to anywhere they want and
correct the consequent lossage in a
/etc
file?
In fact, some developers of ELF systems have apparently added such a file, but with mixed results. The ELF mechanism was designed to correct some of the previous problems, and introducing the old mechanism would bring many of those old problems back.
Currently we are even supporting the
/etc/ld.so.conf
functionality
in our ELF linker, but it is not at all clear that a hybrid
mechanism is the right solution. For that reason we do not
advertise its existence, advocate its use, or even provide a
default installation template. It is there for those who think
that they really need it, and cannot live without it.
Here are some of the problems.
/etc
is yet
another configuration knob to turn. This works against making
the system easy to install and use./etc
file gets out of sync
with the installed system when configurations are changed or
packages are added. The resulting failure mode can be confusing
to some users./usr/local
.libutil.so.1
"?
ELF tools are standardized packages maintained by third parties; these tools are used consistently on different operating systems and platforms. In the long run, the standardization provided by ELF will increase the quality of both systems and applications.
The recommended method is to install a ELF snapshot. If you try upgrading via source and something goes wrong it is very easy to hose your system such that it will not even boot to single-user mode.
However for those who wish to to upgrade from source: (this should work on i386, sparc and any platform that uses ld.new and gas.new)
/emul/aout
tree with
a.out
shared libraries
mkdir -p /emul/aout/usr/lib /emul/aout/usr/X11R6/lib
cp -p /usr/lib/*.so* /emul/aout/usr/lib
cp -p /usr/X11R6/lib/*.so* /emul/aout/usr/X11R6/lib |
cd /usr/src/usr.sbin/config && make && make install |
EXEC_ELF
,
EXEC_AOUT
, and COMPAT_AOUT
all
defined.#!/bin/sh -x -e SRC=/usr/src # if the src is an update, eg: to -current, as well as config, # you might need to rebuild make: ### cp /usr/bin/make /usr/bin/make.old ### cd $SRC/usr.bin/make && make && make install # and at times in the past, /bin/sh, flex, etc # magic build variables export DESTDIR=/../. # hack from Hell export OBJECT_FMT=a.out export BOOTSTRAP_ELF=YESSIREE # update .mk files for new magic cd $SRC/share/mk && make install # Clean any old objects cd $SRC && make cleandir # You may need this: ### cd $SRC/gnu && make depend # update compiler tools cd $SRC/gnu/usr.bin/binutils && make cd ../gas.new && make cd ../ld.new && make cd ../egcs && make # (you may want to copy the old a.out tools here, just in case) cd $SRC/gnu/usr.bin/binutils && make install cd ../gas.new && make install cd ../ld.new && make install cd ../egcs && make install # You may need this: ### cd $SRC/gnu/lib/libbfd && make # now building ELF natively export OBJECT_FMT=ELF # update include files and base libraries cd $SRC && make includes cd $SRC/lib/csu && make && make install cd $SRC/lib && make && make install # build the dynamic linker (needs libc_pic.a) cd $SRC/libexec/ld.elf_so && make && make install # finish the build cd $SRC/gnu/lib && make && make install cd $SRC && make && make install |
If you find you need to make any changes to the above
script, please let us know on <www@NetBSD.org>
.
If you are running an ELF system your compiler will define the constant __ELF__. You can use this in your C programs of course but you can also use the following shell script to determine it as well.
if echo __ELF__ | ${CC:-cc} -E - | grep -q __ELF__ then echo "Not ELF" else echo "It is an ELF system" fi |
The ELF faq is now maintained by Christos Zoulas
<christos@NetBSD.org>