Подтвердить что ты не робот

Почему не все скомпилированные позиции кода независимы?

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

4b9b3361

Ответ 1

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

Ответ 2

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

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

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

Ответ 4

В дополнение к принятому ответу. Одна вещь, которая сильно вредит производительности кода 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 relative", который упрощает работу лот.

Ответ 5

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

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

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

Ответ 6

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

Ответ 7

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

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

Ответ 8

Вопрос датируется 2009 годом. Прошло десять лет, и теперь весь код фактически не зависит от позиции. Это теперь обеспечивается операционными системами и компиляторами. Нет возможности отказаться. Весь код принудительно компилируется с помощью PIE, а флаг -no-pic / -no-pie игнорируется как часть этого оправдания ASLR. Причиной этого является замедление ранее быстрых приложений и продажа более нового оборудования под маской повышенной безопасности. Это совершенно иррационально, потому что теперь большие объемы памяти позволяют нам вообще избавиться от адской динамической компоновки, статически компилируя все приложения.

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

Вы не жалуетесь, потому что вы даже не знаете, что все эти учебные колеса мешают вашему коду. Что я могу сказать? Наслаждайтесь в 2 раза медленнее программного обеспечения с их PIC сейчас! Более того, с появлением LLVM скоро появится принудительный JIT (управляемый код) без доступа к встроенной сборке x86, что еще больше замедлит любой код C/C++. "Те, кто жертвует свободой ради безопасности, не заслуживают ни того, ни другого".

Ответ 9

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