Загрузка файлов .so из памяти

Возможный дубликат:
dlopen из памяти?

Я видел это для DLL-файлов Windows, загружаемых из буфера памяти, но я нигде не могу найти его для Linux, а исходный код «ld» — самый сложный код, который я когда-либо видел. Так:

Есть ли пример загрузки файлов .so из памяти? Даже простой, который я могу закончить? Я просто не знаю, с чего начать, хотя я прочитал большую часть спецификаций ELF, это все еще для меня загадка.


person killercode    schedule 26.01.2012    source источник
comment
.so отправляется через сокетное соединение, и я ищу решение, а не альтернативу.   -  person killercode    schedule 26.01.2012
comment
@killercode вы ищете решение проблемы, которую вы определили довольно узко. В настоящее время вам не хватает знаний для кодирования .so по памяти, и вы хотите заплатить кому-то еще за это. Альтернативы имеют больше смысла, если вы не можете дать нам некоторый контекст.   -  person Dan Fego    schedule 26.01.2012
comment
.so отправляется через сокеты, я не хочу записывать его на диск, так как мое приложение может не иметь права записывать файлы на диск, поэтому я хочу запустить его из памяти, чтобы избежать любого из них на любой платформе, а не только линукс.   -  person killercode    schedule 27.01.2012
comment
killercode... Не могли бы вы найти ответ? У вас есть код, чтобы показать?   -  person Morteza Milani    schedule 13.03.2013


Ответы (3)


Вы смотрите на исходный код неправильной вещи: ld не выполняет загрузку программ и библиотек. Вместо этого вам следует взглянуть на исходный код функций dlopen и dlsym, найденный в libc. Кроме того, вы должны посмотреть на источник динамического компоновщика: ld-linux.so (настоящее имя зависит от платформы; выполните ldd /bin/ls, чтобы узнать, где находится динамический компоновщик).

Разбор ELF не сложен, но требует внимания к деталям и понимания ассемблерного кода для конкретного процессора; вам также нужна спецификация ABI для вашей платформы (и она отличается для 32- и 64-битного Linux, а также отличается для разных процессоров).

Если вам просто нужно загрузить объектные файлы из памяти во время выполнения (т. е. это не обязательно должна быть SO), вы можете взглянуть на проект X11: они реализовали модульную систему, которая, в основном загружает объектный код по некоторому адресу и перемещает его.

person zvrba    schedule 26.01.2012

Вам понадобится семейство функций dlopen() (в GNU/Linux они определены в /usr/include/dlfcn.h).

Например, взгляните на как PHP делает модули.

person Victor Vasiliev    schedule 26.01.2012
comment
я знаю, как использовать .so с диска, я хочу использовать их из памяти, их не будет на диске - person killercode; 26.01.2012

Что для вас означает «загрузка .so файлов из памяти»?

Если у вас есть какой-либо *.so файл, то он находится в какой-то файловой системе и имеет путь. Затем просто используйте dlopen на нем.

Если это не файл, что это? Как вы попали в память? Что именно у вас осталось в памяти? (Есть ли у вас заголовок ELF и раскладка ELF в памяти?)

Если у вас достаточно информации для создания файла ELF *.so, сделайте дамп (то есть запишите) такой файл в какую-нибудь файловую систему (используйте временную файловую систему, например tmpfs, если вас беспокоит производительность диска). Тогда dlopen это.

Если у вас недостаточно информации для создания файла ELF .so, возможно, вы динамически создаете код в памяти. Посмотрите, какая существующая инфраструктура генерации машинного кода (например, LLVM, GCCJIT, libjit , молния GNU, LuaJit ....).

Если у вас есть полный функциональный код в памяти, убедитесь, что память является исполняемой с помощью mmap & mprotect и перейти к нему (например, используя трюки с указателями функций).

person Basile Starynkevitch    schedule 26.01.2012
comment
Я очень удивлен отрицательным отзывом. Что я сказал не так? Почему мой ответ не актуален? - person Basile Starynkevitch; 26.01.2012
comment
Не совсем отвечая на то, чего он вроде бы пытается (упорно) добиться так, как хочет, но эта информация в целом полезная. +1 - person Dan Fego; 26.01.2012
comment
Я не понимаю, что именно означает оригинальный постер, загружая файл .so из памяти... (или даже загружая любой файл из памяти), поскольку файл можно прочитать только из файловой системы. Я предполагаю, что в Windows была такая функция, потому что (IIRC) в Windows несколько процессов не могут работать с файлом одновременно (например, вы не можете удалить файл, который открыт другим процессом в Windows, но вы можете сделать это в Linux) . - person Basile Starynkevitch; 26.01.2012
comment
Он предполагает передачу файла .so через сокет, так что он имеет содержимое всего файла в памяти и хочет фактически dlopen() оттуда, а не с диска. - person Dan Fego; 26.01.2012
comment
На оригинальном плакате не упоминались какие-либо розетки или трубы. Но если он получает содержимое .so ELF-файла с таким файловым дескриптором (недоступным для поиска и mmap), единственный разумный вариант — записать его в файл, а затем dlopen в этот файл. - person Basile Starynkevitch; 26.01.2012