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çerenobjcopy --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 öncenm
aracını bar.so üzerinde çalıştırırsam, söz konusu sembollerin tümününT
bayrağına (büyük harfle global) sahip olduğunu veobjcopy
'dan sonra artık yerel olduklarını belirten birt
olduğunu unutmayın. Yani benobjcopy
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
- Bir paylaşılan nesne benim eklentinin tüm tutmayı tercih ediyorum (bar.so). Ben
RTLD_DEEPBIND
bayrakla eklentinizi yüklemek için
Belki de yanlış anladım, ancak eklentimi yükleyen foo'nun kaynak koduna erişimim yoksa bunu nasıl yapabilirim, bar.so? – brady
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. –