我需要一些GCC优化行为的帮助,该行为在检测到存在结构变量赋值时插入对memcpy
的调用。
我有以下示例代码:
struct foo_t {
int x[1048576];
} *foo0, *foo1;
void bar(struct foo_t* foo)
{
*foo1 = *foo;
}
int main()
{
return 0;
}
# /usr/src/gcc-6.1.0/build/bin/gcc -fPIE -S b.c
这导致GCC编译器在函数栏1中发出对memcpy@PLT()
的调用。
我想从这个源创建一个独立于位置的可执行文件,并在实现ASLR的安全环境中运行,加载程序不允许任何二进制文件其具有基于PLT/GOT的重新定位。
我尝试过使用类似-fno-tree-loop-distribute-patterns
的选项,但即使使用此选项,如果存在-fPIE
标志,我也会看到有对memcpy@PLT
的引用。
我甚至尝试过-fno-plt
和-mstringop-strategy=loop
这样的选项,但我不想使用这些选项生成的输出程序。
我的问题不在于记忆,而在于PLT部分;我希望GCC在检测到存在结构变量赋值时,在一个与位置无关的可执行文件中生成对memcpy
(而不是memcpy@PLT
(的引用。
我也尝试过为这个文件设置隐藏可见性,但在这种情况下也有相同的PLT引用。
#pragma GCC visibility push(hidden)
当GCC检测到存在结构变量赋值时,它是否总是为位置无关的可执行文件插入对memcpy@PLT
的调用?是否可以指示GCC插入带有-fPIE
标志的memcpy
?
memcpy
是一个具有外部链接的函数。在独立于位置的可执行文件中,它只能通过PLT或GOTPSEL(-fno-plt
(来引用。
唯一的其他选项是将memcpy
内联到调用程序中。
不要对整个结构和并集使用assign运算符,否则很可能会调用memcpy。
顺便说一句,如果在与位置无关的代码中使用了标准库的任何函数,或者需要重写所使用的函数,则需要重新编译整个标准库。