В чем разница раздела и сегмента в формате файла ELF
из Вики исполняемый и связываемый формат:
сегменты содержат информацию, необходимую для выполнения файла во время выполнения, в то время как разделы содержат важные данные для связывания и перемещения. Любой байт во всем файле может принадлежать не более чем одной секции, и могут быть сиротские байты, которые не принадлежат ни одной секции.
а в чем разница между разделом и сегменте?
В исполняемом файле ELF выполняется сегмент содержит один или несколько разделов?
2 ответов:
а в чем разница между разделом и сегменте?
именно то, что вы процитировали: сегменты содержат информацию, необходимую во время выполнения, в то время как разделы содержат информацию, необходимую во время связывания.
содержит ли сегмент один или несколько разделов?
сегмент может содержать 0 или более секций. Пример:
readelf -l /bin/date Elf file type is EXEC (Executable file) Entry point 0x402000 There are 9 program headers, starting at offset 64 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040 0x00000000000001f8 0x00000000000001f8 R E 8 INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238 0x000000000000001c 0x000000000000001c R 1 [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 0x000000000000d5ac 0x000000000000d5ac R E 200000 LOAD 0x000000000000de10 0x000000000060de10 0x000000000060de10 0x0000000000000440 0x0000000000000610 RW 200000 DYNAMIC 0x000000000000de38 0x000000000060de38 0x000000000060de38 0x00000000000001a0 0x00000000000001a0 RW 8 NOTE 0x0000000000000254 0x0000000000400254 0x0000000000400254 0x0000000000000044 0x0000000000000044 R 4 GNU_EH_FRAME 0x000000000000c700 0x000000000040c700 0x000000000040c700 0x00000000000002a4 0x00000000000002a4 R 4 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 8 GNU_RELRO 0x000000000000de10 0x000000000060de10 0x000000000060de10 0x00000000000001f0 0x00000000000001f0 R 1 Section to Segment mapping: Segment Sections... 00 01 .interp 02 .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 03 .ctors .dtors .jcr .dynamic .got .got.plt .data .bss 04 .dynamic 05 .note.ABI-tag .note.gnu.build-id 06 .eh_frame_hdr 07 08 .ctors .dtors .jcr .dynamic .gotздесь
PHDRсегмент содержит 0 разделыINTERPсегмент содержит.interpраздел, и первыйLOADсегмент содержит целую кучу разделов.более дальнеишее чтение С хорошим иллюстрации.
раздел содержит статические для компоновщика, сегмент динамических данных для ОС
цитата верна, но чтобы действительно понять ее разницу, вы должны попытаться понять поля заголовка раздела и записи заголовка программы (сегмента), а также то, как они используются компоновщиком (секциями) и операционной системой (сегментом).
особо важная информация (кроме длины):
- : сообщите компоновщику, если раздел либо:
- необработанные данные для загрузки в память, например
.data,.textи т. д.- или форматированные метаданные о других разделах, которые будут использоваться компоновщиком, но исчезнут во время выполнения, например
.symtab,.srttab,.rela.textсегмент: операционная система:
- где сегмент должен быть загружен в виртуальную память
- какие разрешения сегменты есть (чтение, запись, выполнение). Помните, что это может быть эффективно применено процессором:как работает x86 подкачка?
я написал учебник, который охватывает это более подробно по адресу:http://www.cirosantilli.com/elf-hello-world/
содержит ли сегмент один или несколько разделов?
да, и это компоновщик, который помещает разделы в сегменты.
в Binutils, как секции помещаются в сегменты с помощью
ldопределяется текстовым файлом под названием A скрипт линкера. Документы: https://sourceware.org/binutils/docs/ld/Scripts.htmlвы можете получить значение по умолчанию с
ld --verbose, и установить пользовательский с-T.например, мой сценарий компоновщика Ubuntu 17.04 по умолчанию содержит:
.text : { *(.text.unlikely .text.*_unlikely .text.unlikely.*) *(.text.exit .text.exit.*) *(.text.startup .text.startup.*) *(.text.hot .text.hot.*) *(.text .stub .text.* .gnu.linkonce.t.*) }который говорит компоновщику поставить разделы с именем
.text.unlikely,.text.*_unlikely,.text.exitи т. д. в.textсегменте.разработка ОС-это случай, когда пользовательские скрипты полезны, минимальный пример: https://github.com/cirosantilli/x86-bare-metal-examples/blob/d217b180be4220a0b4a453f31275d38e697a99e0/linker.ld
после того, как исполняемый файл связан, можно только узнать, какой раздел пошел в какой сегмент, если компоновщик хранит необязательный заголовок раздела в исполняемом файле:где в разделе " сегментное отображение " хранится в файлах ELF?
Comments