Ld.so(8) — linux man page
Содержание:
- 3.5. Installing and Using a Shared Library
- 7) ldd with missing dependency
- Изменить разрешения
- DESCRIPTION
- 3.1. Conventions
- Решение
- Соглашение об именах библиотек
- LD_LIBRARY_PATH поиск
- 3.3. Environment Variables
- Step 3: Linking with a shared library
- FILES top
- Что делает компоновщик; часть 2
- Краткий обзор
- Какие библиотеки необходимы?
Once you’ve created a shared library, you’ll want to install it.
The simple approach is simply to copy the library into one of the
standard directories (e.g., /usr/lib) and run ldconfig(8).
First, you’ll need to create the shared libraries somewhere.
Then, you’ll need to set up the necessary symbolic links, in particular
a link from a soname to the real name (as well as from a versionless
soname, that is, a soname that ends in «.so» for users who don’t specify
a version at all). The simplest approach is to run:
ldconfig -n directory_with_shared_libraries |
Finally, when you compile your programs, you’ll need to tell the
linker about any static and shared libraries that you’re using.
Use the -l and -L options for this.
If you can’t or don’t want to install a library in a standard place
(e.g., you don’t have the right to modify /usr/lib),
then you’ll need to change your approach.
In that case, you’ll need to install it somewhere, and then
give your program enough information so the program can find the library…
and there are several ways to do that.
You can use gcc’s -L flag in simple cases.
You can use the «rpath» approach (described above), particularly if
you only have a specific program to use the library being placed in
a «non-standard» place.
You can also use environment variables to control things.
In particular, you can set LD_LIBRARY_PATH, which is a colon-separated
list of directories in which to search for shared libraries before
the usual places.
If you’re using bash, you could invoke my_program this way using:
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH my_program |
If you want to override just a few selected functions,
you can do this by creating an overriding object file and setting
LD_PRELOAD; the functions in this object file will override just
those functions (leaving others as they were).
Usually you can update libraries without concern; if there was an API
change, the library creator is supposed to change the soname.
That way, multiple libraries can be on a single system, and the right
one is selected for each program.
However, if a program breaks on an update to a library that kept the
same soname, you can force it to use the older library version by
copying the old library back somewhere,
renaming the program (say to the old name plus «.orig»),
and then create a small
«wrapper» script that resets the library to use and
calls the real (renamed) program.
You could place the old library in its own special area, if you like,
though the numbering conventions do permit multiple versions to live
in the same directory.
The wrapper script could look something like this:
#!/bin/sh export LD_LIBRARY_PATH=/usr/local/my_lib:$LD_LIBRARY_PATH exec /usr/bin/my_program.orig $* |
You can see the list of the shared libraries used by a program using ldd(1).
So, for example, you can see the shared libraries used by ls by typing:
ldd /bin/ls |
-
/lib/ld-linux.so.N (where N is 1 or more, usually at least 2).
This is the library that loads all other libraries. -
libc.so.N (where N is 6 or more).
This is the C library. Even other languages tend to use the C
library (at least to implement their own libraries), so most programs
at least include this one.
7) ldd with missing dependency
We can use the command when an executable is failing because of a missing dependency. Once we found a missing dependency, we can install it or update the cache with the command.
$ sudo ldd /bin/mv
libacl.so.1 => /lib/libacl.so.1 (0×40016000) libc.so.6 => /lib/libc.so.6 (0x4001c000) libattr.so.1 => /lib/libattr.so.1 (0×40141000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0×40000000)
We will perform relocations and report any missing objects (ELF only) by typing below command.
$ sudo ldd -d path/to/executable_file
We will perform relocations for both data objects and functions, and report any missing objects or functions (ELF only) by typing below command.
$ sudo ldd -r path/to/executable_file
Изменить разрешения
Чтобы изменить права доступа к файлу или каталогу, мы используем команду chmod.
У chmod есть аргументы разрешения, которые состоят из 3 компонентов
- Для кого мы меняем разрешение? — пользователь (или владелец), группа, другие, все
- Предоставляем ли мы или отменяем разрешение — обозначается плюсом (+) или минусом (-)
- Какое разрешение мы устанавливаем? — прочитать (r), написать (w) или выполнить (x)
Следующие примеры сделают их использование более понятным.
Предоставьте разрешение на выполнение группе. Затем удалите разрешение на запись для владельца.
Не хотите назначать разрешения индивидуально? Мы можем назначить несколько разрешений одновременно.
Может показаться странным, что как владелец файла мы можем лишить нас возможности читать, записывать и выполнять этот файл, но есть веские причины, по которым мы можем захотеть это сделать. Например, может быть, у нас есть файл с данными, которые мы не хотим случайно изменить. Хотя мы можем удалить эти разрешения, мы не можем лишить нас возможности устанавливать эти разрешения. В итоге, мы всегда имеем контроль над каждым файлом.
DESCRIPTION
ld.sold-linux.so*
Linux binaries require dynamic linking (linking at run time)
unless the
-static
option was given to
ld(1)
during compilation.
The program
ld.so
handles a.out binaries, a binary format used long ago.
The program
ld-linux.so*
(/lib/ld-linux.so.1 for libc5, /lib/ld-linux.so.2 for glibc2)
handles binaries that are in the more modern ELF format.
Both programs have the same behavior, and use the same
support files and programs
(ldd(1),
ldconfig(8),
and
/etc/ld.so.conf).
When resolving shared object dependencies,
the dynamic linker first inspects each dependency
string to see if it contains a slash (this can occur if
a shared object pathname containing slashes was specified at link time).
If a slash is found, then the dependency string is interpreted as
a (relative or absolute) pathname,
and the shared object is loaded using that pathname.
If a shared object dependency does not contain a slash,
then it is searched for in the following order:
- o
-
Using the directories specified in the
DT_RPATH dynamic section attribute
of the binary if present and DT_RUNPATH attribute does not exist.
Use of DT_RPATH is deprecated. - o
-
Using the environment variable
LD_LIBRARY_PATH,unless the executable is being run in secure-execution mode (see below),
in which case this variable is ignored. - o
-
Using the directories specified in the
DT_RUNPATH dynamic section attribute
of the binary if present.
Such directories are searched only to
find those objects required by DT_NEEDED (direct dependencies) entries
and do not apply to those objects’ children,
which must themselves have their own DT_RUNPATH entries.
This is unlike DT_RPATH, which is applied
to searches for all children in the dependency tree. - o
-
From the cache file
/etc/ld.so.cache,which contains a compiled list of candidate shared objects previously found
in the augmented library path.
If, however, the binary was linked with the
-z nodefliblinker option, shared objects in the default paths are skipped.
Shared objects installed in hardware capability directories (see below)
are preferred to other shared objects. - o
-
In the default path
/lib,and then
/usr/lib.(On some 64-bit architectures, the default paths for 64-bit shared objects are
/lib64,and then
/usr/lib64.)If the binary was linked with the
-z nodefliblinker option, this step is skipped.
Rpath token expansion
The dynamic linker
understands certain token strings in an rpath specification
(DT_RPATH or DT_RUNPATH).
Those strings are substituted as follows:
- $ORIGIN (or equivalently ${ORIGIN})
-
This expands to
the directory containing the program or shared object.
Thus, an application located in
somedir/appcould be compiled with
- gcc -Wl,-rpath,’$ORIGIN/../lib’
-
so that it finds an associated shared object in
somedir/libno matter where
somediris located in the directory hierarchy.
This facilitates the creation of «turn-key» applications that
do not need to be installed into special directories,
but can instead be unpacked into any directory
and still find their own shared objects. - $LIB (or equivalently ${LIB})
-
This expands to
libor
lib64depending on the architecture
(e.g., on x86-64, it expands to
lib64and
on x86-32, it expands to
lib). - $PLATFORM (or equivalently ${PLATFORM})
-
This expands to a string corresponding to the processor type
of the host system (e.g., «x86_64»).
On some architectures, the Linux kernel doesn’t provide a platform
string to the dynamic linker.
The value of this string is taken from the
AT_PLATFORMvalue in the auxiliary vector (see
getauxval(3)).
3.1. Conventions
For shared libraries to support all of these desired properties,
a number of conventions and guidelines must be followed.
You need to understand the difference between a library’s
names, in particular its «soname» and «real name» (and how they interact).
You also need to understand where they should be placed in the filesystem.
Every shared library has a special name called the «soname».
The soname has the prefix «lib», the name of the library,
the phrase «.so», followed by a period and a
version number that is incremented whenever the interface changes
(as a special exception, the lowest-level C libraries don’t start
with «lib»).
A fully-qualified soname includes as a prefix the directory it’s in;
on a working system a fully-qualified soname is simply a symbolic
link to the shared library’s «real name».
Every shared library also has a «real name», which is the filename
containing the actual library code.
The real name adds to the soname a period, a
minor number, another period, and the release number.
The last period and release number are optional.
The minor number and release number
support configuration control by letting you know exactly what version(s)
of the library are installed. Note that these numbers might not be
the same as the numbers used to describe the library in documentation,
although that does make things easier.
In addition, there’s the name that the compiler uses when requesting a library,
(I’ll call it the «linker name»), which is simply the soname without
any version number.
The key to managing shared libraries is the separation of these names.
Programs, when they internally list the shared libraries they need,
should only list the soname they need.
Conversely, when you create a shared library, you only create the
library with a specific filename (with more detailed version information).
When you install a new version of a library, you
install it in one of a few special directories and then run the
program ldconfig(8).
ldconfig examines the existing files and creates the sonames as
symbolic links to the real names, as well as setting up the
cache file /etc/ld.so.cache (described in a moment).
ldconfig doesn’t set up the linker names; typically this is done during
library installation, and the linker name is simply created as a symbolic
link to the «latest» soname or the latest real name.
I would recommend having the linker name be a symbolic link to the soname,
since in most cases if you update the library
you’d like to automatically use it when linking.
I asked H. J. Lu why ldconfig doesn’t automatically set up the linker names.
His explanation was basically that
you might want to run code using the latest version of a library,
but might instead want development to link
against an old (possibly incompatible) library.
Therefore, ldconfig makes no assumptions about what you want programs to
link to, so installers must specifically modify symbolic links to
update what the linker will use for a library.
Thus, /usr/lib/libreadline.so.3
is a fully-qualified soname, which
ldconfig would set to be a symbolic link to some realname like
/usr/lib/libreadline.so.3.0.
There should also be a linker name,
/usr/lib/libreadline.so
which could be a symbolic link referring to
/usr/lib/libreadline.so.3.
Решение
На самом деле есть два вопроса (что, кстати, не очень хорошая практика SO), поэтому я отвечу на них независимо.
Также я сосредоточусь на Linux — это та область, с которой я знаком. Из текста вопроса я предполагаю, что в мире Mac все очень похоже.
Соглашение об именах библиотек
При работе с .so библиотеками в среде Linux часто можно увидеть, что динамические библиотеки часто представлены в триплетах. Например, библиотека foo может существовать в 3 файлах: libfoo.so, libfoo.so.6, libfoo.so.6.5.4. Если вы посмотрите внимательно, вы увидите, что все они представляют собой один и тот же файл — обычно две из них являются просто символическими ссылками на третий. Ради дальнейшего обсуждения libfoo.so будет упоминаться как неверсированное библиотека, ibfoo.so.6 as мейджор-о версиях и libfoo.so.6.5.4 * полная версия. Зачем тебе это? Для лучшего контроля версий.
Когда вы связываете свое приложение, вы всегда используете правило компоновщика для неверсионной библиотеки — принимая во внимание тот факт, что компоновщик добавляет а также к правилу, это будет выглядеть
Когда ваше приложение связано, компоновщик открывает libfoo.so и проверяет его на несколько вещей. Один из вещей, которые он проверяет, является так называемым заголовок. Этот заголовок создается, когда библиотека .so связана, и он может иметь имя файла, отличное от того, который в данный момент просматривает один компоновщик. Например, в нем может быть файл с основными версиями, и компоновщик увидит его: SONAME = libfoo.so.6.
Когда компоновщик видит это SONAME, он помечает полученный файл приложения как необходимый — даже когда вы на самом деле просили ,
При этом компоновщик сохранил определенную версию библиотеки. Ваше приложение было изначально скомпилировано и связано с версией 6, поэтому при каждом запуске приложения требуется версия 6.
Если позже система будет обновлена (или приложение будет запущено в другой системе), где другой версии (скажем, 7), файлы .so будут другими: libfoo.so, libfoo.so.7, libfoo.so.7.6.5. Поскольку ваше приложение нуждается , он не запустится — и это хорошо, так как кто знает, что версия 7 все еще совместима? Без этой защиты приложение запускалось бы и использовало другую версию библиотеки, и эффект мог бы быть разрушительным.
LD_LIBRARY_PATH поиск
Ваш второй вопрос для LD_LIBRARY_PATH. Это правда, компоновщик во время выполнения обращается к этой переменной при поиске динамических библиотек. Тем не менее, это не единственное, к чему он обращается. Помимо этого, и из пути поиска по умолчанию, есть также путь к динамическим библиотекам для каждого приложения, который записывается в приложении, когда он связан, как правило, управляется аргументом rpath для компоновщика, например:
Когда путь записывается таким образом, компоновщик во время выполнения добавляет эти пути в список путей поиска при загрузке приложения.
Тот факт, что библиотеки могут быть найдены для вашего приложения без LD_LIBRARY_PATH, означает одну из двух вещей: rpath был записан, когда приложение было связано, или на самом деле включен в пути поиска по умолчанию на вашей платформе.
1
3.3. Environment Variables
Various environment variables can control this process,
and there are environment variables that permit
you to override this process.
3.3.1. LD_LIBRARY_PATH
You can temporarily substitute a different library for
this particular execution.
In Linux, the environment variable LD_LIBRARY_PATH
is a colon-separated set of directories where libraries should be
searched for first, before
the standard set of directories; this is useful when debugging
a new library or using a nonstandard library for special purposes.
The environment variable LD_PRELOAD lists shared libraries with functions that
override the standard set, just as /etc/ld.so.preload does.
These are implemented by the loader /lib/ld-linux.so.
I should note that, while LD_LIBRARY_PATH works on many
Unix-like systems, it doesn’t work on all;
for example, this functionality is available on HP-UX but as
the environment variable SHLIB_PATH,
and on AIX this functionality is through the variable LIBPATH
(with the same syntax, a colon-separated list).
LD_LIBRARY_PATH is handy for development and testing, but shouldn’t
be modified by an installation process for normal use by normal users; see
«Why LD_LIBRARY_PATH is Bad» at
http://www.visi.com/~barr/ldpath.html
for an explanation of why.
But it’s still useful for development or testing, and for working around
problems that can’t be worked around otherwise.
If you don’t want to set the LD_LIBRARY_PATH environment variable, on Linux
you can even invoke the program loader directly and pass it arguments.
For example, the following will use the given PATH instead
of the content of the environment variable LD_LIBRARY_PATH, and run
the given executable:
/lib/ld-linux.so.2 --library-path PATH EXECUTABLE |
Just executing ld-linux.so without arguments will give you more help on
using this, but again, don’t use this for normal use — these are all
intended for debugging.
3.3.2. LD_DEBUG
Another useful environment variable in the GNU C loader is LD_DEBUG.
This triggers the dl* functions so that they give quite verbose information
on what they are doing. For example:
export LD_DEBUG=files command_to_run |
displays the processing of files and libraries when handling libraries,
telling you what dependencies are detected and which SOs are loaded
in what order.
Setting LD_DEBUG to «bindings» displays information
about symbol binding, setting it to «libs» displays the
library search paths, and setting ti to «versions» displays the
version depdendencies.
Setting LD_DEBUG to «help» and then trying to run a program
will list the possible options.
Again, LD_DEBUG isn’t intended for normal use, but it can be handy
when debugging and testing.
As you can see, that was actually pretty easy. We have a shared library. Let us compile our main.c and link it with libfoo. We will call our final program test. Note that the -lfoo option is not looking for foo.o, but libfoo.so. GCC assumes that all libraries start with lib and end with .so or .a (.so is for shared object or shared libraries, and .a is for archive, or statically linked libraries).
$ gcc -Wall -o test main.c -lfoo /usr/bin/ld: cannot find -lfoo collect2: ld returned 1 exit status
Uh-oh! The linker does not know where to find libfoo. GCC has a list of places it looks by default, but our directory is not in that list. We need to tell GCC where to find libfoo.so. We will do that with the -L option. In this example, we will use the current directory, /home/username/foo:
$ gcc -L/home/username/foo -Wall -o test main.c -lfoo
FILES top
/lib/ld.so a.out dynamic linker/loader /lib/ld-linux.so.{1,2} ELF dynamic linker/loader /etc/ld.so.cache File containing a compiled list of directories in which to search for shared objects and an ordered list of candidate shared objects. See ldconfig(8). /etc/ld.so.preload File containing a whitespace-separated list of ELF shared objects to be loaded before the program. See the discussion of LD_PRELOAD above. If both LD_PRELOAD and /etc/ld.so.preload are employed, the libraries specified by LD_PRELOAD are preloaded first. /etc/ld.so.preload has a system-wide effect, causing the specified libraries to be preloaded for all programs that are executed on the system. (This is usually undesirable, and is typically employed only as an emergency remedy, for example, as a temporary workaround to a library misconfiguration issue.) lib*.so* shared objects
Что делает компоновщик; часть 2
библиотекепереадресацияrelocation
Статические библиотеки
статическаяar(Раньше программа, называемая , также была нужна для статических библиотек, чтобы сгенерировать список символов вначале библиотеки. В наши дни инструменты делают это сами.)весь объектпорядокпорядке
Файл | ||||||||
Объект | ||||||||
Опредe- ления |
||||||||
Неразре- шённые ссылки |
Экспортируемые символы
экспортируются
- В исходном коде объявить символ как , примерно так:
- При выполнении команды компоновщика использовать опцию
- Скормить компоновщику файл определения модуля (DEF) (используя опцию ), включив в этот файл секцию , которая содержит символы, подлежащие экспортированию.
и другие относящиеся к библиотеке файлы
Файлы на выходе компоновки library: собственно код библиотеки; этот файл нужен (во время исполнения) любому бинарнику, использующему библиотеку.
library: файл «импортирования библиотеки», который описывает где и какой символ находится в результирующей . Этот файл генерируется, если только экспортирует некоторые её символы. Если символы не экспортируются, то смысла в файле нет. Этот файл нужен во время компоновки.
library: «Экспорт файл» компилируемой библиотеки, который нужен если имеет место .
library: Если опция была применена во время компоновки, которая активирует инкрементную компоновку, то этот файл содержит в себе статус инкрементной компоновки. Он нужен для будущих инкрементных компоновок с этой библиотекой.
library: Если опция была применена во время компоновки, то этот файл является программной базой данных, содержащей отладочную информацию для библиотеки.
library: Если опция была применена во время компоновки, то этот файл содержит описание внутреннего формата библиотеки.
Файлы на входе компоновки: library: Файл «импорта библиотеки», которые описывает где и какие символы находятся в других , которые нужны для компоновки.
library: Статическая библиотека, которая содержит коллекцию объектов, необходимых при компоновке
Обратите внимание на неоднозначное использование расширения
library: Файл «определений», который позволяет управлять различными деталями скомпонованной библиотеки, включая. library: Файл экспорта компонуемой библиотеки, который может сигнализировать, что предыдущее выполнение уже создало файл для библиотеки
Имеет значение при .
library: Файл состояния инкрементной компоновки; см. выше.
library: Файл ресурсов, который содержит информацию о различных GUI виджетах, используемых исполняемым файлом. Эти ресурсы включаются в конечный бинарник.
Импортируемые символы
историческими свойствами 16-ти битных оконобъявляем символ как __declspec(dllimport)
экспортироватьимпортировать
Циклические зависимости
обходной приём
- Сначала имитируем компоновку библиотеки X. Запускаем (не ), чтобы получить файл точно такой же, какой был бы получен с . При этом не будет сгенерирован, но вместо него будет получен файл .
- Компонуем библиотеку как обычно, используя , полученную на предыдущем шаге, и получаем на выходе как так и .
- В конце концов компонуем библиотеку теперь уже полноценно. Это происходит почти как обычно, используя дополнительно файл , полученный на первом шаге. Обычное в этом шаге то, что компоновщик использует и производит . Необычное — компоновщик пропускает шаг создания , так как этот файл был уже создан на первом шаге, чему свидетельствует наличие файла.
Краткий обзор
Из этой статьи вы узнаете, как определять и загружать общие библиотеки, необходимые программам Linux. Вы научитесь:
- Определять, какие библиотеки необходимы той или иной программе.
- Узнаете, как операционная система находит общие библиотеки.
- Загружать общие библиотеки.
Эта статья поможет вам подготовиться к сдаче экзамена LPI 101 на администратора начального уровня (LPIC-1) и содержит материалы цели 102.3 темы 102. Цель имеет вес 1.
Необходимые условия
Чтобы извлечь наибольшую пользу из наших статей, необходимо обладать базовыми знаниями о Linux и иметь компьютер с Linux, на котором можно будет выполнять все встречающиеся команды. Иногда различные версии программ выводят результаты по-разному, поэтому содержимое листингов статей может слегка отличаться от результатов, полученных на вашем компьютере. В частности, многие примеры этой статьи выполнялись в 64-разрядных операционных системах. Чтобы продемонстрировать существенные отличия, мы включили некоторые примеры, выполненные в 32-разрядных ОС.
Какие библиотеки необходимы?
Хотя это выходит за рамки текущих требований экзамена LPI по данной теме, вам все же следует знать, что сегодня многие операционные системы Linux работают на компьютерах с поддержкой как 32-, так и 64-разрядных операций. В связи с этим многие библиотеки скомпилированы в версиях для 32- и 64-разрядных систем. 64-разрядные версии обычно хранятся в директории /lib64, а 32-разрядные версии – в традиционной директории /lib. В стандартной 64-разрядной Linux-системе вы, вероятно, обнаружите две версии библиотеки libc: /lib/libc-2.11.1.so и /lib64/libc-2.11.1.so. Эти две библиотеки обеспечивают выполнение 32- и 64-разрядных программ, написанных на C, в 64-разрядной системе Linux.
Команда
Как можно убедиться в том, что программа была скомпонована статически, если не принимать во внимание ее возможно больший размер? А если программа была скомпонована динамически, как узнать, какие библиотеки требуются для ее работы? На оба этих вопроса поможет ответить команда. Если вы работаете с таким дистрибутивом Linux, как Debian или Ubuntu, то, вероятно, в ней отсутствует исполняемый файл sln; вы можете также проверить наличие файла /sbin/ldconfig
В листинге 2 показан вывод команды для исполняемых файлов ln, sln и ldconfig. Пример был выполнен в 64-разрядной операционной системе Fedora 12 (echidna). Также для сравнения приведен пример этой команды для файла /bin/ln, выполненный в 32-разрядной ОС Fedora 8 (pinguino).
Листинг 2. Вывод команды для sln и ln
$ #Fedora 12 64-bit $ ldd /sbin/sln /sbin/ldconfig /bin/ln /sbin/sln: not a dynamic executable /sbin/ldconfig: not a dynamic executable /bin/ln: linux-vdso.so.1 => (0x00007fff644af000) libc.so.6 => /lib64/libc.so.6 (0x00000037eb800000) /lib64/ld-linux-x86-64.so.2 (0x00000037eb400000) $ # Fedora 8 32-bit $ ldd /bin/ln linux-gate.so.1 => (0x00110000) libc.so.6 => /lib/libc.so.6 (0x00a57000) /lib/ld-linux.so.2 (0x00a38000)
Поскольку в действительности программа проверяет факт динамической компоновки, выводимое ей сообщение «not a dynamic executable» говорит нам о том, что обе программы – sln и ldconfig – были скомпонованы статически; также программа сообщает о том, что команде требуются три общих библиотеки (linux-vdso.so.1, libc.so.6 и /lib64/ld-linux-x86-64.so.2). Заметьте, что расширение .so означает shared
objects (совместно используемый объект), т. е. библиотека является динамической. В листинге мы видим три различных блока с информацией:
- linux-vdso.so.1
- представляет собой виртуальный динамический разделяемый объект (Virtual Dynamic Shared Object, VDSO), который мы рассмотрим чуть позже. В ОС Fedora 8 в списке также присутствует библиотека linux-gate.so.1.
- libc.so.6
- имеет указатель на /lib64/libc.so.6.
- /lib64/ld-linux-x86-64.so.2
- представляет собой абсолютный путь к другой библиотеке.
Выполнив в листинге 3 команду , мы видим, что две последние библиотеки, в свою очередь, являются символическими ссылками на определенные версии библиотек. Этот пример был выполнен в 64-разрядной операционной системе Fedora 12.
Листинг 3. Символические ссылки на библиотеки
$ ls -l /lib64/libc.so.6 /lib64/ld-linux-x86-64.so.2 lrwxrwxrwx. 1 root root 12 2010-01-14 14:24 /lib64/ld-linux-x86-64.so.2 -> ld-2.11.1.so lrwxrwxrwx. 1 root root 14 2010-01-14 14:24 /lib64/libc.so.6 -> libc-2.11.1.so
Виртуальные динамические разделяемые объекты Linux
В те времена, когда процессоры с архитектурой x86 только появились, взаимодействие пользовательских приложений со службами операционной системы осуществлялось с помощью прерываний. По мере создания более мощных процессоров эта схема взаимодействия становилась узким местом системы. Во всех процессорах, начиная с Pentium II, Intel реализовала механизм быстрых системных вызовов (Fast System Call), в котором вместо прерываний используются инструкции SYSENTER и SYSEXIT, ускоряющие выполнение системных вызовов.
Библиотека linux-vdso.so.1 является виртуальной библиотекой, или виртуальным динамически разделяемым объектом (VDSO), который размещается только в адресном пространстве отдельной программы. В более ранних системах эта библиотека называлась linux-gate.so.1. Эта виртуальная библиотека содержит всю необходимую логику, обеспечивающую для пользовательских приложений наиболее быстрый доступ к системным функциям в зависимости от архитектуры процессора – либо через прерывания, либо (для большинства современных процессоров) через механизм быстрых системных вызовов.