MVV

|
Posted: Wed Mar 24, 2010 08:58 Post subject: |
|
|
CaptainFlint wrote: | MVV wrote: | Ну подумай сам. Код модуля загружается в память, и все ее копии пользуют его как общий (по логике, второй и далее разы даже читать секцию кода из файла не надо, раз она уже есть в памяти). Но если одна из них загружается по отличному от базового адреса, система ее загрузит и внесет корректировки в ее код, т.е. он уже будет отличаться от кода тех копий, которые загружены по базовому адресу - как минимум, все инструкции call и jmp (кроме вызовов системных функций) будут содержать другие адреса (если быть точным, будет исправлен адрес в каждом месте, указанном в секции релокаций). |
Не понял, если библиотека уже загружена в память по некоторому адресу, нафига ж тогда её ещё раз грузить по другому адресу? Что-то у тебя с ног на голову всё повёрнуто. Вот твоя аргументация в сокращённом виде (поправь, если не так понял): система грузит вторую копию DLL по новому адресу, меняет указатели, адреса становятся другими, нельзя переиспользовать код, следовательно, придётся держать несколько копий. Так ведь эта цепочка рассуждений начинается как раз того, что по какой-то причине грузится вторая копия по новому адресу! Какие тут ещё могут быть доводы и обоснования? Мы предположили, что загрузилась новая копия, и на основе этого доказали, что новая копия загрузится. |
Она еще не загружена, она еще только загружается. Система вынуждена грузить вторую копию модуля по новому адресу, при этом нужно менять указатели - адреса становятся другими, нельзя переиспользовать код, следовательно, придётся держать несколько копий.
Хорошо, постараюсь объяснить подробнее.
У всех копий одной и той же библиотеки, загруженных в разные процессы по одинаковым базовым адресам (например, по рекомендуемому), секции кода ссылаются на общий участок физической памяти (т.к. их код идентичен).
Но если системе нужно подгрузить библиотеку к некоторому процессу, и выясняется, что рекомендуемый базовый адрес уже занят, системе приходится загружать библиотеку по другому адресу в виртуальном адресном пространстве. Тут начинаются проблемы, так как код, прописанный в библиотеке, по другому адресу работать не способен (абсолютные адреса прописаны с учетом рекомендуемого базового адреса - например, базовый адрес 0x400000, и инструкция call 0x400300, но если базовый адрес 0x1000000, эта инструкция должна быть call 0x1000300), поэтому необходимо исправить каждый адрес в коде.
Поэтому система загружает секцию кода в отдельный участок физической памяти, с которым будет связана секция кода новой копии библиотеки, и в этом участке исправляет все адреса, указанные в таблице релокаций библиотеки, с учетом разницы старого и нового базовых адресов.
Т.е., имеем дополнительное потребление физической памяти и необходимость загрузки и коррекции кода с учетом изменившегося базового адреса - если при компоновке библиотеки выбрать адрес, который не используется другими модулями, подгружаемыми к конкретному процессу, такой проблемы просто не возникнет. _________________ TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel… |
|