2011-07-08 9 views
19

Her şeyden önce, bunu teknik bir bakış açısıyla soruyorum, kütüphane kodu kullanıcısı açısından değil. Bir farkın örneği, paylaşılan nesnelerin program üstbilgileri ve sıradan nesne dosyaları içermemesidir. Diğer farklılıklar neler?ELF nesne dosyası ile paylaşılan nesne arasındaki ELF başlık farkları nelerdir?

Sorunun amacına göre, linker'ı sıradan bir nesne dosyası olarak ele almak ve yeniden konumlandırmak ve statik bağlantı kurmak için paylaşılan bir nesne dosyasından hangi içeriğin kaldırılması gerektiğini anlamaya çalışıyorum. Paylaşılan bir kütüphane olarak tanımlamak ve DT_NEEDED referansı oluşturmak yerine oluşturulan yürütülebilir dosyaya. Bu da, paylaşılan bir kütüphanenin statik olarak bağlanabilir bir şeyle ilkelleştirilmesi için ilk adımdır (daha sonra yeniden yerleştirmelerin tatmin edici olabilmesi için daha fazla çalışmaya gerek olabilir).

+0

Sorunuzun bir cevabı değil, 'lr '' ld' için yararlı bir seçenek olabilirsiniz. – bdonlan

+0

Tam olarak aradığınız şey tam olarak değilse, en azından yardımcı olabilir: http: // statifier. http://libraryopt.sourceforge.net/ (paylaşılan bir kütüphaneyi parçalara ayırır, gereksiz sembolleri kaldırır ve yeniden oluşturur) sourceforge.net/ (http://libraryopt.sourceforge.net/). – technosaurus

+0

Fikirler için teşekkürler, ancak statifier ile iyi bir sonuç elde edemedim ve paylaşılan bir kütüphaneyi tek bir dosyaya dönüştürmek için mekanik bir dönüşüm (orta derecede ağrılı ve standart olmayan yük bölümleri olan bazı garip kütüphanelerde başarısız olsa da) gerektiğini anladım. Statik bağlantı için yeniden yüklenebilir '.o' dosyası. –

cevap

11

Bulmanız gereken en önemli farklardan biri, son bağlantı aşamasında, C kütüphanesi bileşenlerinin statik olarak kütüphaneye bağlanması ve INIT ve FINI sembollerinin diğer şeyler arasında oluşturulmasıdır. Bunlar, program başlığında DT_INIT vegirişleriyle belirtilir; Bunları statik yapıcı/yıkıcı girişlerine dönüştürmeniz gerekecektir. DT_NEEDED girişleri, bir .o; bunları manuel olarak tekrar eklemeniz gerekecektir. Son bağlantı aşamasında oluşturulan PLT'nin, nihai çıktı dosyasıyla birleştirilmesi veya normal yer değiştirmelere dönüştürülmesi gerekmektedir; PLT sadece kod olduğundan, bu önemsizdir. GOT da bir sorun; .text segmentinden sabit bir göreceli ofsetde bulunur ve veri üyelerine işaretçiler içerir. Bununla birlikte, bununla birlikte, her kitaplık veya yürütülebilir dosya için yalnızca bir tane olabilir olan _DYNAMIC yapısına bir işaretçi içerir. Ve GOT'ta ofsetleri değiştiremezsiniz çünkü doğrudan koddan başvurulurlar.

Bir .so'yu yeniden .o'ya dönüştürmek oldukça zor; PLT/GOT’lara dönüşümde bilgi kayboldu. Daha iyi bir yaklaşım, C kütüphanesindeki dinamik bağlayıcıyı, zaten bellekte eşlenmiş olan bir paylaşılan kütüphaneyi statik bir görüntü olarak bağlamak için değiştirmek olabilir. Diğer bir deyişle, sadece bir sayfa hizalanmış salt okunur bölümüne dönüştürerek. daha sonra, uygun izinlerle yeniden eşleştirmek ve normal paylaşımlı kütüphane başlatma işlemini gerçekleştirmek için bunu dinamik bağlayıcıya iletin. Ardından, paylaşılan kitaplığı başlatmak için C kitaplığına çağrı yapmak üzere statik bir kurucu ekleyin. Son olarak, paylaşılan kütüphanenin .text segmentindeki dinamik sembollere karşılık gelen uygun dışa aktarılmış sembolleri ekleyin.

Bu yaklaşımla ilgili bir sorun, statik yapıcıların sahte kurucunuzu ilklendiren statik yapıcıdan önce çalışabilmesidir. Bu durumda, solibin işlevlerini çağırmaya çalışmamalılar ya da solib'in henüz başlatılmadığı için muhtemelen çökeceksiniz. Bu, ihraç edilen sembollerin, solibin ilk olarak (başlangıçta veri sembolleri ile o kadar kolay değil) ilk başta başlatılmasını sağlayan bir trambolin fonksiyonuna işaret ederek potansiyel olarak önlenebilir.

Ayrıca, bazı kullanımlarınızda this previous question .

+3

Ancak en önemlisi, (Elf_Ehdr.e_type) türünün de değişmesi gerekiyor. (EXEC/DYN - REL) –

İlgili konular