2012-04-11 10 views
1

Возможно ли предоставить доступ к исполняемым страницам Linux для сохранения пространства? Я знаю, что есть общие API-интерфейсы, которые могут использоваться для обмена памятью между различными процессами, но я не думаю, что это предназначено для этого.Совместное использование страниц исполняемой памяти в Linux?

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

Возможно ли это на ядре Linux? Ядро Дарвина реализует это с использованием функции Mach VM, известной как , commpages (там хранится dyld общий кэш). Составы доступны и распределяются между каждым процессом.

Чтобы уточнить, я знаю, какие общие объекты (библиотеки) есть. В настоящее время, что делает динамический компоновщик в Linux, он загружает все необходимые библиотеки в адресное пространство программы, а это означает, что каждое приложение, которое ссылается на libc (например), будет иметь изображение libc где-то в своем адресном пространстве. В Darwin эта проблема может быть устранена путем использования разделов libc (и других разделов только для чтения) на наборе разделяемых страниц памяти. Записываемые разделы общих изображений по-прежнему разделены.

Редактировать: Я знаю, что формат ELF не поддерживает разделение сегментов DATA и TEXT разделяемых библиотек. Я не использую ELF, Я использую другой двоичный формат (с моим собственным модулем ядра binfmt и моим собственным динамическим компоновщиком). Мне интересно, поддерживает ли ядро ​​Linux функцию, похожую на страницу.

Редактировать 2: Единственный способ, которым я могу придумать это, - выделить большую ячейку памяти в ядре и отобразить ее в каждый исполняемый файл. В первый раз, когда выполняется любой двоичный файл, динамический компоновщик может снять защиту, заполнить его нужными данными и защитить его. Затем каким-то образом ядро ​​должно было бы убедиться, что сегмент памяти не модифицирован ничем другим, поскольку он откроет массивное отверстие безопасности. Другой

ответ

4

Как сказал гейкозавр, Linux уже делает это.

При запуске приложения динамический компоновщик (ld.so) mmap() s разделяемые библиотеки. Он выполняет несколько вызовов mmap() для каждой библиотеки:

  • mmap(PROT_READ|PROT_EXEC) для исполняемой секции (т.е. .text)
  • mmap(PROT_READ|PROT_WRITE) для данных (т.е. .data и .bss)

(Вы можете проверить это самостоятельно, используя strace.)

Ядро, являющееся умным небольшим количеством кода, понимает, что исполняемый раздел, идентифицированный смещением и inode (известный через fd), уже отображается. Поскольку он доступен только для чтения, нет смысла выделять для него больше памяти.

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

+0

Ответ Кристофа, как правило, замалчивается при обсуждении связывания и загрузки. Существует два понятия совместного использования: обращение к одному и тому же объекту кода (в файле) и доступ к одной и той же странице (кода) в физической памяти. Функция mmap() ядра понимает последнее, и ссылка только понимает ее достаточно, чтобы это произошло. Даже два процесса, выполняющие одну и ту же статически связанную программу, могут совместно использовать физические кодовые страницы, последнее понятие. – bootchk

4

Linux уже делает это; на самом деле, вот что поделился объект около/для.

+0

Общие объекты дублируются в адресное пространство каждого приложения. –

+0

Они * отображаются * в каждое адресное пространство приложений, но они только физически присутствуют в памяти один раз. –

+0

Какую часть ld-linux делает? –

Смежные вопросы