问题 我们可以为android-ndk r10c中的共享库启用pie(即Position Independent Executables)吗?


我们可以为android-ndk r10c中的共享库启用pie(即Position Independent Executables)吗?如果是,那该怎么做?

我读到我们应该使用PIC作为动态库,PIE作为可执行文件,但看起来像android NDK不支持PIC。

我尝试在LDFLAGS中启用-pie标志,但我收到以下错误:

/android-ndk-r10c/platforms/android-19/arch-arm/usr/lib/crtbegin_dynamic.o:
  in function _start:crtbrand.c(.text+0x8c): error: undefined reference to 'main'

请帮我解决这个问题,因为我已经读到谷歌将在即将到来的Android版本中强制执行PIE,所以我希望我的应用程序与ANDROID-L +兼容。


8202
2017-11-20 06:51


起源

如果可能,请显示编译器的示例调用以及链接器的调用。 - jww


答案:


真正的简短故事是,如果您正在构建共享库(而不是可执行文件),则不需要执行任何操作。在较旧版本的Android上运行的库将继续正常运行 - 在Android 5.0中没有任何改变。

几乎同样简短的故事是,如果您使用Android.mk构建可执行文件并定位到Android 4.1+,则必须自动添加必要的标记。

全文:当您尝试添加时失败的原因 -pie 标记到LDFLAGS的库,是这个标志只用于可执行文件,而不是库。构建共享库时,编译器标志 -fPIC (在构建单个目标文件时,如果手动运行编译器 - Android.mk和ndk-build自动处理这种情况)可能需要某些体系结构,但您会注意到它是必需的,因为链接器将拒绝生成共享库,如果需要,你没有设置它。因此,如果您遇到问题,您将会知道它将无法构建 - 如果您已成功构建它,则没有任何问题。

类似地,在构建可执行文件时,您需要添加 -fPIE 在构建目标文件时,和 -fPIE -pie 链接可执行文件时。如果你的APP_PLATFORM是android-16(Android 4.1)或更高版本,Android.mk和ndk-build会自动处理这个问题。这是一个很大的问题 - 用它构建的可执行文件 -pie 只能在android-16或更高版本上运行,而无需构建可执行文件 -pie 不适用于android-21(Android 5.0)。所以这里有一个宽限期,Android 4.1到4.4会运行任何可执行文件就好了,而你明确需要一个版本没有 -pie 对于较旧的和另一个版本 -pie 对于新的。

如果您还需要定位4.1之前的Android版本,请参阅 https://stackoverflow.com/a/26422855/3115956 有关如何轻松构建可执行文件的两个版本的说明。


13
2017-11-20 07:09



谢谢你的回复。首先,我的应用程序应该支持Android 4.1以上,所以我可以毫不费力地使用-pie。我没有任何可执行文件但有几个共享库。我还认为PIE仅对可执行文件是强制性的,但只需检查此链接 vinsol.com/blog/2014/08/19/... 提到我们应该为库启用饼图。 - ssk
几乎 - 它说你应该为库启用PIC,而不是PIE。如果基于其他静态库构建可执行文件,则需要使用-fPIC构建这些库(否则在构建可执行文件时会出现错误)。如果您只是构建共享库,则需要相同(如果不这样做,则在链接时会出现错误)。因此,重申一下,如果您只使用共享库而不使用可执行文件,那么您就可以了,并且您不需要对此进行任何更改。 - mstorsjo
谢谢mstorsjo。得到它了 :) - ssk


我们可以为android-ndk r10c中的共享库启用pie(即Position Independent Executables)吗?

PIE是在Android 4.1 /中引入的android-16 (看到 Android <uses-sdk>),但它是可选的。看到 Android 1.5到4.1中的安全增强功能。所以我认为它更少依赖于NDK版本,而更多依赖于Android版本。

当我尝试在Android 4.0或更低版本上运行PIE代码时,我得到了一个段错误 /system/bin/linker。那就是HTC Evo 4G。您的里程可能会有所不同,具体取决于OEM提供的链接/装载机的强大程度。另见 Android 4.0(ICS)支持主要可执行文件的PIE(位置无关可执行文件)吗?

现在,Android 5.0及更高版本需要PIE。另见 Android 5.0中的安全增强功能

如果您尝试编译/链接Android 5.0 /android-21 (看到 Android <uses-sdk>),没有PIE,那么你会得到一个链接错误。另见 位置独立可执行文件和Android棒棒糖


我们可以为android-ndk中的共享库启用pie ...

快速说明一下(一旦你了解它)。 PIC 与...略有不同 PIE。您在可执行程序上使用PIE,在共享对象上使用PIC。

如果 您正在从同一组源和目标文件构建可执行文件和共享对象,然后您将使用PIC,因为PIC适用于两者(相同) 不是 PIE的真实情况)。另见 位置独立可执行文件和Android棒棒糖


如果是,那该怎么做?

您可以通过两种方式之一编译和链接PIE可执行文件。首先,编译所有内容 -fPIE 和链接 -pie。第二个是编译所有内容 -fPIC 和链接 -pie

如果 您正在从同一组源和目标文件构建可执行文件和共享对象,然后您将使用PIC,因为PIC适用于两者(相同) 不是 PIE的真实情况)。另见 位置独立可执行文件和Android棒棒糖


2
2018-06-05 08:32