Почему код PIC реализован для разыменования дважды, а не один раз?

Из Позиционно-независимого кода (PIC) в разделяемых библиотеках я узнал, что при вызове кода PIC в linux сначала вызывается функция plt, а затем она вызывает (tail call) фактическую функцию. При первом вызове функции будет загружена функция.

Вопрос в том, почему не разыменовывать и вызывать указатель на функцию в GOT-записи напрямую, поскольку это имеет ряд преимуществ:

  1. Улучшенная производительность;
  2. Меньше места в памяти;
  3. Функции plt могут быть выгружены, если не нужны.

Я не вижу причин, почему это так не реализовано.

Редактировать:

Текущий импл:

  1. Вызовите функцию plt, перейдите по адресу, указанному в записи таблицы GOT.

  2. При первом вызове точка входа точно указывает на следующую инструкцию того же функционала plt.

  3. В остальной части функции plt он загрузит аргумент в загрузчик и вызовет загрузчик.

  4. После загрузки соответствующая запись GOT будет содержать адрес функции.

Как вы можете видеть, я не думаю, что есть причина добавлять этот дополнительный слой, поскольку то, что делает plt funcs, это просто прыжок (хвостовой вызов), даже удаление первой инструкции перехода и прямой вызов записи GOT будут работать.

Так что я не могу понять, почему они разработали это в первый раз.

Примечание: я также разместил тот же контент в stackru: почему код PIC реализован для разыменования дважды, а не один раз? Вы можете ответить на мой вопрос там, если хотите.

0 ответов

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