Çalışma Zamanında Kütüphanelerin Aranması
Çalışma zamanında kütüphanelerin aranmasında, derleme zamanına görece, daha karmaşık bir yol izlenmektedir. İlk olarak kütüphanelerin aranmasıyla ilgili, derleme sürecini de ilgilendiren, bir özellikten bahsedelim.
Arama Dizinlerinin ELF Dosya İçeriğine Yazılması
Çalışma zamanında kütüphanelerin, standart arama dizinlerine ek olarak, nerelerde aranacağı ELF dosya içeriğine yazılabilmektedir. Çalışabilir ve paylaşımlı kütüphane dosyalarının her ikisinde de bu özellik kullanılabilmektedir.
Gerekli kütüphanelerin standart aranacak dizinlerde olmadığı ve konumlarının bilindiği durumlarda bu özellik kullanışlı olabilmektedir. Bağlayıcı bu amaçla rpath seçeneğini barındırmaktadır. Basit bir örnek üzerinden bu özelliği inceleyelim. Uygulama ve kütüphane kodlarını sırasıyla driver.c ve test.c olarak isimlendirelim.
İlk olarak, bu zamana kadar yaptığımız gibi kütüphaneye ilişkin herhangi bir arama bilgisi kullanmaksızın dosyaları derleyelim.
Uygulamayı çalıştırdığımızda, dinamik bağlayıcı tarafından, aşağıdaki gibi bir hata almaktayız.
Dinamik bağlayıcı, driver uygulamasının bağımlılık listesinde bulunan libtest.so dosyasını, öntanımlı baktığı dizinlerde, bulamadığından uygulamayı çalıştıramamaktadır. Dinamik bağlayıcı tarafından uygulamanın çalıştığı dizine bakılmamaktadır. Standart dışı dizinlerde bulunan kütüphanelerin dinamik bağlayıcıya, daha pratik olarak, nasıl gösterilebileceğine bakacağız, fakat bu noktada bu işlemin rpath ile nasıl yapılabildiğine bakalım.
Test amaçlı olarak çalışma dizinimizde lib adıyla bir dizin oluşturup, libtest.so dosyasını bu dizine kopyalayalım.
Uygulamamızı bu sefer kütüphaneye ilişkin arama dizin bilgisiyle beraber derleyelim.
Not: PWD çevre değişkeni çalışılan dizini göstermektedir.
Bu sefer dinamik bağlayıcı libtest.so dosyasını bulmakta ve uygulamayı çalıştırabilmektedir.
Bu noktada derleme işleminde hem L hem de rpath seçeneklerine lib değerini geçirdik, fakat bu değerler birbirinden farklı olabilirdi. L seçeneği geliştirme ortamına rpath ise çalışma ortamına ilişkindir.
Uygulama veya kütüphane dosyalarının rpath listeleri ELF içinde DT_RPATH isimli bir alanda tutulmaktadır, bu bilgiye aşağıdaki gibi ulaşmak mümkündür.
Dinamik bağlayıcı kütüphaneleri ararken, ilk olarak rpath listesindeki dizinlere bakmaktadır. Bağlayıcının bu davranışı değiştirilebilmesine karşın, bu özellik her zaman kullanışlı olmamaktadır. Test ortamlarında standart dışı dizinlerde bulunan kütüphaneler dinamik bağlayıcıya gösterilmek istenmektedir, rpath bu yöntemin kullanılmasını engellemektedir. Bu yüzden ELF formatına önceliği daha düşük DT_RUNPATH isimli bir alan eklenmiştir. rpath olarak bu alanın kullanılabilmesi için bağlayıcıya --enable-new-dtags seçeneği geçirilmelidir.
Not: Bağlayıcıya --inhibit-rpath seçeneği geçirilerek, rpath listesine bakması engellenebilir.
Aynı uygulamayı bu şekilde tekrar derleyelim.
Bu durumda ELF içinde DT_RUNPATH alanının kullanıldığını görmekteyiz.
rpath dizinleri mutlak olmak zorunda değildir, driver uygulamasını bu kez yalnız lib dizinini göstererek derleyelim.
Uygulamanın çalıştığı dizinde lib dizini bulunduğu için bir problem çıkmayacaktır. Şimdi çalışma dizinimizde test isimli bir dizin oluşturalım ve uygulamayı bu dizindeyken çalıştırmayı deneyelim.
Dinamik bağlayıcı çalışma dizininde lib dizinini bulamadığı için beklediğimiz üzere hata vermektedir. Dinamik bağlayıcının, göreli yol ifadelerini çözümlerken, çalışma dizini yerine uygulamanın bulunduğu dizine bakması sağlanabilir. Bunun için $ORIGIN özel değeri kullanılmaktadır. $ORIGIN değeri, dinamik bağlayıcı tarafından, uygulamanın veya paylaşımlı kütüphanenin bulunduğu dizin ifadesine genişletilir. Tekrar çalışma dizinine geçerek örneğimizi aşağıdaki gibi tekrar derleyelim. Sonrasında test dizinine geçip tekrar çalıştıralım.
Uygulamanın bu kez sorunsuz çalıştığını görmekteyiz. Bu özellik uygulamanın gerekli kütüphanelerle beraber dağıtıldığı durumlarda oldukça işe yaramaktadır. Örneğin, uygulama ve gerekli kütüphaneler arşivlendikten sonra hedef sistemde istenilen bir dizine açılarak çalıştırılabilir. Hedef sistemde kütüphaneler herhangi başka bir yere kopyalanmak zorunda değildir, ayrıca uygulamanın bulunduğu dizin PATH çevre değişkenine eklenerek, uygulama herhangi bir dizinden çalıştırılabilir.
Not: rpath seçeneğine alternatif olarak, önceliği daha düşük olan, LD_RUN_PATH çevre değişkeni kullanılabilir.
Standart Dışı Dizinlerde Arama
Standart dışı dizinlerin dinamik bağlayıcıya gösterilmesi gerekmektedir. Bu amaçla LD_LIBRARY_PATH çevre değişkeni kullanılmakta veya dinamik bağlayıcıya, --library-path seçeneği ile, arama listesi açık bir şekilde geçirilebilmektedir.
Örnek uygulamamızı rpath kullanmaksızın yeniden derleyip çalıştıralım.
Beklediğimiz üzere, dinamik bağlayıcı kütüphane dosyasın bulamamakta. Bu durumda LD_LIBRARY_PATH çevre değişkenini kullanabiliriz.
Diğer bir alternatif ise dinamik bağlayıcı uygun şekilde direkt olarak çağırmak şeklinde olabilir.
/etc/ld.so.conf ve /etc/ld.so.cache Dosyaları
Paylaşımlı kütüphaneler bir çok farklı dizinde bulunabilmektedir, tüm bu dizinlerin yükleme zamanında dinamik bağlayıcı tarafından aranması oldukça maliyetli olacaktır. Bu yüzden /etc/ld.so.conf ve /etc/ld.so.cache dosyası kullanılmaktadır.
/etc/ld.so.conf dosyasının içeriği aşağıdaki gibidir.
/etc/ld.so.conf.d/ dizininde ise sonu .conf ile biten, dizin yolu gösteren, dosyalar bulunmaktadır. Bu dizindeki dosyalardan birinin içeriği aşağıdaki gibidir.
/etc/ld.so.conf dosyası üzerinden bir çok .conf dosyasına ulaşılmaktadır. Kendimiz de buraya .conf uzantılı başka dosya isimleri ekleyebiliriz. ldconfig uygulaması ile tüm bu .conf dosyalarının içerdiği dizinler, ardından /lib ve /usr/lib dizinleri dolaşılarak /etc/ld.so.cache dosyası oluşturulmakta veya güncellenmektedir. /etc/ld.so.cache içinde kütüphane isimleri ve yol ifadeleri bulunmaktadır. Bu dosya bir yazı dosyası olmadığından içeriğine ldconfig -p şeklinde bakabiliriz. Sistemimizde, cache dosyasındaki ilk kayıtlar aşağıdaki gibidir.
Dinamik bağlayıcı bu cache dosyasına bakarak aradığı kütüphanelere hızlı bir şekilde ulaşabilmektedir.
Kütüphanelerin Aranma Sırası
Dinamik bağlayıcı kütüphaneleri belli bir sıraya göre aramaktadır. Öncelik sıralaması aşağıdaki gibidir.
1.
Bağımlılık listesinde "/" karakteri varsa kütüphane ismiyle beraber yol ifadesinin de geçirildiği kabul edilir ve arama bu dizinde yapılır. Yol ifadesi mutlak veya göreli olabilir.
2.
Dosya DT_RUNPATH listesi içermiyorsa DT_RPATH alanındaki liste aranır. Her iki alanında arama listesi içermesi ilk bakışta anlamsız gelebilir fakat DT_RUNPATH öncesi bağlayıcıların da çalışabilmesi için statik bağlayıcılar DT_RPATH alanına da DT_RUNPATH bilgilerini kopyalabilmektedirler. Bu durumda eski bağlayıcılar yalnız DT_RPATH içeriğine bakarken, yeni bağlayıcılar DT_RUNPATH bir liste içeriyorsa bu aşamada ELF dosya içindeki arama dizinlerini gözardı eder.
3.
LD_LIBRARY_PATH çevre değikenin değerine bakılır.
4.
DT_RUNPATH listesine bakılır. DT_RUNPATH alanının eklenme nedeni, ELF içindeki arama dizinlerine LD_LIBRARY_PATH değişkeninden sonra bakılmak istenmesidir.
5.
/etc/ld.so.cache dosyasına bakılır.
6.
/lib ve /usr/lib dizinlerine bakılır.
Last updated
Was this helpful?