[devel] IA: eliminating TEXTRELocations

Dmitry V. Levin =?iso-8859-1?q?ldv_=CE=C1_altlinux=2Eorg?=
Сб Ноя 8 18:57:31 MSK 2003


Greetings!

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

Об одной такой проблеме т.н. "text relocations" я расскажу подробнее.

Начну с вольного перевода нескольких фрагментов из статьи
"How To Write Shared Libraries" (Ulrich Drepper,
http://people.redhat.com/drepper/dsohowto.pdf, 2003, версия 1.2).

"Самое главное - всегда использовать параметры -fpic либо -fPIC при
порождении кода, который в конечном итоге попадёт в DSO.  Эта
рекомендация применима в равной степени как к коду, так и к данным. Код,
который не был скомпилирован таким образом, будет содержать text
relocations.  Этому нет оправдания.  Text relocations требуют от
динамического компоновщика (dynamic linker) дополнительной работы.
Аргументы, базирующиеся на утверждении, что код не является разделяемым
потому, что другие процессы не используют этот DSO, не верны.  В таком
случае вообще нет смысла использовать DSO; соответствующий код следует
просто собирать в составе приложения."

"Результат любого перемещения (relocation) будет сохранен в виде ссылки
где-то в DSO.  В нормальной ситуации это место будет расположено в
сегменте данных.  В случае некорректно порождённого пользователем,
компилятором или компоновщиком кода перемещения могут затрагивать сегменты
кода и read-only данных.  Динамический компоновщик в состоянии обработать
корректно эту ситуацию только в случае, если DSO, в соответствие со
спецификацией формата ELF, содержит пометку DT_TEXTREL в его динамической
секции (dynamic section).  В результате, к сожалению, изменённая страница
памяти больше не будет разделяемой, т.е. не сможет быть использована
другими процессами.  Сам процесс text relocation также довольно длительный
ввиду того, что ядро производит дополнительные изменения в структурах
хранения информации по управлению памятью.  И, наконец, код и данные,
которые могли бы быть размещены в read-only памяти, оказываются в обычной
памяти, доступной для случайного изменения вследствие сбоя в программе."

Проверить, содержит ли данный конкретный DSO text relocations (т.е.
помечен ли он как содержащий text relocations), легко:
"readelf -d binary |fgrep TEXTREL" или "objdump -p binary |fgrep TEXTREL"
- выбирайте любой способ.

Вот список пакетов в Сизифе, которые в принципе собираются (точнее говоря,
процесс сборки которых доходит как минимум до завершения секции %install),
но при этом содержат text relocations:

AfterStep-2.0-alt1.cvs20031017
Mesa-5.0.1-alt7
SDL-1.2.6-alt1
TORCS-1.2.1-alt1
XFree86-4.3.0-alt6
a52dec-0.7.4-alt2
allegro-4.0.3-alt1
alsa-patch-bay-0.5.1-alt0.7
arj-3.10b-alt2
avifile-0.737-alt0.7
beep-1.0.0-alt0.1pre4
compat-libstdc++-egcs-alt1
cups-1.1.18-alt8.3
doomlegacy-1:1.41-alt1
em8300-0.13.0.cvs-alt3
ffmpeg-0.4.8-alt1
fglrx_glx-3.2.8-alt1
flac-1.1.0-alt3
gammu-0.88-alt1
gnokii-0.5.5-alt1
gnu-ghostscript-7.07-alt0.1
goblin-2.5-alt1
gstreamer-plugins-0.6.4-alt1
gthumb-2.1.8-alt1
hermes-1.3.3-alt1
imlib2-1.0.6-alt4
j2se1.3-sun-1.3.1_03-alt1
j2se1.4-blackdown-1.4.1_01-alt2
j2se1.4-sun-1.4.2_01-alt2
kdemultimedia-3.1.4-alt2
kudzu-1.1.13-alt4
lablGL-1.00-alt1
ladspa-guitar-preamp-1.0-alt1
ladspa-guitar-super-60-1.0-alt1
ladspa-guitar-unmatched-1.0-alt1
ladspa-moogvcf-plugins-1.1-alt0.5
lame-3.93.1-alt2
libalsa-0.9.8-alt1
libassuan-0.6.0-alt1
libdv-0.99-alt1
libfame-0.9.0-alt2
liblcms-1.09-alt1
libmpeg3-1.5.0-alt1
libnet1-1.0.2a-ipl4mdk
libopenh323-1.11.2-alt2
libquicktime-0.9.2-alt1.1
lockdev-1.0.1-alt1
mjpegtools-1.6.1.90-alt2
mnogosearch-ruby-1.0.3-alt1
mpeg2dec-0.3.1-alt1.5cvs20030408
mpeg_lib-1.3.1-ipl11mdk
mpfc-1.0-alt1
muse-0.6.1-alt0.5
nvidia_glx_src_1.0.4363-1.0.4363-alt5
nvidia_glx_src_1.0.4496-1.0.4496-alt6
ocaml-mysql-1.0.1-alt1
ocaml-postgres-20010808-alt11s
ocamlgsl-0.2.2-alt3
ocamlnet-0.96-alt4s
openoffice-1:1.0.2-alt5
opensc-0.7.0-alt1
openssl-0.9.6k-alt1
pcre-ocaml-4.28.3-alt5s
ppp-2.4.1.20030923-alt1
pxp-1.1.94-alt3s
python21-2.1.3-alt5.1
reiserfs-utils-1:3.6.4-alt2
rte-0.5.1-alt2
ruby-gdchart-0.0.9-alt3
tcl-cost-2.2-alt4.p1
transcode-0.6.10-alt2
transconnect-1.3-alt1
tuxvsclippy-0.2.3-alt1
valgrind-2.0-alt0.20030725
valgrind-calltree-0.9.4-alt2
veejay-0.5.1-alt0.5
wine-20030911-alt1
xine-1.0.0-alt2.rc2
xmms-defx-0.9.9-alt1
xmms-kjofol-0.95-alt4
xmms-kjofol-skins-1.2.0-alt3
xmms-musepack-0.98-alt1
xmp-2.0.5-alt0.6pre3
xvid-0.9.2-alt1
zinf-2.2.4-alt1

Я внедрил проверку на TEXTREL в verify_elf очередной версии rpm-build.
По умолчанию она будет включена.

Теперь verify_elf будет содержать 2 проверки: RPATH и TEXTREL.

Чтобы ослабить проверку RPATH, можно использовать либо прежнее выражение
%set_verify_elf_method relaxed
либо новую форму выражения
%set_verify_elf_method rpath=relaxed

Чтобы ослабить проверку на TEXTREL, можно использовать новую форму
выражения
%set_verify_elf_method textrel=relaxed

Чтобы ослабить проверку обоих параметров, можно использовать новую форму
выражения
%set_verify_elf_method rpath=relaxed,textrel=relaxed

Разумеется, ослаблять проверки, включённые по умолчанию, не
рекомендуется.

Если вы собираете пакет, содержащий лишь разделяемые библиотеки, то для
решения проблемы TEXTREL, как правило, достаточно применить выражение
%add_optflags %optflags_shared

Если в пакете присутствуют как DSO, так и обычные исполняемые приложения,
то проблему TEXTREL, как правило, можно решить путём корректировки CFLAGS
в makefile'ах.

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


--
ldv
----------- следующая часть -----------
Было удалено вложение не в текстовом формате...
Имя     : =?iso-8859-1?q?=CF=D4=D3=D5=D4=D3=D4=D7=D5=C5=D4?=
Тип     : application/pgp-signature
Размер  : 189 байтов
Описание: =?iso-8859-1?q?=CF=D4=D3=D5=D4=D3=D4=D7=D5=C5=D4?=
Url     : <http://lists.altlinux.org/pipermail/devel/attachments/20031108/1f2352e3/attachment-0001.bin>


Подробная информация о списке рассылки Devel