-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Default structure alignment on i386 ("x86") is not compatible with System V ABI for Android #1079
Comments
Could it be, that you are only seeing issues on Android?
|
On Linux, MAX_ALIGNMENT will always be set to whatever the long size is, except for ARM, PPC & MIPS.
Edit: okay, so I've been mentally switching a logical OR for a logical AND in my head this entire time. |
|
Probably need to update this test, but I'm not sure if any other platforms actually do result in a size of 28 bytes: |
Currently using the latest release of JNA, 5.2.0 (some files in dist are actually 5.0.0).
Project files use jna-min.jar, and builds use libjnidispatch.so (from android-x86.jar).
JVM is whatever is included with Android Studio 3.3 for Linux.
Build machine is running Debian Stretch.
Note: I'm mainly focusing on Android , but this issue probably affects all Linux & Unix-like derivatives.Currently using NDK revision 19c.
http://java-native-access.github.io/jna/5.2.0/javadoc/com/sun/jna/Structure.html#ALIGN_GNUC
The JavaDoc implies that all GNUC platforms will have a maximum structure
alignment of 4 bytes, but this is not so. Obviously x86_64 compatibility relies
on the maximum alignment being at least as big as an 8-byte pointer, but there
are no 32/64-bit checks. For i386, the maximum should always be 4 bytes,
assuming we are only covering the types mentioned here:
https://github.com/java-native-access/jna/blob/master/www/Mappings.md
For reference, here's the SysV ABI for i386:
"System V Application Binary Interface - Intel386™ Architecture Processor Supplement"
Fourth Edition. Section 3-2 "Fundamental Types", page 28:
http://www.sco.com/developers/devspecs/abi386-4.pdf
The following test source files both compile for me with no errors, but the
equivalent structures in Java (via the JNA) would result in unaligned access:
https://gist.github.com/BugsBeGone/8bf86685b532492f877a4ed5db7ce128
Those are C11 examples, but you can test with C++11 as well by changing the
includes from "<assert.h>" & "<stddef.h>", to "<type_traits>" & "<cstddef>".
There are workarounds for this issue on both the native and the Java side. The
most straightforward is to compile with "-malign-double", however this may cause
compatibility issues with other ABI-compliant binaries. I.e. if someone wants
to create a library to be accessed via JNA, but that also links against any
default-compiled prebuilt binaries, it may not work if the binaries have any
exported structs containing doubles.
The second option is to use "__attribute__((aligned(8))" on all double members
of all structs. This is ugly, and also requires a lot of messing around with
macros if your native code is targeting architectures other than i386. Even
better if the source is not yours, now you'll have another fork to maintain.
The third and final option is to override Structure.getNativeAlignment(). This
is probably the least invasive way to handle the issue, but means littering your
library mappings with overrides for each and every struct containing a double.
Also, it depends on various calls to the JNA Platform class, specifically the
methods isIntel() and is64Bit(). If the JNA project has any plans to refactor
some of those methods names in the future, it'll make for a pretty nasty
breaking change to anyone who needs this workaround:
https://github.com/java-native-access/jna/blob/master/TODO#L88
I'm working on a fix at the moment, just wanted to report this sooner rather
than later, in case anyone else is racking their brains trying to get stuff to
work for i386.
The text was updated successfully, but these errors were encountered: