GCC:-static和-pie与x86不兼容?

4nt*_*ine 8 gcc gcc4.7 android-5.0-lollipop

我正在为Android 5.0重新编译一些可执行文件,因为它需要可执行文件PIE.我能够ARM在配置时添加一些参数(使用独立工具链)重新编译它:

export CFLAGS="-I/softdev/arm-libs/include -fPIE"
export CPPLAGS="$CPPFLAGS -fPIE"
export CXXLAGS="$CXXFLAGS -fPIE"
export LDFLAGS="-L/softdev/arm-libs/lib -static -fPIE -pie"
Run Code Online (Sandbox Code Playgroud)

ARM没有错误:

configure:3406: arm-linux-androideabi-gcc -o conftest -I/softdev/arm-libs/include -fPIE  -L/softdev/arm-libs/lib -static -fPIE -pie conftest.c  >&5
configure:3410: $? = 0
Run Code Online (Sandbox Code Playgroud)

但我无法做同样的事情,x86因为我得到错误:

export CFLAGS="-I/softdev/x86-libs/include -fPIE"
export CPPLAGS="$CPPFLAGS -fPIE"
export CXXLAGS="$CXXFLAGS -fPIE"
export LDFLAGS="-L/softdev/x86-libs/lib -static -fPIE -pie"
Run Code Online (Sandbox Code Playgroud)

错误:

configure:3336: i686-linux-android-gcc -I/softdev/x86-libs/include -fPIE  -L/softdev/x86-libs/lib -static -fPIE -pie conftest.c  >&5
/softdev/x86-toolchain-gcc4.8/bin/../lib/gcc/i686-linux-android/4.8/../../../../i686-linux-android/bin/ld: fatal error: -pie and -static are incompatible
collect2: error: ld returned 1 exit status
configure:3340: $? = 1
Run Code Online (Sandbox Code Playgroud)

我需要静态链接可执行文件.怎么了,怎么解决?

PS.还尝试使用android ndk r9d和r10c中的x86独立工具链:

./make-standalone-toolchain.sh --toolchain=x86-4.8 --arch=x86 --install-dir=/softdev/x86-toolchain-gcc4.8-r9d --ndk-dir=/softdev/android-ndk-r9d/ --system=darwin-x86_64
Run Code Online (Sandbox Code Playgroud)

whe*_*rom 6

我只是对te.c中的不足进行了快速测试:

int main( int argc, const char* argv[] )
{
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

运行arm-linux-androideabi-gcc -o conftest -static -FPIE -pie te.c不会产生任何错误。但是file -k conftest输出

conftest: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), not stripped
Run Code Online (Sandbox Code Playgroud)

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]
...
Run Code Online (Sandbox Code Playgroud)

PHDR和INTERP标头的存在指示-pie在arm编译器中静默覆盖-static。为什么我不知道为什么,但是我会认为当-static和-pie一起使用时没有给出警告的错误。相反,像您这样的程序员留下了错误的印象,即这两个选项可以一起使用。

只是为了澄清唯一的行为差异,就是x86编译器在同时看到--static和--pie时出错,而arm版本在给出--pie的情况下默默地忽略了--static。如果仅给出这些,则两个编译器的行为相同。

  • 对于工具链测试,通常也可以使用`echo'main(){}'> te.c`。 (2认同)