Загрузка.so файлов из памяти
Возможный дубликат:
извлекать из памяти?
Я видел это для DLL-файлов Windows, загружаемых из буфера памяти, но я не могу найти его где-нибудь для Linux, и исходный код "ld" - самый сложный код, который я когда-либо видел. Так:
Есть ли пример загрузки.so файлов из памяти? Даже простой, который я могу закончить? Я просто не знаю, с чего начать, хотя я прочитал большинство спецификаций ELF, для меня это все еще загадочно.
3 ответа
Вы смотрите на исходный код неправильной вещи: ld
не выполняет загрузку программ и библиотек. Вместо этого вы должны посмотреть на исходный код dlopen
а также dlsym
функции найдены в libc. Кроме того, вы должны посмотреть на источник динамического компоновщика: ld-linux.so (истинное имя зависит от платформы; выполнить ldd /bin/ls
чтобы узнать, где находится динамический компоновщик).
Разбор ELF не сложен, но требует внимания к деталям и понимания кода сборки для конкретного процессора; вам также нужна спецификация ABI для вашей платформы (и она отличается для 32- и 64-битных Linux, а также для разных процессоров.)
Если вам просто нужно загрузить объектные файлы из памяти во время выполнения (т. Е. Это не обязательно должен быть SO), вы можете посмотреть на проект X11: они реализовали модульную систему, которая, в основном, загружает объектный код в некоторых адрес и перемещает его.
Что значит "загрузка" .so
файлы из памяти "значит для тебя?
Если у тебя есть *.so
файл, то он находится в некоторой файловой системе и имеет путь. Тогда просто используйте dlopen
в теме.
Если это не файл, что это? Как ты попал в память? Что именно у тебя в памяти? (У вас есть заголовок ELF и расположение ELF в памяти?)
Если у вас есть достаточно информации, чтобы сделать ELF *.so
файл, сбросить (т.е. записать) такой файл в некоторую файловую систему (использовать временную файловую систему, такую как tmpfs
если вы заинтересованы в производительности диска). затем dlopen
тот.
Если у вас недостаточно информации для создания ELF .so
файл, то, вероятно, вы динамически строите код в памяти. Посмотрите, что делает существующая инфраструктура генерации машинного кода (например, LLVM, GCCJIT, libjit, GNU lightning, LuaJit....).
Если у вас есть полный функциональный код в памяти, убедитесь, что память является исполняемой с помощью mmap & mprotect, и перейдите в нее (например, используя приемы указателей на функции).
Вам необходимо семейство функций dlopen() (в GNU/Linux они определены в /usr/include/dlfcn.h).
Для примера рассмотрим, как PHP работает с модулями.