Linux, GNU GCC, ld, sürüm komut dosyaları ve ELF ikili biçimi - Nasıl çalışır?


13

Linux'ta kütüphane sürümlemesi ve bunların nasıl işe yarayacağı hakkında daha fazla bilgi edinmeye çalışıyorum. Bağlam şöyledir:

- Dinamik bir kütüphanenin aynı arayüz setini ortaya koyan iki versiyonum var, diyelim libsome1.sove libsome2.so.

- Bir uygulamaya bağlı libsome1.so.

- Bu uygulama, libdl.sodinamik olarak başka bir modül yüklemek için kullanır diyelim libmagic.so.

- Şimdi libmagic.sobağlandı libsome2.so. Açıkçası, sembolleri gizlemek için bağlayıcı komut dosyaları kullanılmadan libmagic.so, çalışma zamanında içindeki arabirimlere yapılan tüm çağrılar libsome2.soçözülür libsome1.so. Bu, döndürülen libVersion()değeri makronun değerine göre kontrol ederek onaylanabilir LIB_VERSION.

- Bu yüzden derlemek ve libmagic.sotanımlanmış libmagic.sove onun tarafından ihraç 3 dışında tüm sembolleri gizleyen bir linker komut dosyası ile bağlantı deneyin . Bu eserler ... Veya en azından libVersion()ve LIB_VERSIONdeğerler maç (ve sürüm 2 değil 1 bildiriyor).

- Ancak, bazı veri yapıları diske serileştirildiğinde, bazı bozulmalar olduğunu fark ettim. Uygulamanın dizininde, silmek libsome1.sove yerine işaret etmek için yumuşak bir bağlantı oluşturursam libsome2.so, her şey beklendiği gibi çalışır ve aynı bozulma gerçekleşmez.

Yardım edemiyorum ama bunun çalışma zamanı bağlayıcısının sembollerin çözünürlüğündeki bazı çatışmalardan kaynaklanabileceğini düşünüyorum. Ben libsome2.so, tüm semboller symbol@@VER_2(böylece hala nm -CD libsome2.sohala semboller listelemek symbolve listelemek değil çünkü hakkında hala kafam karıştı) için bağlanmış olmaya çalışıyorum gibi birçok şey denedim symbol@@VER_2... Hiçbir şey çalışmıyor gibi görünüyor !!! Yardım!!!!!!


Son yaklaşımınız benim başlayacağım yaklaşımdır. Ve yolsuzluğun muhtemelen bazı sembol karışıklıkları olduğuna katılıyorum. Ne yazık ki sana bir cevabım yok.
RobotHumans

bu SO üzerinde daha iyi olabilir, tbh emin söylemek için yeterince anlamıyorum. taşımamızı isterseniz işaretleyin.
xenoterracide

1
Deneyin RTLD_LOCALve RTLD_DEEPBINDUygulamada Dlopen bayrakları. Bunu şimdi test etmek için zamanım yok ama manpage temelinde çalışmalı.
stribika

Yanıtlar:


13

Bu tam olarak sorunuza cevap vermiyor, ama ...

Her şeyden önce, ELF, Linux tarafından yürütülebilir dosyalar (programlar), paylaşılan kütüphaneler ve ayrıca yazılım derlenirken bulunan ara dosyalar olan nesne dosyaları için kullanılan özelliktir. Nesne dosyaları .o ile biter, paylaşılan kütüphaneler .so ile biter ve noktalarla ayrılmış sıfır veya daha fazla basamak gelir ve yürütülebilir dosyalar normalde herhangi bir uzantıya sahip değildir.

Paylaşılan kitaplığı adlandırmak için genellikle üç form vardır, ilk form .so ile biter. Örneğin, readline adlı bir kütüphane libreadline.so adlı bir dosyada saklanır ve normalde / lib, / usr / lib veya / usr / local / lib dosyalarından birinin altında bulunur. Bu dosya, -lreadline gibi bir seçenekle yazılım derlenirken bulunur. -l derleyiciye aşağıdaki kitaplıkla bağlantı kurmasını söyler. Kütüphaneler zaman zaman değiştiği için, eskimiş hale gelebilir, böylece kütüphaneler SONAME olarak adlandırılan bir şey gömerler. Readline için SONAME, libreadline'ın ikinci sürümü için libreadline.so.2 gibi görünebilir. Uyumlu ve yazılımın yeniden derlenmesini gerektirmeyen pek çok küçük readline sürümü de olabilir. Readline'ın küçük bir sürümü libreadline.so.2.14 olarak adlandırılabilir. Normalde serbest bırakılır. bu nedenle, readline'ın en son ana sürümü olan libreadline.so.2'nin bu durumda sembolik bir bağlantısıdır. libreadline.so.2 ayrıca aslında kullanılan dosya olan libreadline.so.2.14'e sembolik bir bağlantıdır.

Bir kitaplığın SONAME öğesi kitaplık dosyasının içine gömülüdür. Libreadline.so.2.14 dosyasının içinde bir yerde libreadline.so.2 dizesi bulunur. Bir program derlendiğinde ve readline ile bağlantılı olduğunda, libreadline.so dosyasını arayacak ve içine gömülü SONAME'i okuyacaktır. Daha sonra, program gerçekten yürütüldüğünde, sadece libreadline.so değil, libreadline.so.2'yi yükler, çünkü ilk bağlandığında okunan SONAME idi. Bu, bir sistemde birden fazla uyumsuz readline sürümünün yüklü olmasına izin verir ve her program bağlandığı uygun ana sürümü yükler. Ayrıca, readline'ı 2.17'ye yükseltirken, sadece mevcut kütüphanenin yanına libreadline.so.2.17 yükleyebilirim ve libreadline.so.2 sembolik bağlantısını libreadline.so.2.13'ten libreadline.so.2.17'ye taşıdığımda,

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.