diff --git a/CHANGES.md b/CHANGES.md index 01a785fb7e..d1ed64a103 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,7 +12,7 @@ Bug Fixes --------- * [#652](https://github.com/java-native-access/jna/issues/652): Dead Lock in class initialization - [@matthiasblaesing](https://github.com/matthiasblaesing). * [#843](https://github.com/java-native-access/jna/pull/843): Correctly bind `com.sun.jna.platform.win32.SecBufferDesc` and add convenience binding as `com.sun.jna.platform.win32.SspiUtil.ManagedSecBufferDesc`. Bind SSPI functions `InitializeSecurityContext`, `AcceptSecurityContext`, `QueryCredentialsAttributes`, `QuerySecurityPackageInfo`, `EncryptMessage`, `DecryptMessage`, `MakeSignature`, `VerifySignature` in `com.sun.jna.platform.win32.Secur32` - [@matthiasblaesing](https://github.com/matthiasblaesing). - +* [#863](https://github.com/java-native-access/jna/pull/863): Fix ARM softfloat/hardfloat detection by modifying armSoftFloat condition in ELFAnalyser. Before this fix a softfloat binary could be misdetected as hardfloat. - [@kunkun26](https://github.com/kunkun26). Breaking Changes ---------------- diff --git a/src/com/sun/jna/ELFAnalyser.java b/src/com/sun/jna/ELFAnalyser.java index c3eed7985f..6e7d9901ec 100644 --- a/src/com/sun/jna/ELFAnalyser.java +++ b/src/com/sun/jna/ELFAnalyser.java @@ -133,8 +133,8 @@ private void runDetection() throws IOException { if(arm) { int flags = headerData.getInt(_64Bit ? 0x30 : 0x24); - armSoftFloat = (flags & EF_ARM_ABI_FLOAT_SOFT) == EF_ARM_ABI_FLOAT_SOFT; armHardFloat = (flags & EF_ARM_ABI_FLOAT_HARD) == EF_ARM_ABI_FLOAT_HARD; + armSoftFloat = !armHardFloat; } } } diff --git a/test/com/sun/jna/ELFAnalyserTest.java b/test/com/sun/jna/ELFAnalyserTest.java index 9367cc9d0b..b1ce5c6c00 100644 --- a/test/com/sun/jna/ELFAnalyserTest.java +++ b/test/com/sun/jna/ELFAnalyserTest.java @@ -1,11 +1,10 @@ package com.sun.jna; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; +import java.nio.file.CopyOption; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.junit.AfterClass; @@ -21,6 +20,7 @@ public class ELFAnalyserTest { private static File testResources = new File("build/test-resources"); private static File win32Lib = new File(testResources, "win32-x86-64.dll"); private static File linuxArmelLib = new File(testResources, "linux-armel.so"); + private static File linuxArmelNoflagLib = new File(testResources, "linux-armel-noflag.so"); private static File linuxArmhfLib = new File(testResources, "linux-armhf.so"); private static File linuxAmd64Lib = new File(testResources, "linux-amd64.so"); @@ -37,6 +37,7 @@ public static void initClass() throws IOException { extractFileFromZip(linuxArmelZip, "libjnidispatch.so", linuxArmelLib); extractFileFromZip(linuxArmhfZip, "libjnidispatch.so", linuxArmhfLib); extractFileFromZip(linuxAmd64Zip, "libjnidispatch.so", linuxAmd64Lib); + makeLinuxArmelNoflagLib(linuxArmelLib, linuxArmelNoflagLib); } @Test @@ -72,6 +73,16 @@ public void testArmel() throws IOException { assertTrue(ahfd.isArmSoftFloat()); assertFalse(ahfd.isArmHardFloat()); } + + @Test + public void testArmelNoflag() throws IOException { + ELFAnalyser ahfd = ELFAnalyser.analyse(linuxArmelNoflagLib.getAbsolutePath()); + assertTrue(ahfd.isELF()); + assertTrue(ahfd.isArm()); + assertFalse(ahfd.is64Bit()); + assertTrue(ahfd.isArmSoftFloat()); + assertFalse(ahfd.isArmHardFloat()); + } @AfterClass public static void afterClass() throws IOException { @@ -79,6 +90,7 @@ public static void afterClass() throws IOException { linuxArmhfLib.delete(); linuxArmelLib.delete(); win32Lib.delete(); + linuxArmelNoflagLib.delete(); testResources.delete(); } @@ -104,5 +116,18 @@ private static void extractFileFromZip(File zipTarget, String zipEntryName, File zip.close(); } } + + // The e_flags for elf arm binaries begin at an offset of 0x24 bytes. + // The procedure call standard is coded on the second byte. + private static void makeLinuxArmelNoflagLib(File sourceFile, File outputFile) throws IOException { + final int POS_ABI_FLOAT_BIT = (byte) 0x25; + Files.copy(sourceFile.toPath(), outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + RandomAccessFile out = new RandomAccessFile(outputFile, "rw"); + + out.seek(POS_ABI_FLOAT_BIT); + out.write(0); + + out.close(); + } }