Linux, GNU GCC, ld, skrip versi dan format biner ELF - Bagaimana cara kerjanya?

13

Saya mencoba mempelajari lebih lanjut tentang versi perpustakaan di Linux dan bagaimana menjalankannya. Inilah konteksnya:

- Saya punya dua versi perpustakaan dinamis yang mengekspos set antarmuka yang sama, katakan libsome1.sodan libsome2.so.

- Aplikasi terhubung dengan libsome1.so.

- Aplikasi ini digunakan libdl.sountuk memuat modul lain secara dinamis, katakanlah libmagic.so.

- Sekarang libmagic.soterhubung libsome2.so. Jelas, tanpa menggunakan skrip linker untuk menyembunyikan simbol libmagic.so, pada saat run-time semua panggilan ke antarmuka libsome2.sodiselesaikan libsome1.so. Ini dapat dikonfirmasi dengan memeriksa nilai yang dikembalikan oleh libVersion()terhadap nilai makro LIB_VERSION.

- Jadi saya coba selanjutnya mengkompilasi dan menghubungkan libmagic.sodengan skrip linker yang menyembunyikan semua simbol kecuali 3 yang didefinisikan libmagic.sodan diekspor olehnya. Ini berfungsi ... Atau setidaknya libVersion()dan LIB_VERSIONnilainya cocok (dan ini melaporkan versi 2 bukan 1).

- Namun, ketika beberapa struktur data serial ke disk, saya melihat beberapa korupsi. Dalam direktori aplikasi jika saya menghapus libsome1.sodan membuat tautan lunak di tempatnya untuk menunjuk libsome2.so, semuanya berfungsi seperti yang diharapkan dan korupsi yang sama tidak terjadi.

Saya tidak dapat membantu tetapi berpikir bahwa ini mungkin disebabkan oleh beberapa konflik dalam resolusi simbol run-time linker. Saya sudah mencoba banyak hal, seperti mencoba menautkan libsome2.sosemua simbol yang dinyalakan symbol@@VER_2(yang saya masih bingung karena perintah nm -CD libsome2.somasih mencantumkan simbol sebagai symboldan tidak symbol@@VER_2) ... Sepertinya tidak ada yang berhasil !!! Tolong!!!!!!

sinar matahari
sumber
Pendekatan terakhir Anda adalah yang akan saya mulai. Dan saya setuju bahwa korupsi mungkin beberapa simbol kebingungan. Sayangnya saya tidak punya jawaban untuk Anda.
RobotHumans
ini mungkin lebih baik pada SO, meskipun tbh saya tidak cukup mengerti untuk mengatakan dengan pasti. tandai jika Anda ingin kami memindahkannya.
xenoterracide
1
Coba RTLD_LOCALdan RTLD_DEEPBINDdlopen bendera di aplikasi Anda. Saya tidak punya waktu untuk menguji ini sekarang tetapi harus bekerja berdasarkan halaman manual.
stribika

Jawaban:

13

Ini tidak persis menjawab pertanyaan Anda, tetapi ...

Pertama-tama, ELF adalah spesifikasi yang digunakan oleh Linux untuk file yang dapat dieksekusi (program), shared library, dan juga file objek yang merupakan file perantara yang ditemukan ketika menyusun perangkat lunak. File objek berakhiran .o, pustaka bersama diakhiri dengan .so diikuti oleh nol atau lebih digit yang dipisahkan oleh titik, dan file yang dapat dieksekusi tidak memiliki ekstensi apa pun secara normal.

Biasanya ada tiga bentuk untuk menamai perpustakaan bersama, formulir pertama hanya berakhiran .so. Sebagai contoh, perpustakaan yang disebut readline disimpan dalam file yang disebut libreadline.so dan terletak di bawah salah satu dari / lib, / usr / lib, atau / usr / local / lib secara normal. File itu terletak ketika menyusun perangkat lunak dengan opsi seperti -lreadline. l memberitahu kompiler untuk menghubungkan dengan perpustakaan berikut. Karena perpustakaan berubah dari waktu ke waktu, itu mungkin menjadi usang sehingga perpustakaan menanamkan sesuatu yang disebut SONAME. SONAME untuk readline mungkin terlihat seperti libreadline.so.2 untuk libreadline versi utama versi kedua. Mungkin juga ada banyak versi kecil readline yang kompatibel dan tidak memerlukan perangkat lunak untuk dikompilasi ulang. Versi minor readline mungkin dinamai libreadline.so.2.14. Biasanya libreadline. jadi hanya tautan simbolis ke versi utama readline terbaru, libreadline.so.2 dalam kasus ini. libreadline.so.2 juga merupakan tautan simbolis ke libreadline.so.2.14 yang sebenarnya merupakan file yang digunakan.

SONAME pustaka tertanam di dalam file pustaka itu sendiri. Di suatu tempat di dalam file libreadline.so.2.14 adalah string libreadline.so.2. Ketika suatu program dikompilasi dan dihubungkan dengan readline, ia akan mencari file libreadline.so dan membaca SONAME yang tertanam di dalamnya. Kemudian, ketika program ini benar-benar dieksekusi, ia akan memuat libreadline.so.2, bukan hanya libreadline.so, karena itu adalah SONAME yang dibaca ketika pertama kali ditautkan. Ini memungkinkan suatu sistem untuk menginstal beberapa versi readline yang tidak kompatibel, dan setiap program akan memuat versi utama yang sesuai dengan tautannya. Juga, ketika memutakhirkan readline, katakanlah, ke 2.17, saya bisa menginstal libreadline.so.2.17 di samping perpustakaan yang ada, dan begitu saya memindahkan tautan simbolik libreadline.so.2 dari libreadline.so.2.13 ke libreadline.so.2.17,

penguin359
sumber