我试图了解ELF段是如何进行内存映射的。我注意到各个部分都映射到同一个ELF段。例如,.rodata映射到与.text。
相同的段为什么会这样?为什么不将.rodata映射到单独的只读且不可执行的段?
此外,将.text部分映射到"仅执行"它需要什么?细分(不可读)?是否存在可能阻碍此问题的内核/硬件限制?
编辑: 我可以补充一点,我正在使用GNU链接器,如果这有所不同。
答案 0 :(得分:7)
收集上述评论
在包括x86-64在内的多种计算机体系结构中,无法将内存标记为可执行但不可读。
虽然x86 16位和32位确实允许在传统模式中进行分段,并且理论上可以使用内存段将内存标记为仅可执行文件,但是平面地址空间的优势非常大,现在x86-64 { {3}}:
3.2.4 IA-32e模式中的分段
在Intel 64架构的IA-32e模式中,分段的影响取决于处理器是以兼容模式还是64位模式运行。在兼容模式下,分段的功能与使用传统的16位或32位保护模式语义一样。
在64位模式下,通常(但不是完全)禁用分段,从而创建平坦的64位线性地址空间。处理器将CS,DS,ES,SS的分段基数视为零,创建一个等于有效地址的线性地址。 FS和GS部分是例外。这些段寄存器(保存段基)可用作线性地址计算中的附加基址寄存器。它们有助于解决本地数据和某些操作系统数据结构。
请注意,处理器不会在运行时以64位模式执行段限制检查。
因此,内核只需将其段设置为覆盖整个地址空间,而不依赖于分段来实现内存保护。
他们使用的是页面表的属性。进程内存映射中存在的每个页面都有一个页表条目,用于控制对它的访问。可以看到它们的格式概述mostly ignores its segments registers,但最重要的是有两个位控制允许的访问类型:
无法使用这些标志指示可执行文件 - noread-nowrite组合。如果页面完全存在于内存映射中,则它必须是可读的。
英特尔最新的微体系结构Skylake正在迅速采用一种解决方案,将允许只执行内存:这是功能受洗的MPK(here),支持最近刚刚发布的Linux内核4.6。密钥占用页表条目的四位62:59,内存区域可以用表示执行noread-nowrite访问的键标记。
答案 1 :(得分:-1)
% objdump -h /bin/ls
/bin/ls: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 0000001c 0000000000400238 0000000000400238 00000238 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .note.ABI-tag 00000020 0000000000400254 0000000000400254 00000254 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .note.gnu.build-id 00000024 0000000000400274 0000000000400274 00000274 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .gnu.hash 000000c0 0000000000400298 0000000000400298 00000298 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .dynsym 00000cd8 0000000000400358 0000000000400358 00000358 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .dynstr 000005dc 0000000000401030 0000000000401030 00001030 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .gnu.version 00000112 000000000040160c 000000000040160c 0000160c 2**1
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .gnu.version_r 00000070 0000000000401720 0000000000401720 00001720 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .rela.dyn 000000a8 0000000000401790 0000000000401790 00001790 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .rela.plt 00000a98 0000000000401838 0000000000401838 00001838 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .init 0000001a 00000000004022d0 00000000004022d0 000022d0 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
11 .plt 00000720 00000000004022f0 00000000004022f0 000022f0 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .text 0001112a 0000000000402a10 0000000000402a10 00002a10 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .fini 00000009 0000000000413b3c 0000000000413b3c 00013b3c 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .rodata 00006754 0000000000413b80 0000000000413b80 00013b80 2**6
CONTENTS, ALLOC, LOAD, READONLY, DATA
15 .eh_frame_hdr 0000081c 000000000041a2d4 000000000041a2d4 0001a2d4 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
16 .eh_frame 00002c7c 000000000041aaf0 000000000041aaf0 0001aaf0 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
17 .init_array 00000008 000000000061de00 000000000061de00 0001de00 2**3
CONTENTS, ALLOC, LOAD, DATA
18 .fini_array 00000008 000000000061de08 000000000061de08 0001de08 2**3
CONTENTS, ALLOC, LOAD, DATA
19 .jcr 00000008 000000000061de10 000000000061de10 0001de10 2**3
CONTENTS, ALLOC, LOAD, DATA
20 .dynamic 000001e0 000000000061de18 000000000061de18 0001de18 2**3
CONTENTS, ALLOC, LOAD, DATA
21 .got 00000008 000000000061dff8 000000000061dff8 0001dff8 2**3
CONTENTS, ALLOC, LOAD, DATA
22 .got.plt 000003a0 000000000061e000 000000000061e000 0001e000 2**3
CONTENTS, ALLOC, LOAD, DATA
23 .data 000002a0 000000000061e3c0 000000000061e3c0 0001e3c0 2**6
CONTENTS, ALLOC, LOAD, DATA
24 .bss 00000e08 000000000061e680 000000000061e680 0001e660 2**6
ALLOC
每个部分都有自己的attrs,例如READONLY
,CONTENTS
,ALLOC
,LOAD
,DATA
具有相同attrs的部分可以一起映射。
sh_flags Sections support one-bit flags that describe miscellaneous
attributes. If a flag bit is set in sh_flags, the
attribute is "on" for the section. Otherwise, the
attribute is "off" or does not apply. Undefined attributes
are set to zero.
SHF_WRITE This section contains data that should be
writable during process execution.
SHF_ALLOC This section occupies memory during process
execution. Some control sections do not
reside in the memory image of an object
file. This attribute is off for those
sections.
SHF_EXECINSTR This section contains executable machine
instructions.
SHF_MASKPROC All bits included in this mask are reserved
for processor-specific semantics.
ELF
有SHF_EXECINSTR
部分attr,因此编译器或链接没有设置attr。
答案 2 :(得分:-1)
section和segment是两个不同的概念,程序加载使用segment时,甚至可以剥离section表。一个细分可以包含多个部分。 .rodata和.text都是只读的。因此可以将它们放在同一段中。