链接器:啥是链接文件的“NMAGIC”部分,部分对齐的目的是啥?

Posted

技术标签:

【中文标题】链接器:啥是链接文件的“NMAGIC”部分,部分对齐的目的是啥?【英文标题】:linker: what is "NMAGIC" section of linked file and what is the aim of section alignment?链接器:什么是链接文件的“NMAGIC”部分,部分对齐的目的是什么? 【发布时间】:2020-03-12 15:24:56 【问题描述】:

老男人here说

-n --nmagic 关闭节的页面对齐,并尽可能将输出标记为“NMAGIC”。 -N ——魔幻 将文本和数据部分设置为可读可写。此外,不要对数据段进行页面对齐,并禁用针对共享的链接 图书馆。如果输出格式支持 Unix 风格的幻数, 将输出标记为“OMAGIC”。注意:虽然可写文本部分是 允许用于 PE-COFF 目标,它不符合格式 微软发布的规范。 --没有魔法 此选项抵消了 -N 选项的大部分效果。它将文本部分设置为只读,并强制数据段为 页面对齐。注意 - 此选项不启用链接 共享库。为此使用 -Bdynamic。

我知道这些选项用于使代码 (.text) 部分可写或不可写,但我不明白要对齐或不对齐部分,什么是“NMAGIC”部分

【问题讨论】:

【参考方案1】:

在历史悠久的 (PDP-11) Unix 上,可执行文件的标头以分支指令开头,该指令将跳过标头,到达代码的实际开头。当 Unix 被移植到其他处理器时,最初的 PDP-11 分支指令变成了 a.out(5) 文件格式的“幻数”。当引入“纯文本”时,最初是为了允许进程共享它们的代码段,引入了一个新的幻数,以便内核能够区分(有一些重要的 Unix 程序依赖于自修改代码,因此需要加载可写的代码段)。旧的幻数(0407)被命名为“OMAGIC”——“老魔术”——而新的幻数(0410)被命名为“NMAGIC”,“新魔术”。数据段紧跟在内存中的代码段之后,所以当代码段被设为只读时,它必须被填充到页边界。

从那时起,各种操作系统和文件格式引入了其他幻数;在最后一个使用 a.out 格式的 FreeBSD 版本中,正常的格式是 ZMAGIC 和 QMAGIC,它们被引入以允许地址空间中的页面零被取消映射以确保安全(因此空指针取消引用会出错)同时仍然允许需要分页的可执行文件(即,mmap() 到进程的地址空间)。

所以更直接地回答您的问题:NMAGIC 和 OMAGIC 是可执行文件的不同格式,而不是单独的部分。它们指示可执行文件的内存和磁盘布局之间的所需对应关系。 (这些数字传统上用八进制而不是十六进制或十进制编写的原因是八进制是 PDP-11 上指令格式的自然表示。)GNU ld (仅)使用这些名称作为对具有类似特征的可执行格式的引用,即使您没有生成传统的 a.out 格式——这在今天当然是非常罕见的。使用 OMAGIC 格式的一个特别的好处是它比任何其他格式都更紧凑,这在空间有限、没有需求分页、也没有任何填充空间的情况下可能很重要。

【讨论】:

没有得到一切,但这听起来更像是一个历史原因。如果 OMAGIC 节省空间有什么缺点?如果 NMAGIC 不是全部,为什么不呢?

以上是关于链接器:啥是链接文件的“NMAGIC”部分,部分对齐的目的是啥?的主要内容,如果未能解决你的问题,请参考以下文章

GCC链接器:在指定部分移动符号

Golang内部构件,第3部分:链接器,目标文件和重定位

链接器为rodata 部分计算错误的地址

linux中,啥是连结档,链接,链接目录

GNU Linker - 孤立的部分和符号赋值

链接器脚本:我可以在多个部分中指定 (*COMMON) 吗?