如何检测 Android x86 是否正在模拟 ARM?

问题描述 投票:0回答:4

我有一个 JNI 库,可以在大多数 Android 设备上运行良好 - ARMv5、ARMv7 和 x86。

我在 ARMv7 上使用 NEON 指令,但我不想用条件/重复的源代码弄乱代码,而是想在库加载时检测 Java 中的非 NEON ARMv7,并加载 v5 库:慢速 CPU 很慢。

我发现一篇文章建议我在 /proc/cpuinfo 中查找“neon”功能,因此我正在解析该功能,并通常加载 libthing.so,或者如果设备声称是 ARMv7,则加载 libthing-v5.so氖。这在 ARM 上运行得很好。

不幸的是,x86 不仅模拟 ARM /proc/cpuinfo(!),如果它认为它不理解 NEON,那么它还会从 armeabiv7a 目录中挖掘出 libthing-v5.so 并使用它,因为没有x86 目录中的一个。

我当前的解决方法是将 x86 库复制到 libthing.so 和 libthing-v5.so,因此如果 x86 假装是不含 NEON 的 ARMv7 芯片,它无论如何都会获得 x86 库。

除了根据 Yeppp 或 Android 自己的 cpufeatures 构建一个自己的小型独立架构检测库之外,还有其他方法可以从 Java 中确定真正的本地架构吗?


@ph0b:这里是 Razr i 的输出,显示模拟器已确定该应用程序已安装为“ABI2 58”,并且需要伪造 /proc/cpuinfo。

鉴于这两个共享库都可以从 x86 以及 armeabi* 目录获得,我不明白为什么该设备决定成为 ARM。我可能会向我在英特尔的联系人询问此事。

06-05 10:58:41.360 17807 18053 D dalvikvm: Trying to load lib /data/data/com.company.android/lib/libmp.so 0x42409cb0
06-05 10:58:41.360 17807 18053 D dalvikvm: Added shared lib /data/data/com.company.android/lib/libmp.so 0x42409cb0
06-05 10:58:41.370 17807 18053 D dalvikvm: No JNI_OnLoad found in /data/data/com.company.android/lib/libmp.so 0x42409cb0, skipping init
06-05 10:58:41.420 17807 18053 D         : Searching package installed with ABI2 with Uid: 10109 
06-05 10:58:41.420 17807 18053 D         : Apps with ABI2 58 accessing /proc/cpuinfo 
06-05 10:58:41.430 17807 18053 I System.out: #Here's most of /proc/cpuinfo
06-05 10:58:41.430 17807 18053 I System.out: #Thu Jun 05 10:58:41 GMT+01:00 2014
06-05 10:58:41.430 17807 18053 I System.out: Serial=0000000000000001
06-05 10:58:41.430 17807 18053 I System.out: Revision=0001
06-05 10:58:41.430 17807 18053 I System.out: CPU=revision\t\: 1
06-05 10:58:41.430 17807 18053 I System.out: BogoMIPS=1500
06-05 10:58:41.430 17807 18053 I System.out: Hardware=placeholder
06-05 10:58:41.430 17807 18053 I System.out: Features=vfp swp half thumb fastmult edsp vfpv3 
06-05 10:58:41.430 17807 18053 I System.out: Processor=ARMv7 processor rev 1 (v7l)
06-05 10:58:41.430 17807 18053 I NativeWahooLibrary: Detected ARMv7 processor rev 1 (v7l) (=ARMv7, true) with (neon@-1) vfp swp half thumb fastmult edsp vfpv3 
06-05 10:58:41.430 17807 18053 D dalvikvm: Trying to load non-neon lib /data/data/com.company.android/lib/libwahoo-v5.so 0x42409cb0
android-ndk x86 arm
4个回答
3
投票

我怀疑 x86 是否模拟了 ARM /proc/cpuinfo!?

无论如何,为了从Java中检测本地架构,您可以依赖

Build.CPU_ABI
Build.CPU_ABI2
http://developer.android.com/reference/android/os/Build.html#CPU_ABI,以及然后继续解析 /proc/cpuinfo 以仅在 CPU_ABI 和 CPU_ABI2 为 arm*/armeabi-v7a 时查找 neon


2
投票

您不能依赖 proc/cpuinfo、getProperty("os.arch") 或 Build.CPU_ABI(2)。如果仿真处于活动状态,它们都是假的。我进行检测的方法是解析 /proc/cpuinfo 寻找单词“占位符”。它位于“硬件:”行中。通常情况下,Samsung Galaxy 有一个真实的公司名称,例如“Samsung”,但在 x86 上的 ARM 仿真中,我看到 /proc/cpuinfo 中的硬件行中只有“占位符”。我还没有在很多设备型号上进行过测试,所以不能说这种方式有多可靠。


2
投票

您还可以检索 ELF 文件头中定义的

e_machine
值,例如文件
libc.so
,以检测指定的架构。

https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header

代码片段:

File libc = new File(Environment.getRootDirectory(), "lib/libc.so"); // or 'lib64' if 64 bit
// assert libc file exsits
RandomAccessFile file = new RandomAccessFile(libc, "r");
file.seek(0x12); // 'e_machine' offset
byte[] buf = new byte[2]; // 2 bytes size
file.readFully(buf);
int em = (buf[0] & 0xff) | ((buf[1] & 0xff) << 8);
file.close();
if(em == 0x03 || em == 0x3E) {
    // x86!
}

Build.CPU_ABI
表示您在 ARM 上运行,但与 x86
em
冲突时,它正在模拟!


0
投票

如果您有不同的 ARM 和 x86 本机库列表,那么这听起来很可怕,那么类似的设备将自动切换到在 ARM 模拟器下运行应用程序。

https://software.intel.com/en-us/forums/android-applications-on-intel-architecture/topic/518471

© www.soinside.com 2019 - 2024. All rights reserved.