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