为什么程序头是可执行的?

发布于 2024-11-11 16:52:19 字数 237 浏览 3 评论 0原文

我在我的 Linux 机器上的几个二进制文件上使用了 readelf,并在程序头中看到了令我惊讶的东西。该示例来自“ld”实用程序,但它也会出现在我使用 gcc 编译的任何内容中。

PHDR 0x000034 0x08048034 0x08048034 0x00120 0x00120 RE 0x4

该段跨越整个程序头。为什么被标记为可执行?它不包含机器代码。而且,为什么这会出现在标题中?我真的不希望它出现在我的程序图像中。

I used readelf on several binaries on my linux box and saw something that surprised me in the program headers. This eample is from the 'ld' utility, but it also occurs with anything I compile with gcc.

PHDR 0x000034 0x08048034 0x08048034 0x00120 0x00120 R E 0x4

This segment spans the entirety of the program headers. Why is is marked as executable? It doesn't contain machine code. But also, why is even this present in the headers? I don't really want it in my program image.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

过期情话 2024-11-18 16:52:19

指向 PHDR 的 PHDR 告诉加载器 PHDR 本身应该映射到进程地址空间,以便程序本身可以访问它们。

这主要用于动态链接。

内存被标记为可执行的原因是因为 PHDR 小于一页,并且位于可执行代码开头的旁边。如果 PHDR 的权限与程序文本的权限不同,则链接器必须在它们之间插入填充。

The PHDR pointing to the PHDRs tells the loader that the PHDRs themselves should be mapped to the process address space, in order to make them accessible to the program itself.

This is useful mainly for dynamic linking.

The reason the memory is marked as executable is because the PHDRs are smaller than one page, and live right next to the start of the executable code. If the permissions for the PHDRs were different from those of the program text, the linker would have to insert padding between them.

樱&纷飞 2024-11-18 16:52:19

主要的文件 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;

这取自此处

The main File ELF headers are there to easily find the offset in the file where other sections are stored. Then each subheader describes the data in it's section.

Main ELF header looks like this:

/* 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;

The program header(s) are there because they describe the executable parts of the ELF executable.

The next portion of the program are
the ELF program headers. These
describe the sections of the program
that contain executable program code
to get mapped into the program address
space as it loads.

/* 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;

This is taken from here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文