我看到在加载到内存中时,使用-PIE参数链接的ELF文件的.text段位于虚拟内存地址的某个位置,如Linux x86_64上的0x00005xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx我判断了几个正在运行的进程,似乎.Text段的地址all的前缀为0x00005,例如,我找不到任何前缀为0x00004的进程.

Dynamic Linker Select 这个地址范围(0x00005xxxxxxxxxxxx)来定位.text段有什么原因吗?为什么它不 Select 一些从4Mb+开始的地址,比如没有-PIE参数链接的二进制地址?

推荐答案

为什么动态链接器 Select 这个地址范围(0x00005xxxxxxxxxxx)来定位. text段?

动态链接器有nothing to do with this个.

在执行第一个用户空间指令(该指令是动态链接二进制文件的动态加载器中的_start)之前,内核执行可执行文件,作为执行execve系统调用的一部分.

因此,您必须查看内核源代码来解释为什么PIE二进制文件最终会在0x5...范围内.

查看fs/binfmt_elf.c,你可以看到它使用了ELF_ET_DYN_BASE,在arch/x86/include/asm/elf.h中定义为

#define ELF_ET_DYN_BASE         (mmap_is_ia32() ? 0x000400000UL : \
                                                  (DEFAULT_MAP_WINDOW / 3 * 2))

DEFAULT_MAP_WINDOW本身来自arch/x86/include/asm/page_64_types.h:

#define DEFAULT_MAP_WINDOW ((1UL << 47) - PAGE_SIZE)

把这些加在一起:(1UL << 47) - 4096 == 0x7ffffffff0000x7ffffffff000 / 3 * 2 == 0x555555554aaa.

P.S.注意,.text是一个区段,not是一个区段.看this answer.

Linux相关问答推荐

BASH-SCRIPT-在特定行合并两个文件

如何在带模式的文件频繁更改的管道中使用grep-f带模式的文件?

如何在Linux下使用正则表达式更改文件名

sed + 从没有额外空格的文本中删除单词

Bash 更新 yaml 文件中的图像值

std::system 使用什么Shell?

我可以阅读 Linux 内核的哪些部分以获得乐趣?

PHP factor 30 从 Linux 到 Windows 的性能差异

在没有root访问权限的情况下安装zsh?

如何比较两个压缩包的内容

使用 RPATH 但不使用 RUNPATH?

适用于 Linux 和 Mac 的 HTTP 调试代理

使用特定目录作为根目录压缩目录的命令

如何在不包括可用空间的情况下创建光盘(sd 卡)的 .IMG 映像?

Mac OS X 中的 ldconfig 等效项?

如何在字符串中查找子字符串(或如何 grep 变量)?

使用 C++ 代码在 Linux 中清除终端

crt1.o:在函数_start中:-Linux 中未定义对main的引用

Linux SCHED_OTHER、SCHED_FIFO 和 SCHED_RR - 区别

Linux cmd 在 jar 中搜索类文件,而不考虑 jar 路径