Перемещение символа

Ниже показано, как будет вызван вызов функции (в первый раз) в PIC

  1. Перейти к PLT запись нашего символа.
  2. Перейти к GOT запись нашего символа.
  3. Перейти к PLT введите и сдвиньте смещение в стеке. Что смещение на самом деле Elf_Rel структура, описывающая, как исправить символ.
  4. Перейти к PLT запись окурка.
  5. Нажмите указатель на link_map структура для того, чтобы компоновщик мог найти, к какой библиотеке принадлежит символ.
  6. Процедура распознавания вызовов.
  7. Патч GOT запись.

Это отличается от того, как делается ссылка на данные, которая просто использует GOT Таблица

Итак, почему эта разница? Почему 2 разных подхода?


1 ответ

Решение

почему есть эта разница? Почему 2 разных подхода?

То, что вы описали, это ленивый переезд.

Вы не должны использовать это, и не будете использовать это, если, например, LD_BIND_NOW=1 устанавливается в окружающей среде.

Это оптимизация: она позволяет вам сократить объем работы, которую должен выполнять динамический компоновщик, когда при вызове конкретной программы не выполняется много возможных путей выполнения программы.

Представьте себе программу, которая может вызывать foo(), bar() или же baz(), в зависимости от аргументов, и который вызывает ровно одну из подпрограмм в любом данном исполнении.

Если вы не использовали отложенное перемещение, динамический загрузчик должен был бы разрешить все 3 подпрограммы при запуске программы. Ленивое перемещение позволяет динамическому загрузчику выполнять только одно перемещение, которое фактически требуется в любом данном выполнении (ту функцию, которая вызывается), и точно в нужное время (когда функция вызывается).

Теперь, почему переменные не могут быть разрешены таким образом?

Потому что у динамического загрузчика нет удобного способа узнать, когда выполнять это перемещение.

Предположим, что глобалы a, b а также c и что foo() Рекомендации a а также b, bar() Рекомендации b а также c, а также baz() Рекомендации a а также c, Теоретически динамический загрузчик может сканировать тела foo, bar а также baz и построить карту "если звонит foo, а затем разрешить глобальные a а также b "и т. д. Но гораздо проще и быстрее разрешить все ссылки на глобальные переменные при запуске.

Другие вопросы по тегам