можно выразиться). Занимаюсь я просто реализацией аналогов "dlopen", "dlsym" и "dlclose" с нуля. Как я поняла, вот у shared object'а есть сегменты, и нужно сегменты с флажком "PT_LOAD" отдельно маппить в память (каждый раз отдельно вызывать "mmap") или более ничего? Или как-то иначе это работает? Не нашла, где это описывается достаточно подробно. А реализации функций в "glibc" том же крайне сложно пока прочесть и понять
для .so надо ещё DT_DYNAMIC парсить
Да, это я поняла уже. А обычно принято для парсинга просто временно маппать весь файл в память временно? Или же пользовать системными I/O-функциями?
как удобно так и делай, главное чтобы все DT_LOAD были замаплены по своим адресам со смещением
Если у нас 1-ый PT_LOAD-сегмент лежит по виртуальному адресу 0x0000 (как записано в файле), 2-ой - в 0x1000, 3-ий - в 0x1800, то у них, соответсвенно, должны быть по итогу адреса base + 0x0000, base + 0x1000 и base + 0x1800? Я же правильно поняла?
единственное, в зависимости от архитектуры может понадобится некоторые сегменты пропатчить
Не обязательно если не нужна поддержка отладки
обязательно там важные вещи лежат, в частности оттуда можно до таблиц символов добраться, чтобы линковать
Делается mmap на нужный размер. Потом поверх него mnap с флажком map_fixed для маппинга rwe сегментов
оттуда же, емнип, и релоки достаются
Потом mremap после патча абсолютных релокаций
То есть, мы подсчитываем в целом, сколько нам нужно вообще байтов в целом на все сегменты с учётом прописанных им виртуальных адресов ("p_vaddr") и размеров в памяти ("p_memsz"), делаем один большой "mmap" с этим размером, получаем базовый адрес, а затем на основе него начинаем отдельно мапать каждый сегмент с offset'ом от базового адреса, который нам теперь дан, на основе "p_vaddr" и с нужными флажками доступа? Вдруг я не так поняла
Несколько запуталась, на каком этапе тогда нужно патчить/релоцировать?
Обсуждают сегодня