Почему не все позиции скомпилированного кода независимы? - PullRequest
68 голосов
/ 02 мая 2009

При компиляции разделяемых библиотек в gcc опция -fPIC компилирует код как независимый от позиции. Есть ли какая-либо причина (производительность или нет), почему бы вам не компилировать весь код независимо от позиции?

Ответы [ 8 ]

59 голосов
/ 02 мая 2009

Это добавляет косвенность. С позиционно-независимым кодом вы должны загрузить адрес своей функции и затем перейти к нему. Обычно адрес функции уже присутствует в потоке команд.

26 голосов
/ 05 ноября 2011

Эта статья объясняет, как работает PIC, и сравнивает ее с альтернативой - Перемещение времени загрузки . Я думаю, что это актуально для вашего вопроса.

26 голосов
/ 02 мая 2009

Да, есть причины производительности. Некоторые обращения фактически находятся под другим уровнем косвенности, чтобы получить абсолютную позицию в памяти.

Существует также GOT (таблица глобальных смещений), в которой хранятся смещения глобальных переменных. Для меня это просто выглядит как таблица исправлений IAT, которая классифицируется как позиция, зависящая от Википедии и нескольких других источников.

http://en.wikipedia.org/wiki/Position_independent_code

17 голосов
/ 02 мая 2009

В дополнение к принятому ответу. Одна вещь, которая сильно влияет на производительность кода PIC - это отсутствие «относительной IP-адресации» на x86. С помощью «IP относительной адресации» вы можете запросить данные, которые составляют X байтов из текущего указателя инструкции. Это сделало бы код PIC намного проще.

Прыжки и вызовы, как правило, относительны к EIP, поэтому они не представляют проблемы Однако для доступа к данным потребуется немного больше хитрости. Иногда регистр будет временно зарезервирован как «базовый указатель» на данные, необходимые для кода. Например, распространенным методом является злоупотребление работой вызовов на x86:

call label_1
.dd 0xdeadbeef
.dd 0xfeedf00d
.dd 0x11223344
label_1:
pop ebp            ; now ebp holds the address of the first dataword
                   ; this works because the call pushes the **next**
                   ; instructions address
                   ; real code follows
mov eax, [ebp + 4] ; for example i'm accessing the '0xfeedf00d' in a PIC way

Этот и другие методы добавляют слой косвенности к доступу к данным. Например, GOT (Глобальная таблица смещений), используемая компиляторами gcc.

x86-64 добавлен режим «RIP относительный», который упрощает lot .

2 голосов
/ 02 мая 2009

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

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

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

1 голос
/ 08 декабря 2015

position-independent code снижает производительность на большинстве архитектур, поскольку требует дополнительного регистра.

Итак, это для целей производительности.

1 голос
/ 02 мая 2009

Кроме того, аппаратное обеспечение виртуальной памяти в большинстве современных процессоров (используемых большинством современных ОС) означает, что большое количество кода (все приложения пользовательского пространства, за исключением странного использования mmap и т. П.) Не обязательно должны быть независимыми от позиции. Каждая программа получает свое собственное адресное пространство, которое, по ее мнению, начинается с нуля.

0 голосов
/ 11 октября 2016

В настоящее время операционная система и компилятор по умолчанию делают весь код как независимый от позиции код. Попробуйте выполнить компиляцию без флага -fPIC, код скомпилируется нормально, но вы просто получите предупреждение. Как и в Windows, для достижения этой цели используется метод, называемый отображением памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...