我在我的linux机器上的几个二进制文件上使用了readelf,并在程序头中看到了令我惊讶的东西。这个示例来自'ld'实用程序,但它也出现在我使用gcc编译的任何内容中。
PHDR 0x000034 0x08048034 0x08048034 0x00120 0x00120 R E 0x4
此段涵盖整个程序标头。为什么被标记为可执行文件?它不包含机器代码。但是,为什么甚至在标题中出现?我真的不希望它出现在我的程序图像中。
答案 0 :(得分:4)
指向PHDR的PHDR告诉加载程序PHDR本身应该映射到进程地址空间,以便程序本身可以访问它们。
这主要用于动态链接。
将内存标记为可执行文件的原因是因为PHDR小于一页,并且位于可执行代码的开头旁边。如果PHDR的权限与程序文本的权限不同,则链接器必须在它们之间插入填充。
答案 1 :(得分:0)
主文件ELF标题可以轻松找到存储其他部分的文件中的偏移量。然后每个子标题描述其中的数据。
主要ELF标题如下所示:
/* ELF File Header */
typedef struct
{
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
Elf32_Half e_type; /* Object file type */
Elf32_Half e_machine; /* Architecture */
Elf32_Word e_version; /* Object file version */
Elf32_Addr e_entry; /* Entry point virtual address */
Elf32_Off e_phoff; /* Program header table file offset */
Elf32_Off e_shoff; /* Section header table file offset */
Elf32_Word e_flags; /* Processor-specific flags */
Elf32_Half e_ehsize; /* ELF header size in bytes */
Elf32_Half e_phentsize; /* Program header table entry size */
Elf32_Half e_phnum; /* Program header table entry count */
Elf32_Half e_shentsize; /* Section header table entry size */
Elf32_Half e_shnum; /* Section header table entry count */
Elf32_Half e_shstrndx; /* Section header string table index */
} Elf32_Ehdr;
程序头是存在的,因为它们描述了ELF可执行文件的可执行部分。
该计划的下一部分是 ELF程序标题。这些 描述程序的各个部分 包含可执行程序代码 被映射到程序地址 空间,因为它加载。
/* Program segment header. */
typedef struct
{
Elf32_Word p_type; /* Segment type */
Elf32_Off p_offset; /* Segment file offset */
Elf32_Addr p_vaddr; /* Segment virtual address */
Elf32_Addr p_paddr; /* Segment physical address */
Elf32_Word p_filesz; /* Segment size in file */
Elf32_Word p_memsz; /* Segment size in memory */
Elf32_Word p_flags; /* Segment flags */
Elf32_Word p_align; /* Segment alignment */
} Elf32_Phdr;
这取自here