В 32-битных системах Linux, вызывая этот
$ /lib/libc.so.6
и на 64-битных системах это
$ /lib/x86_64-linux-gnu/libc.so.6
в оболочке, обеспечивает вывод как это:
GNU C Library stable release version 2.10.1, by Roland McGrath et al.
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.4.0 20090506 (Red Hat 4.4.0-4).
Compiled on a Linux >>2.6.18-128.4.1.el5<< system on 2009-08-19.
Available extensions:
The C stubs add-on version 2.1.2.
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
Native POSIX Threads Library by Ulrich Drepper et al
BIND-8.2.3-T5B
RT using linux kernel aio
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.
Почему и как это происходит, и как это можно сделать в других общих библиотеках?
Я посмотрел, /usr/lib
чтобы найти исполняемые файлы, и я нашел /usr/lib/libvlc.so.5.5.0
. Запуск его привел к ошибке сегментации . : - /
Ответы:
Эта библиотека имеет
main()
функцию или эквивалентную точку входа и была скомпилирована таким образом, что она полезна как в качестве исполняемого файла, так и в качестве общего объекта.Вот одно предложение о том, как это сделать, хотя у меня это не работает.
Вот еще один ответ на аналогичный вопрос о SO , который я бесстыдно плагиат, подправлю и добавлю немного объяснений.
Во-первых, источник для нашей библиотеки примеров
test.c
:Скомпилируйте это:
Здесь мы компилируем разделяемую библиотеку (
-fPIC
), но сообщаем компоновщику, что это обычный исполняемый файл (-pie
), и делаем свою таблицу символов экспортируемой (-Wl,-E
), чтобы с ней можно было с пользой связываться.И, хотя
file
он скажет, что это общий объект, он работает как исполняемый файл:Теперь нам нужно посмотреть, действительно ли это может быть динамически связано. Пример программы
program.c
:Использование
extern
избавляет нас от необходимости создавать заголовок. Теперь скомпилируйте это:Прежде чем мы сможем выполнить его, нам нужно добавить путь
libtest.so
для динамического загрузчика:В настоящее время:
И
ldd a.out
покажет связь сlibtest.so
.Обратите внимание , что я сомневаюсь , что это как Glibc на самом деле составлена, так как это, вероятно , не так , как портативные сам Glibc (см
man gcc
отношении к-fPIC
и-pie
переключателям), но она демонстрирует базовый механизм. Чтобы узнать подробности, вам нужно взглянуть на исходный make-файл.источник
nm
в общей библиотеке, но это была не отладочная версия. Итак, почемуlibvlc
и другие терпят крах?libc
является исключением.ld
иlibpthread
.ld.so
особенный в других отношениях. В некоторой степени это более настоящий исполняемый файл, чем обычный динамически связанный исполняемый файл.Давайте погрузимся за ответ в случайном репозитории glibc в github. Эта версия предоставляет «баннер» в файле
version.c
.В том же файле есть несколько интересных моментов:
__libc_print_version
функция, обеспечивающая печать на стандартный текст и символ,__libc_main (void)
который задокументирован как точка входа. Так что этот символ вызывается при запуске библиотеки.Так как же компоновщик / компилятор знает, что это именно функция точки входа?
Давайте погрузимся в make-файл . В флаге компоновщика есть интересный флаг:
Так что это флаг компоновщика для установки точки входа в библиотеку. При сборке библиотеки вы можете предусмотреть
-e function_name
для компоновщика создание исполняемого поведения. Что это действительно делает? Давайте посмотрим на руководство (несколько устаревшее, но все еще действующее) :(текущую документацию можно найти здесь )
Реально
ld
компоновщик создает исполняемый файл с функцией точки входа, если вы предоставляете ему опцию командной строки-e
(наиболее практичное решение), предоставляете символ функцииstart
или вводите адрес символа в ассемблере.Однако обратите внимание, что явно не гарантируется работа с другими компоновщиками (я не знаю, имеет ли llvm lld такой же флаг). Почему это должно быть полезно для других целей, кроме предоставления информации о файле, я не знаю.
источник