Разрешение символов и динамическое связывание

Я читал о процессе перемещения и разрешения символов, и у меня есть несколько вопросов по этому поводу.

Таким образом, весь процесс (загрузка исполняемого файла) начинается с команды exec(BA_OS). Во время exec(BA_OS) система извлекает имя пути из сегмента PT_INTERP и создает исходный образ процесса из сегментов файла интерпретатора. То есть вместо использования образов сегментов исходного исполняемого файла система составляет образ памяти для интерпретатора. Затем интерпретатор несет ответственность за получение управления от системы и предоставление среды для прикладной программы.

После этого динамический компоновщик делает следующее (пока LD_BIND_NOW имеет ненулевое значение):

  • Добавление сегментов памяти исполняемого файла в образ процесса;
  • Добавление сегментов разделяемой объектной памяти в образ процесса;
  • Выполнение перемещений исполняемого файла и его общих объектов;
  • Закрытие дескриптора файла, который использовался для чтения исполняемого файла, если он был передан динамическому компоновщику;
  • Передача управления программе, создающая впечатление, что программа получила управление непосредственно от exec(BA_OS).

Итак, мой вопрос сейчас

<сильный>1. Когда эти общие объекты загружаются в память?

Второй шаг выше указывает, что компоновщик добавляет сегменты памяти общих объектов в образ процесса. Все ли (и под всеми я подразумеваю общие объекты и их зависимости и зависимости от них и т.д.) загружены библиотеки в этот момент? Или компоновщик только создает образ процесса с использованием зависимостей и загружает библиотеку в физическую память позже, когда это необходимо?

<сильный>2. Как динамический компоновщик получает адрес для исправления записи GOT символа?

Ниже показано, что происходит (или то, что я знаю, что происходит), когда функция вызывается в первый раз.

  • Перейдите к записи PLT нашего символа.
  • Перейдите к записи GOT нашего символа.
  • Вернитесь к записи PLT и поместите смещение в стек. Что смещение на самом деле является структурой Elf_Rel, описывающей, как исправлять символ.
  • Перейти к записи-заглушке PLT.
  • Нажмите указатель на структуру link_map (в другой статье это был указатель на таблицу перемещений), чтобы компоновщик нашел, к какой библиотеке принадлежит символ.
  • Вызов динамического компоновщика.
  • Исправьте запись GOT.

Что делает динамический компоновщик, когда он вызывается? Как он использует элементы стека (смещение и указатель) для исправления записи GOT? Предположим, что имеется большое количество файлов .so. Существует ли порядок, в котором динамический компоновщик выполняет поиск в этих файлах?


Я только начал изучать этот материал. Пожалуйста, поправьте меня, если мое понимание неверно. Если вы знаете какие-либо другие хорошие ресурсы, пожалуйста, дайте мне знать.


person ray an    schedule 21.05.2018    source источник