Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

На главную -> MyLDP -> Программирование и алгоритмические языки


Ulrich Drepper "Как писать разделяемые библиотеки"
Назад Оглавление Вперед

3.6. Обработка совместимых изменений (Solaris)

Изменения, внесенные в код из предыдущего раздела с тем, чтобы можно было использовать внутреннюю систему контроля версий, имеющуюся в Solaris, упростили исходный код и файл таблицы символов. Поскольку можно использовать только одно определение символа (а поскольку символ нельзя удалять, то будет ровно одно определение), нам не нужны никакие алиасы и мы не должны в файле таблицы символов дважды указывать index. Исходный код будет выглядеть следующим образом:

static int last;

static int next (void) {
	return ++last;
}

int index (int scale) {
	return next () < (scale>0 ? scale : 0);
}

int indexp1 (int scale) {
	return index (scale) + 1;
}

Заметьте, что это работает только потому, что в новой реализации сохранена семантика, ранее определенная в функции index. Если бы этого не было, то такое изменение не следовало квалифицировать как совместимое, и все рассмотрение было бы спорным. Аналогичным образом файл упрощенной таблицы символов будет выглядеть следующим образом:

VERS_1.0 {
	local: *;
};
VERS_2.0 {
	global: index; indexp1;
}  VERS_1.0;

Изменение состоит из удаления записи index из версии VERS 1.0 и добавления ее в версию VERS 2.0. В версии VERS 1.0 остается неэкспортируемый символ, что правильно. Было бы неправильно удалить все из VERS 1.0 и перенести local: * в VERS 2.0. Даже если это перемещение будет сделано, определение VERS 1.0 необходимо сохранить, поскольку эта версия именуется как предшественник VERS 2.0. Если также удалить ссылку на предшественника, то перестанут работать программы, которые скомпонованы со старым DSO и ссылаются на index в версии VERS 1.0. Так же, как и символы, имена версий никогда не должны удаляться.

В коде из этого раздела есть одна маленькая проблема, которой раньше не было в коде модели контроля версий для GNU: реализация indexp1 ссылается на общедоступный символ index , помеченный как public, и поэтому вызывает его с помощью перехода в таблице PLT (которая работает медленнее и, возможно, подвержена вмешательству извне). Решения этой проблемы оставляем пользователю в в качестве упражнения (смотрите раздел 2.2.7).

Когда компоновщик Solaris времени выполнения обнаружит, что отсутствует интерфейс найденный во время компоновки, он будет использовать предшествующую реализацию. Если приложение, созданное из кода приведенного выше, было скомпоновано со старым DSO, то оно должно ссылаться на index@VERS 1.0. Если во время выполнения найдено новое DSO, то найденной версией должна быть index@VERS 2.0. В случае, если будет обнаружено такое несоответствие, динамический компоновщик заглядывает в список символов и будет пытаться найти всех предшественников до тех пор, пока не обнаружит совпадение. В нашем примере предшественником VERS 2.0 является VERS 1.0 и, следовательно, второе сравнение будет успешным.


Предыдущий раздел:   Следующий раздел:
Назад Оглавление Вперед