Почему я не могу напрямую запустить общую библиотеку в Linux? - PullRequest
3 голосов
/ 05 октября 2010
$ chmod +x libsomelibrary.so
$ ./libsomelibrary.so
Segmentation fault

$ gcc -O2 http://vi-server.org/vi/bin/rundll.c -ldl -o rundll
$ ./rundll ./libsomelibrary.so main
(application starts normally)

Почему я не могу просто запустить libsomelibrary.so, если у него есть используемая точка входа?

rundll.c тривиально:

void* d = dlopen(argv[1], RTLD_LAZY);
void* m = dlsym(d, argv[2]);
return ((int(*)(int,char**,char**))m)(argc-2, argv+2, envp);

Почему он не используется внутри при попытке загрузить бинарный файл?

Ответы [ 3 ]

4 голосов
/ 05 октября 2010

main не является точкой входа, распознаваемой ядром или динамическим компоновщиком - она ​​вызывается кодом запуска, связанным с вашим исполняемым файлом, когда вы его компилируете (такой код запуска по умолчанию не связан с общими библиотеками).

Заголовок ELF содержит начальный адрес.

3 голосов
/ 05 октября 2010

Вы можете запускать общие библиотеки в Linux.

Например, если вы запустите /lib/libc.so.6, он напечатает номер своей версии:

$ /lib/libc.so.6
GNU C Library stable release version 2.12, by Roland McGrath et al.
Copyright (C) 2010 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.5.0 20100520 (prerelease).
Compiled on a Linux 2.6.34 system on 2010-05-29.
Available extensions:
        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
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.

В вашей библиотеке что-то не хватает.

3 голосов
/ 05 октября 2010

Общие библиотеки не предназначены для непосредственного запуска. Они предназначены для связи в другой кодовой базе. Он может иметь пригодную для использования точку входа, но быть исполняемым подразумевает нечто большее, чем просто наличие используемой точки входа. Утилита rundll является доказательством этого. Ваш второй тест показывает, что разделяемая библиотека действительно является исполняемой, но только после rundll делает некоторую работу. Если вам интересно, что нужно сделать, прежде чем код библиотеки может быть выполнен, взгляните на исходный код rundll.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...