diff --git a/vlc-android/src/org/videolan/libvlc/LibVlcUtil.java b/vlc-android/src/org/videolan/libvlc/LibVlcUtil.java index a4d5cd30fe0105a6c7570491b1a05092e996bb41..a4bed55b36ed0eff012742386ca0efabc9c9f760 100644 --- a/vlc-android/src/org/videolan/libvlc/LibVlcUtil.java +++ b/vlc-android/src/org/videolan/libvlc/LibVlcUtil.java @@ -121,17 +121,27 @@ public class LibVlcUtil { } catch (Exception e) { } } - Log.i(TAG, "machine = " + (elf.e_machine == EM_ARM ? "arm" : elf.e_machine == EM_386 ? "x86" : "mips")); + final boolean elfHasX86 = elf.e_machine == EM_386 || elf.e_machine == EM_X86_64; + final boolean elfHasArm = elf.e_machine == EM_ARM || elf.e_machine == EM_AARCH64; + final boolean elfHasMips = elf.e_machine == EM_MIPS; + final boolean elfIs64bits = elf.is64bits; + + Log.i(TAG, "machine = " + (elfHasArm ? "arm" : elfHasX86 ? "x86" : "mips") + ", " + + (elfIs64bits ? "64bits" : "32bits")); Log.i(TAG, "arch = " + elf.att_arch); Log.i(TAG, "fpu = " + elf.att_fpu); boolean hasNeon = false, hasFpu = false, hasArmV6 = false, - hasArmV7 = false, hasMips = false, hasX86 = false; + hasArmV7 = false, hasMips = false, hasX86 = false, is64bits = false; float bogoMIPS = -1; int processors = 0; if(CPU_ABI.equals("x86") || CPU_ABI2.equals("x86")) { hasX86 = true; + } else if(CPU_ABI.equals("x86_64") || + CPU_ABI2.equals("x86_64")) { + hasX86 = true; + is64bits = true; } else if(CPU_ABI.equals("armeabi-v7a") || CPU_ABI2.equals("armeabi-v7a")) { hasArmV7 = true; @@ -139,6 +149,12 @@ public class LibVlcUtil { } else if(CPU_ABI.equals("armeabi") || CPU_ABI2.equals("armeabi")) { hasArmV6 = true; + } else if(CPU_ABI.equals("arm64-v8a") || + CPU_ABI2.equals("arm64-v8a")) { + hasNeon = true; + hasArmV6 = true; + hasArmV7 = true; + is64bits = true; } try { @@ -192,21 +208,21 @@ public class LibVlcUtil { processors = 1; // possibly borked cpuinfo? // Enforce proper architecture to prevent problems - if(elf.e_machine == EM_386 && !hasX86) { + if(elfHasX86 && !hasX86) { errorMsg = "x86 build on non-x86 device"; isCompatible = false; return false; - } else if(elf.e_machine == EM_ARM && hasX86) { + } else if(elfHasArm && hasX86) { errorMsg = "ARM build on x86 device"; isCompatible = false; return false; } - if(elf.e_machine == EM_MIPS && !hasMips) { + if(elfHasMips && !hasMips) { errorMsg = "MIPS build on non-MIPS device"; isCompatible = false; return false; - } else if(elf.e_machine == EM_ARM && hasMips) { + } else if(elfHasArm && hasMips) { errorMsg = "ARM build on MIPS device"; isCompatible = false; return false; @@ -228,6 +244,10 @@ public class LibVlcUtil { return false; } } + if (elfIs64bits && !is64bits) { + errorMsg = "64bits build on 32bits device"; + isCompatible = false; + } float frequency = -1; try { @@ -256,6 +276,7 @@ public class LibVlcUtil { machineSpecs.hasMips = hasMips; machineSpecs.hasNeon = hasNeon; machineSpecs.hasX86 = hasX86; + machineSpecs.is64bits = is64bits; machineSpecs.bogoMIPS = bogoMIPS; machineSpecs.processors = processors; machineSpecs.frequency = frequency; @@ -273,6 +294,7 @@ public class LibVlcUtil { public boolean hasArmV7; public boolean hasMips; public boolean hasX86; + public boolean is64bits; public float bogoMIPS; public int processors; public float frequency; /* in MHz */ @@ -281,11 +303,14 @@ public class LibVlcUtil { private static final int EM_386 = 3; private static final int EM_MIPS = 8; private static final int EM_ARM = 40; + private static final int EM_X86_64 = 62; + private static final int EM_AARCH64 = 183; private static final int ELF_HEADER_SIZE = 52; private static final int SECTION_HEADER_SIZE = 40; private static final int SHT_ARM_ATTRIBUTES = 0x70000003; private static class ElfData { ByteOrder order; + boolean is64bits; int e_machine; int e_shoff; int e_shnum; @@ -317,6 +342,8 @@ public class LibVlcUtil { switch (elf.e_machine) { case EM_386: case EM_MIPS: + case EM_X86_64: + case EM_AARCH64: return elf; case EM_ARM: in.close(); @@ -354,10 +381,12 @@ public class LibVlcUtil { bytes[1] != 'E' || bytes[2] != 'L' || bytes[3] != 'F' || - bytes[4] != 1) { // ELFCLASS32, Only 32bit header is supported + (bytes[4] != 1 && bytes[4] != 2)) { + Log.e(TAG, "ELF header invalid"); return false; } + elf.is64bits = bytes[4] == 2; elf.order = bytes[5] == 1 ? ByteOrder.LITTLE_ENDIAN // ELFDATA2LSB : ByteOrder.BIG_ENDIAN; // ELFDATA2MSB