Linux, GNU GCC, ld, сценарії версій та двійковий формат ELF - Як це працює?


13

Я намагаюся дізнатися більше про версію бібліотеки в Linux і про те, як все це працювати. Ось контекст:

- У мене є дві версії динамічної бібліотеки, які розкривають один і той же набір інтерфейсів, скажімо, libsome1.soі libsome2.so.

- Програма пов’язана проти libsome1.so.

- libdl.soСкажімо, ця програма використовує для динамічного завантаження іншого модуля libmagic.so.

- Зараз libmagic.soпов’язаний проти libsome2.so. Очевидно, що без використання скриптів посилання для приховування символів у libmagic.so, під час виконання всі виклики до інтерфейсів libsome2.soвирішені libsome1.so. Це можна підтвердити, перевіривши повернене значення libVersion()проти значення макроса LIB_VERSION.

- Тому я намагаюся поруч компілювати та зв’язуватись libmagic.soіз скриптом посилання, який приховує всі символи, крім 3, які визначені у libmagic.soта експортуються ним. Це працює ... Або принаймні libVersion()і LIB_VERSIONзначення відповідають (і він повідомляє версію 2, а не 1).

- Однак, коли деякі структури даних серіалізуються на диск, я помітив деяку корупцію. У каталозі програми, якщо я видаляю libsome1.soі створюю на його місці м'яке посилання, на яке вказують libsome2.so, все працює як очікувалося, і така ж корупція не трапляється.

Я не можу не думати, що це може бути викликано певним конфліктом у роздільній здатності символів, які виконують час роботи. Я пробував багато речей, як, наприклад, намагаюся зв’язати libsome2.soтак, щоб усі символи були впорядковані symbol@@VER_2( до чого я все ще плутаю, оскільки команда nm -CD libsome2.soвсе ще перераховує символи як symbolі ні symbol@@VER_2) ... Ніщо, здається, не працює !!! Допоможіть !!!!!!


Ваш останній підхід - це той, з якого я б почав. І я згоден, що корупція - це, мабуть, якась символьна плутанина. На жаль, я не маю для вас відповіді.
RobotHumans

це може зробити краще на SO, хоча я не розумію цього достатньо, щоб сказати точно. позначте його, якщо ви хочете, щоб ми перемістили його.
ксенотеррацид

1
Спробуйте RTLD_LOCALі RTLD_DEEPBINDрозкрийте прапори у вашій програмі. Я не маю часу перевірити це зараз, але це має працювати на основі сторінки.
stribika

Відповіді:


13

Це точно не відповідає на ваше запитання, але ...

Перш за все, ELF - це використання специфікацій Linux для виконуваних файлів (програм), спільних бібліотек, а також об’єктних файлів, які є проміжними файлами, знайденими при компілюванні програмного забезпечення. Файли об’єктів закінчуються на .o, бібліотеки, що поділяються, закінчуються .so супроводжується нулем або більше цифр, розділених періодами, а виконувані файли зазвичай не мають розширення.

Зазвичай існує три форми для імені спільної бібліотеки, перша форма просто закінчується .so. Наприклад, бібліотека під назвою readline зберігається у файлі під назвою libreadline.so і розташовується під одним з / lib, / usr / lib або / usr / local / lib. Цей файл знаходиться при компілюванні програмного забезпечення з такою опцією, як -lreadline. -l повідомляє компілятору зв’язатись із наступною бібліотекою. Оскільки бібліотеки час від часу змінюються, вони можуть застарівати, тому бібліотеки вбудовують щось, що називається SONAME. SONAME для readline може виглядати як libreadline.so.2 для другої версії основної версії libreadline. Також може бути багато незначних версій readline, сумісних і не потребують перекомпіляції програмного забезпечення. Незначна версія рядка читання може бути названа libreadline.so.2.14. Зазвичай ліберальна лінія. тому це лише символічне посилання на останню основну версію readline, libreadline.so.2 в даному випадку. libreadline.so.2 також є символічним посиланням на libreadline.so.2.14, що є власне файлом, який використовується.

SONAME бібліотеки вбудований у сам файл бібліотеки. Десь усередині файла libreadline.so.2.14 є рядок libreadline.so.2. Коли програма компілюється та зв’язується з лінією читання, вона шукатиме файл libreadline.so та читатиме вбудований у неї SONAME. Пізніше, коли програма буде фактично виконана, вона завантажить libreadline.so.2, а не просто libreadline.so, оскільки це була SONAME, яку читали під час її першого посилання. Це дозволяє системі встановити кілька несумісних версій readline, і кожна програма завантажить відповідну основну версію, з якою вона була пов'язана. Також під час оновлення readline, скажімо, до 2.17, я можу просто встановити libreadline.so.2.17 поряд з існуючою бібліотекою, і як тільки я перейду символічне посилання libreadline.so.2 з libreadline.so.2.13 на libreadline.so.2.17,

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.