【发布时间】:2019-06-06 08:39:07
【问题描述】:
我想在编译时将 EWR(Execute/Write/Read) 内存属性添加到 .data 部分。
MSVC 编译器只需添加“/SECTION:.data,EWR”链接器选项即可完成此操作。
但我不知道如何在 GCC 编译器 (MinGW) 中执行此操作。
请帮忙!
【问题讨论】:
标签: gcc linker-flags
我想在编译时将 EWR(Execute/Write/Read) 内存属性添加到 .data 部分。
MSVC 编译器只需添加“/SECTION:.data,EWR”链接器选项即可完成此操作。
但我不知道如何在 GCC 编译器 (MinGW) 中执行此操作。
请帮忙!
【问题讨论】:
标签: gcc linker-flags
我能想到的最简单的方法是在链接中添加一个虚拟文件,其中包含具有所需标志的 .data.* 部分。使用汇编很容易生成该虚拟文件:
.section .data.fake, "axw"
(假设您在 ELF 平台上,使用 gas)。
比如说,包含上面的文件叫做dummy.s,那么你可以手动组装它,然后将结果添加到链接中
as dummy.s -o dummy.o
gcc <all your normal .o files> dummy.o # or `ld`
或者只是将汇编文件传递给驱动程序:
gcc <all your normal files> dummy.s
注意汇编器会给出警告:
Warning: setting incorrect section attributes for .data.fake
因为不寻常的标志。它确实按照要求设置它们。
现在,让我解释一下发生了什么。
所有输入.data* 部分都合并到输出.data 部分。查看默认链接器脚本 (ld --verbose):
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
输出部分的标志是输入部分的标志的联合(我很确定这种行为记录在链接器手册中)。这就是诀窍的工作原理。然后,保存结果.data 的段的标志也被计算为其包含的部分的标志的并集。查看readelf -lW 的输出以确保您获得了预期的结果。我有
...
LOAD 0x002e28 0x0000000000003e28 0x0000000000003e28 0x000200 0x000208 *RWE* 0x1000
...
05 .init_array .fini_array .dynamic .got .got.plt *.data* .bss
【讨论】:
data2 不如data.2 好(请参阅我的答案中默认班轮脚本的摘录)。此外,请考虑将答案标记为已接受,除非您认为该问题需要进一步关注。