Когда сегменты памяти созданы, им дают разрешения - чтение, запись и выполнение - или rwx
для краткости. В выводе, который вы видите, указан адрес виртуальной памяти сегмента, а также размер этого сегмента, разрешения этого сегмента и имя (если доступно) файла, используемого для заполнения сегмента. Это довольно стандартные результаты чего-то вроде команды mmap
, которая часто используется за кулисами загрузчиком для помощи в загрузке библиотек. Именно так интерпретируется формат вашего вывода.
Сколько сегментов памяти загружается? Кажется, что каждый из включенных вами файлов имеет read
/ execute
section (очень часто для разделов кода, таких как .text
), раздел readonly
(общий для разделов только для чтения, таких как .rodata
), и раздел read
/ write
(общий для разделов глобальных данных, таких как .data
. По причинам, обычно связанным с безопасностью и стандартизацией, эти части файла загружаются в сегменты с различными разрешениями. Например, вы, как правило, не хотите, чтобы инструкции вашей программы были доступны для записи (в противном случае произвольная уязвимость записи в память могла быпозволить злоумышленникам написать свои собственные инструкции в вашем адресном пространстве).
Что происходит, когда одна и та же библиотека вызывается дважды, как в моей команде? Короче говоря, не беспокойтесь о нескольких сегментахсоздается для отдельного файла. Файл загружается не более одного раза. Скорее, части файлафайлы загружаются на основе их разрешений. Это потому, что все функции, которые я упомянул выше.
Если вы хотите немного лучше понять формат файла ELF и посмотреть, как загрузчик знает, как создавать сегменты памяти, попробуйте использовать утилиту readelf
на вашем компьютере. cat++
программа. Заголовки программы покажут вам количество сегментов, разделы в каждом сегменте и разрешения каждого сегмента (и многое другое). Попробуйте readelf -l cat++
и убедитесь сами.