ELF 1.2 specifications описывает объекты, которые находятся в определенном смещении в файле, который часто обозначается как p_offset
, и который будет загружен по определенному адресу в памяти (часто обозначается как p_vaddr
).
В спецификации не указано никакого выравнивания сегмента напрямую.
Однако это требует, чтобы
сегменты процесса загружаемых должны иметь совпадающие значения для p_vaddr
и p_offset
, по модулю размера страницы.
Этот член [p_align
] дает значение, в котором сегменты выровнены в памяти и в файле.
Значения 0 и 1 означают, что настройка не требуется. В противном случае p_align
должен быть положительной интегральной мощностью 2, а p_addr
должен равняться p_offset
, по модулю p_align
.
Терминология немного по-моему (сегменты не выровнены в обычном смысле, они не начинаются с кратного p_align
).
Обоснование цитаты заключается в том, что система должна иметь возможность быстро загружать сегмент, поэтому необходимо избегать смещения его в памяти в соответствии с его загрузочным адресом.
Файл при загрузке выполнен из одного или «единицы измерения» памяти, называемых страницами.
Страницы имеют фиксированный размер, поэтому все они начинаются с адреса, кратного их размеру.
Для 32-битной системы x86, этот размера по 4Kb, представьте то последовательность страниц и их исходные адреса:
Page 0 Page 1 Page 2 ... Page 4 ... Page 100 ... Page K
0 4096 8192 16384 409600 K*4096
Дело в том, что можно изменить адрес страницы очень быстро, без копирования любой байт, это называется переназначение.
После загрузки файла ОС переназначает страницу файла так, чтобы каждый сегмент был указан по адресу, указанному в p_vaddr
.
Теперь, если начало сегмента в файле не удовлетворяют условия, указанные в цитате и p_align
не кратны по 4Kb, этот «трюк» не будет работать, и ОС должна вернуться к смещению сегмента после загрузки.
Чтобы сделать вещи проще и не тратьте память, сегменты обычно выравниваются с размером 4KiB в файле.
Это не требуется, но часто является выравниванием раздела по умолчанию для 32-битного кода. –