2013-07-27 3 views
2

Насколько мне известно, x64-ассемблерный код очень ограничен ограниченным количеством регистров.Создайте файлы .SO в Linux без использования PIC (позиция независимого кода) (x86 32bit)

Когда я узнал, что в Linux для создания файла .so необходимо указать аргумент командной строки -fPIC для gcc, чтобы создать независимый от позиции код, я не мог в это поверить.

Насколько я знаю, формат файла elf поддерживает перемещение, так же как и в моих глазах намного лучше - работает система Windows DLL: в Windows компоновщик переносит все смещения в DLL, если это необходимо.

Я думаю, что время, необходимое для загрузки SO-файла или DLL-файла, а также объем памяти, используемый для перемещения по-разному перемещенных .so-файлов, не так плох, как отсутствие целого регистра всех время, которое указывает на GOT и все эти косвенные прыжки.

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

1) Почему Linux не поддерживает более динамическую загрузку библиотеки, например Windows, которая должна производить гораздо более эффективный код?

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

2) Возможно ли, чтобы я создал НЕ-фиктивные скомпилированные SO-файлы в Linux? Могу ли я просто оставить -fPIC? Есть ли какие-либо инструкции, руководство или проект, который работает по этой теме и позволяет не тратить весь реестр и динамически загружать библиотеки?

Что произойдет, если я просто удалю -fPIC при компиляции .so-файла?

+1

Вы больше всего интересуетесь IA32 или x86-64? Любой ответ будет зависеть от этого различия. –

+0

Я занимаюсь 32-битным кодом и скорректировал заголовок вопроса – Christian

+1

Для интенсивных вычислений программы действительно стоит (по многим причинам) переключиться на 64-битный linux. –

ответ

4

Что произойдет, если я просто сниму -fPIC при компиляции файла .so?

Полученный общий объект ELF-файл будет (очень вероятно) быть динамически загружены на полу-случайных (т.е. непредсказуемые) адресов страниц (например, потому что mmap системный вызов будет сталкиваться с ASLR).

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

Таким образом, на практике забывание -fPIC об общем объекте (то есть динамически связанной библиотеке) чаще всего является плохой идеей, даже если это возможно.

Читать Drepper's HowTo do Dynamic Shared Libraries бумаги и Уилера Program Library Howto

КСТАТИ position independent code гораздо дороже на x86 (32 бита), чем на x86-64. Но это стоит усилий (возможно, код PIC не более 5-10% медленнее, чем не-PIC на x86 32 бита).

+0

Спасибо! Замечательно, что ld.so может делать то, что я хочу. Я читал другие вещи, которые вы пишете и в других местах, но мне интересно, действительно ли объем работы, который должен выполнять ld.so, действительно важен во всех сценариях. Напр. серверный процесс, когда все перемещается, где проблема? И получить до 10% производительности, потому что один реестр не тратится впустую, и все прыжки могут быть прямыми, кажется, очень хорошо стоят усилий в некоторых обстоятельствах. Интересно, почему я не видел никакого текста о pic и переездах, в котором говорится, что кто-то может скорее пойти со скоростью выполнения, чем с быстрой загрузкой – Christian