我正在使用 Android r10e NDK 为 Android 构建 Unison(文件同步可执行文件),但这并不是真正的 Android 问题。
Android > 5.0 (SDK 21) 要求可执行文件与位置无关。所以我
编译时将 -pie 传递给arm-linux-androideabi-gcc,其工作原理:
% hardening-check ./unison
./unison:
Position Independent Executable: yes
...
这在 Android 5.0 设备上运行良好。
Android > 6.0 (SDK 21) 仍然要求可执行文件与位置无关,
但also要求在不进行文本重定位的情况下构建可执行文件。所以我
编译时将 -fPIC 传递给arm-linux-androideabi-gcc,它似乎构建
没有文本重定位的二进制文件:
% arm-linux-androideabi-readelf -a ./unison |& grep TEXTREL
(no output is shown)
问题是,我一次只能满足一个要求。如果我使用 -pie 和
-fPIC 在一起,生成的可执行文件是位置无关的(耶!),但是
还有文本重定位(嘘!):
% hardening-check ./unison
./unison:
Position Independent Executable: yes
...
% arm-linux-androideabi-readelf -a ./unison |& grep TEXTREL
0x00000016 (TEXTREL) 0x0
0x0000001e (FLAGS) TEXTREL BIND_NOW
...Android 6.0 设备拒绝运行它:
% adb push unison /data/local/tmp
% adb shell '/data/local/tmp/unison -version'
WARNING: linker: /data/local/tmp/unison has text relocations. This is wasting memory and prevents security hardening. Please fix.
CANNOT LINK EXECUTABLE: can't protect segments for "/data/local/tmp/unison": Permission denied
让这些标志协同工作需要什么特殊的调味料?或者,
或者,我错过了什么? PIC 和 PIE 是否互斥?
Thanks!
Edit:
我正在手动完成 OPAM 存储库为 Android 构建 Unison 所经历的相同过程。即:
构建 ocaml 交叉编译器。
拉下 Unison 源。
-
应用补丁:
--- pty.c~ 2010-04-15 19:29:31.000000000 +0200
+++ pty.c 2013-01-16 19:28:56.258812188 +0100
@@ -10,7 +10,7 @@
extern void uerror (char * cmdname, value arg) Noreturn;
// openpty
-#if defined(__linux)
+#if defined(__linux) && !defined(__ANDROID__)
#include <pty.h>
#define HAS_OPENPTY 1
#endif
--- Makefile.OCaml~ 2013-01-16 19:27:10.686807807 +0100
+++ Makefile.OCaml 2013-01-16 19:29:46.814814286 +0100
@@ -136,7 +136,9 @@
# openpty is in the libutil library
ifneq ($(OSARCH),solaris)
ifneq ($(OSARCH),osx)
- CLIBS+=-cclib -lutil
+ ifneq ($(OSCOMP),android)
+ CLIBS+=-cclib -lutil
+ endif
endif
endif
buildexecutable::
-
构建:
% make \
UISTYLE=text \
OCAMLOPT="arm-linux-androideabi-ocamlopt -verbose -ccopt '-fPIC -pie'" \
OSCOMP=android
上述过程构建了一个 PIE 可执行文件,该可执行文件在 Android 5 上运行良好,但在 Android 6 上失败,因为它具有文本重定位。删除上面的“-pie”会构建一个没有文本重定位的二进制文件,但不是 PIE 可执行文件,因此它无法在 Android 5 或 6 上运行。