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

时间:2014-11-20 06:51:33

标签: android android-ndk

我们可以为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 +兼容。

2 个答案:

答案 0 :(得分:13)

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

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

完整的故事:当您尝试向库的LDFLAGS添加-pie标志时失败的原因是此标志仅适用于可执行文件,而不适用于库。在构建共享库时,编译器标志-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以获取有关如何轻松构建两个版本的可执行文件的说明。

答案 1 :(得分:2)

  

我们可以为android-ndk r10c中的共享库启用派(即位置独立可执行文件)吗?

PIE是在Android 4.1 / android-16中引入的(请参阅Android <uses-sdk>),但它是可选的。见Security Enhancements in Android 1.5 through 4.1。所以我认为它更少依赖于NDK版本,而更多依赖于Android版本。

当我尝试在Android 4.0或更低版本上运行PIE代码时,我在/system/bin/linker中遇到了段错误。那就是HTC Evo 4G。您的里程可能会有所不同,具体取决于OEM提供的链接/装载机的强大程度。另请参阅Is PIE (Position-independent executable) for main executables supported in Android 4.0 (ICS)?

现在,Android 5.0及更高版本需要PIE。另请参阅Security Enhancements in Android 5.0

如果您尝试编译/链接Android 5.0 / android-21(请参阅Android <uses-sdk>),并且没有PIE,则会出现链接错误。另请参阅Position Independent Executables and Android Lollipop

  

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

快速说明显而易见的事情(一旦你了解它)。 PICPIE略有不同。您可以在可执行程序上使用PIE,在共享对象上使用PIC。

如果 您正在使用同一组源和目标文件构建可执行文件和共享对象,那么您将使用PIC,因为PIC适用于两者(相同的<强> 不是 属于PIE)。另请参阅Position Independent Executables and Android Lollipop

  

如果是,那该怎么做?

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

如果 您正在使用同一组源和目标文件构建可执行文件和共享对象,那么您将使用PIC,因为PIC适用于两者(相同的<强> 不是 属于PIE)。另请参阅Position Independent Executables and Android Lollipop