Какова основная причина использования таблиц PLT & GOT для разделяемых библиотек? - PullRequest
1 голос
/ 08 марта 2020

Я читаю эссе Иана Лэнса Тейлора о компоновщиках: http://inai.de/documents/Linkers.pdf

При обсуждении общих объектов на странице 9 он упоминает, что поскольку общие библиотеки можно загружать в процесс в непредсказуемый виртуальный адрес, динамический компоновщик c должен будет обрабатывать большое количество перемещений после того, как адрес известен. Это замедлит загрузку. Чтобы избежать такого большого количества перемещений, выполняемых компоновщиком Dynami c, компоновщик программы преобразует ссылки на функции в P C -относительные вызовы в таблицу PLT, а глобальные / stati c ссылки на переменные превращаются в ссылки в таблицу GOT. Тогда динамическому компоновщику c нужно только переместить записи в PLT / GOT во время загрузки, а не обрабатывать перемещения во всем двоичном файле.

Однако этот фокус на оптимизации времени загрузки сбивает меня с толку, потому что здесь, кажется, гораздо более очевидная проблема, и ускорение загрузки не имеет значения. Весь смысл общих объектов состоит в том, что один общий объект, загруженный в физическую память, теперь может быть отображен в виртуальное адресное пространство каждого процесса, который в этом нуждается. Это можно сделать быстро, изменив некоторые таблицы страниц и избегая загрузки новой копии библиотеки с диска.

Так что, если динамический c компоновщик сделал какие-либо перемещения в основной части общей библиотеки, они Изменения будут появляться в любом другом процессе, который также сопоставляет эту совместно используемую библиотеку, и они разрушат библиотеку, если она появится по другому виртуальному адресу.

И по этой причине у нас есть GOT и PLT. Линкер программы преобразует все ссылки в независимые от позиции ссылки в GOT и PLT. И тогда динамический компоновщик c перемещает записи в GOT и PLT уникально для каждого процесса. Основное содержимое общей библиотеки совместно используется каждым процессом, но GOT и PLT уникальны для каждого процесса и не являются общими.

Правильно ли это понимание PLT и GOT? Я сделал вывод о некоторых механизмах, основанных на моем понимании, но я не вижу другого способа, которым он мог бы работать.

1 Ответ

0 голосов
/ 09 марта 2020

Вы, похоже, отсутствует или не понимаете концепцию копирование при записи (CoW) страниц.

Два процесса могут mmap один и тот же файл на диске в их отдельных виртуальные адреса, и ОС может использовать одну физическую страницу ОЗУ для обоих отображений (то есть процессы совместно используют одну страницу физической памяти). Но как только один процесс изменяет память, для этого процесса создается копия, и изменения не появляются в другом процессе (страницы физической памяти больше не используются).

Так что, если динамический c компоновщик сделал какие-либо перемещения в основной части разделяемой библиотеки, эти изменения будут появляться в любом другом процессе, которому также сопоставлена ​​эта разделяемая библиотека,

Не если память CoW.

И по этой причине у нас есть GOT и PLT

Нет, причина в оптимизации (гораздо меньше страниц должно быть скопировано), а не правильность , как подразумевает ваше (неправильное) понимание.

...