2011-05-31 11 views
7

Daha büyük bir programa (foo) bağlanan bir paylaşılan kitaplık (bar.so) biçiminde bir eklentim var. Hem foo hem de bar.so aynı üçüncü parti kütüphanesine (baz) bağımlıdırlar, fakat bunların baz uygulamalarını tamamen ayrı tutmaları gerekir. Bu yüzden foo'yu (verilen nesne dosyalarını ve arşivleri kullanarak) bağladığımda, bar.so'daki herhangi bir baz kullanımını göz ardı etmek için ona ihtiyacım var.Paylaşılan nesnedeki simgelere erişim kısıtlaması nasıl yapılır?

Şu anda baz_fun aşağıdaki çıktıyı almak kusurlu sembollerinden biridir nerede --trace-symbol=baz_fun Foo'ları bağlarsanız:

bar.so: definition of baz_fun 
foo/src.a(baz.o): reference to baz_fun 

bu o foo bar.so gelen baz_fun başvurduğunu söylüyor inanıyoruz (ve foo'nun yürütülmesi bunu onaylar). Ben denedim

Çözümleri:

  • ilgi sembolleri "yerelleştirerek" objcopy kullanarak: local.syms ilgi sembolleri içeren objcopy --localize-symbols=local.syms bar.so. Sanırım burada kafam karışabilir ve belki "yerel" demek istediğimi kasteder. Yine de, yukarıdaki çıktıdan aynı çıktıyı elde ediyorum. objcopy'u kullanmadan önce nm aracını bar.so üzerinde çalıştırırsam, söz konusu sembollerin tümünün T bayrağına (büyük harfle global) sahip olduğunu ve objcopy'dan sonra artık yerel olduklarını belirten bir t olduğunu unutmayın. Yani ben objcopy doğru kullanıyorum görünür.
  • -fvisibility=hidden ile derleme, bazı diğer kısıtlamalar nedeniyle bu özelliği destekliyor gibi görünmeyen GCC 3.3'ü kullanmam gerekir. GCC'nin daha yeni bir sürümüne geçebilirim, ancak bu bayrakla derlenmenin o yola gitmeden önce bana yardım edeceğine dair onay isterim.

Diğer şeyler nota: Ben foo veya Baz

  • ya kaynak koduna erişimi olmayan

    • Bir paylaşılan nesne benim eklentinin tüm tutmayı tercih ediyorum (bar.so). Ben RTLD_DEEPBIND bayrakla eklentinizi yüklemek için
  • cevap

    3

    Kullanım dlopen ayrılmış istemiyoruz bu yüzden baz aslında bir lisans kütüphanesidir.

    (düzenleme)

    RTLD_DEEPBIND Linux özgü olduğuna dikkat ve glibc 2.3.4 veya daha yeni ihtiyacım var.

    +0

    Belki de yanlış anladım, ancak eklentimi yükleyen foo'nun kaynak koduna erişimim yoksa bunu nasıl yapabilirim, bar.so? – brady

    +0

    Sadece çubuğu kontrol edip foo yapmıyorsanız, çubuğu iki kütüphanede, bar1 ve bar2'de bölebilirsiniz. bar1 eklenti arayüzünü sağlar ve tüm çağrıları bar2'ye yönlendirir ve bar 2 her şeyi uygular. bar1, dlopen ("libbar2.so", RTLD_NOW | RTLD_DEEPBIND) 've' dlsym 'gereksinimini duyduğu tüm işlevleri çağırmalıdır. Ya da bir bar ve dlopen ("libbaz.so", RTLD_NOW | RTLD_DEEPBIND) "ve" dlsym "gereksinim duyduğunuz tüm işlevleri tutabilirsiniz. Hangi yöntemin daha az çağrıya ihtiyaç duyduğunu "dlsym" olarak kullanın. –

    İlgili konular