正如 n4sm 下面提到的 gcc-8 或更高版本支持-static-pie
它使用 PIE 生成静态二进制文件。请注意,这是一种选择,而不是两种。如果您尝试使用-static -pie
它不会按照你的想法做。
我刚刚在 te.c 中进行了快速测试:
int main( int argc, const char* argv[] )
{
return 0;
}
Running arm-linux-androideabi-gcc -o conftest -static -FPIE -pie te.c
不会产生任何错误。然而file -k conftest
outputs
conftest: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), not stripped
readelf -l conftest
输出
Elf 文件类型为 DYN(共享对象文件)
入口点0x500
有7个程序头,从偏移52开始
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x00000034 0x00000034 0x000e0 0x000e0 R 0x4
INTERP 0x000114 0x00000114 0x00000114 0x00013 0x00013 R 0x1
[Requesting program interpreter: /system/bin/linker]
...
PHDR 和 INTERP 标头的存在表明 -pie 在arm 编译器中默默地覆盖了 -static。为什么这是我不知道的,但我认为这是一个错误,当 -static 和 -pie 一起使用时不会发出警告。相反,像您这样的程序员会留下这样的错误印象:这两个选项可以在手臂上一起使用。
只是为了澄清这里唯一的行为差异是 x86 编译器在看到 --static 和 --pie 时出错,而 ARM 版本如果给出 --pie 则默默地忽略 --static 。如果只给出其中一个,则两个编译器的行为是相同的。