Android ndk 我如何检测Android x86何时在模仿ARM?

Android ndk 我如何检测Android x86何时在模仿ARM?,android-ndk,x86,arm,Android Ndk,X86,Arm,我有一个JNI库,在大多数Android设备上运行良好——ARMv5、ARMv7和x86 我在ARMv7上使用NEON指令,但我希望在库加载时检测Java中的非NEON ARMv7,并加载v5库,而不是用条件/重复源代码来混乱代码:CPU慢就是慢 我发现一篇帖子建议我在/proc/cpuinfo中查找“neon”功能,所以我正在解析它,并加载libthing.so通常,或者libthing-v5.so,如果设备声称是没有neon的ARMv7。这在手臂上很有效 不幸的是,x86不仅模拟了ARM/p

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

我在ARMv7上使用NEON指令,但我希望在库加载时检测Java中的非NEON ARMv7,并加载v5库,而不是用条件/重复源代码来混乱代码:CPU慢就是慢

我发现一篇帖子建议我在/proc/cpuinfo中查找“neon”功能,所以我正在解析它,并加载libthing.so通常,或者libthing-v5.so,如果设备声称是没有neon的ARMv7。这在手臂上很有效

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

我目前的解决方法是将x86库复制到libthing.so和libthing-v5.so。因此,如果x86假装是一个无霓虹灯的ARMv7芯片,它无论如何都会得到x86库

除了根据Yeppp或Android自己的CPuffeatures创建一个我自己的小型独立体系结构检测库之外,还有什么方法可以从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

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


无论如何,为了从Java中检测本地架构,您可以依赖于
Build.CPU_ABI
Build.CPU_ABI2
:,然后继续解析/proc/cpuinfo,仅当CPU_ABI和CPU_ABI2是arm*/armeabi-v7a

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

听起来很可怕如果你有一个不同的ARM和x86本机lib列表,那么像这样的设备将自动切换到在ARM emulator下运行应用程序


您还可以检索ELF文件头中定义的
e_machine
值,例如文件
libc.so
,以检测指定的体系结构

代码段:

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!
}
File libc=new文件(Environment.getRootDirectory(),“lib/libc.so”);//如果为64位,则为“lib64”
//断言libc文件存在
RandomAccessFile文件=新的RandomAccessFile(libc,“r”);
file.seek(0x12);/'e_机器的偏移量
字节[]buf=新字节[2];//2字节大小
文件。可读(buf);

int em=(buf[0]&0xff)|((buf[1]&0xff)请参阅上面Razri的奇怪输出,它显示了一个ARM/proc/cpuinfo。它为我的测试应用程序发出一个x86/proc/cpuinfo。除此之外,我手头上的两个Intel设备上都有CPU_ABI=x86和CPU_ABI2=armeabi-v7a;我真正的ARM设备有CPU_ABI=armeabi-v7a和CPU_ABI2=armeabi,除了一个意外地变成了Intel(!)@ph0b似乎包含x86和arm-v7的应用程序被检测为“armeabi-v7a”(例如:华硕Zenfone设备)在
Build.CPU\u ABI
Build.CPU\u ABI2
中,如果我们尝试编译一个应用程序来输出
Build.CPU\u ABI*
而不使用NDK,它将显示正确的结果,即
x86
armeabi-v7a
,对此有什么想法吗?如果该应用程序包含正在安装的x86库(或者根本没有库)在x86设备上,
Build.CPU_ABI
应返回x86,否则设备上的构建有问题。在Zenfone上,实际安装的LIB有时是arm LIB,因为它认为缺少一些x86 LIB,所以会返回到arm LIB。使用我的应用程序,您可以轻松确定这一点: