2012-02-06 7 views
4
nm -D /lib32/libc.so.6 | grep '\<fopen\>' 
0005d0c0 T fopen 
00109750 T fopen 

readelf -s /lib32/libc.so.6 | egrep '0005d0c0|00109750' 
181: 0005d0c0 50 FUNC GLOBAL DEFAULT 12 [email protected]@GLIBC_2.1 
182: 00109750 136 FUNC GLOBAL DEFAULT 12 [email protected]_2.0 
679: 0005d0c0 50 FUNC GLOBAL DEFAULT 12 [email protected]@GLIBC_2.1 
680: 00109750 136 FUNC GLOBAL DEFAULT 12 [email protected]_2.0 

вот мой вопрос:Почему у /lib32/libc.so.6 есть два символа «fopen»?

  1. почему /lib32/libc.so.6 имеет два Еореп символа в нем? идентичный символ в том же файле цели должен быть запрещен, правильно?

  2. Почему readelf -s выгружает fopen @@ GLIBC_2.1 и [email protected]_2.0 вместо fopen?

Благодаря

ответ

3

На самом деле несколько определений одного и того же символа отлично, и может произойти в ряде способов. Один из них (что здесь не так) - слабые символы.

Что происходит, так это то, что динамический компоновщик glibc поддерживает управление версиями символов, а glibc использует это. Он экспортирует версию fopen из glibc 2.1 и обратно совместимую версию от glibc 2.0 с разностными интерфейсами.

При динамическом времени соединения приложение может выбрать определенную версию или по умолчанию.

+0

Благодарю gby, не могли бы вы привести пример этого, спасибо :) – camino

+1

Лучший ресурс на планете за что-либо относительно общей библиотеки - это «Как писать общие библиотеки» Ульриха Дреппера: http://people.redhat.com/ drepper/dsohowto.pdf – gby

+0

Спасибо большое! :) – camino

9

Чтобы понять, что здесь происходит, сначала вам нужно понять, как традиционно обрабатывается двоичная совместимость.

Механизм использовался для «внешнего управления версиями». Вы начали с libfoo.so.1, и когда вам нужно было изменить ABI существующей функции, вам пришлось ввести libfoo.so.2.

Приложения, которые были связаны, прежде libfoo.so.2 продолжали использовать libfoo.so.1 со старым ABI, и новые мки используемых libfoo.so.2 с новым ABI.

Все это подробно описано here.

Но тогда glibc представил extension, где вместо введения целой новой библиотеки (которая разделяет 99% кода с предыдущим verson) вы вводите новый символ в существующую библиотеку.

Это расширение позволяет libc.so.6 оставаться в версии 6 для лет, позволяя старым двоичным файлам работать, а также для развития ABI.

В частном случае fopen, несовместимыми изменение struct FILE было сделано в версии 2.1 Glibc. Бинарники, которые были связаны с системами glibc-2.0, продолжают использовать старый struct FILE (единственный доступный тогда) и продолжают звонить _IO_old_fopen (для которых [email protected]_2.0 является псевдонимом). Бинарники, связанные с glibc-2.1 и new, используют новый struct FILE и звоните _IO_new_fopen (для которых [email protected]_2.1 - это псевдоним).

@@ - всего лишь обозначение, показывающее текущий по умолчанию символ версия.