Hi,
The following code fails to build with OE Aarch64 toolchain with current kernel headers. While ugly, the code is a reduced testcase from fuse build failure ( https://bugs.launchpad.net/linaro-oe/+bug/1087757 ) and the same fuse code compiles on all other architectures. Before I send a workaround for upstream, I'd like to know how we can end up with different definitions for int64_t when that happens on no other architectures - something wrong with the generic kernel headers?
Testcase:
#include <sys/types.h> #define __s64 int64_t #include <signal.h>
int main(int argc, char **argv) { int64_t x=4; return x; }
Failure:
/data/oe/build/tmp-eglibc/sysroots/x86_64-linux/usr/bin/aarch64-oe-linux/aarch64-oe-linux-gcc -save-temps --sysroot=/data/oe/build/tmp-eglibc/sysroots/genericarmv8 -o test test.c In file included from /data/oe/build/tmp-eglibc/sysroots/genericarmv8/usr/include/asm-generic/types.h:7:0, from /data/oe/build/tmp-eglibc/sysroots/genericarmv8/usr/include/asm/types.h:1, from /data/oe/build/tmp-eglibc/sysroots/genericarmv8/usr/include/linux/types.h:4, from /data/oe/build/tmp-eglibc/sysroots/genericarmv8/usr/include/asm/sigcontext.h:19, from /data/oe/build/tmp-eglibc/sysroots/genericarmv8/usr/include/bits/sigcontext.h:27, from /data/oe/build/tmp-eglibc/sysroots/genericarmv8/usr/include/signal.h:338, from test.c:4: /data/oe/build/tmp-eglibc/sysroots/genericarmv8/usr/include/asm-generic/int-ll64.h:29:44: error: conflicting types for 'int64_t' In file included from test.c:2:0: /data/oe/build/tmp-eglibc/sysroots/genericarmv8/usr/include/sys/types.h:197:13: note: previous declaration of 'int64_t' was here
On Wednesday 19 December 2012, Riku Voipio wrote:
Hi,
The following code fails to build with OE Aarch64 toolchain with current kernel headers. While ugly, the code is a reduced testcase from fuse build failure ( https://bugs.launchpad.net/linaro-oe/+bug/1087757 ) and the same fuse code compiles on all other architectures. Before I send a workaround for upstream, I'd like to know how we can end up with different definitions for int64_t when that happens on no other architectures - something wrong with the generic kernel headers?
I think the problem here is that user space redefines the __s64 type, which is already defined by the kernel and is in the reserved namespace.
In the kernel, most architectures nowadays use "long long" for s64, while in user space, 64 bit platforms traditionally use "long" for int64_t, hence the conflict that happens here but not on some other architectures. Normally these don't conflict, since the "long long" variant is only used for kernel interfaces.
I don't know why the fuse header does this, because it's otherwise a straight copy of include/linux/fuse.h, except that it redefines the basic integer types.
Arnd
On Thursday 27 December 2012, Arnd Bergmann wrote:
On Wednesday 19 December 2012, Riku Voipio wrote:
Hi,
The following code fails to build with OE Aarch64 toolchain with current kernel headers. While ugly, the code is a reduced testcase from fuse build failure ( https://bugs.launchpad.net/linaro-oe/+bug/1087757 ) and the same fuse code compiles on all other architectures. Before I send a workaround for upstream, I'd like to know how we can end up with different definitions for int64_t when that happens on no other architectures - something wrong with the generic kernel headers?
I think the problem here is that user space redefines the __s64 type, which is already defined by the kernel and is in the reserved namespace.
In the kernel, most architectures nowadays use "long long" for s64, while in user space, 64 bit platforms traditionally use "long" for int64_t, hence the conflict that happens here but not on some other architectures. Normally these don't conflict, since the "long long" variant is only used for kernel interfaces.
I don't know why the fuse header does this, because it's otherwise a straight copy of include/linux/fuse.h, except that it redefines the basic integer types.
It was this commit that introduced the problem in fuse back in 2008, in combination with the kernel moving to int-ll64.t for 64-bit architectures that are presumably all broken now:
fuse.git.sourceforge.net/git/gitweb.cgi?p=fuse/fuse;a=blob;f=include/fuse_kernel.h;hb=5f722fa8f6561c964fd0bd651b4602ac0f7bc3b4
On x86, this never showed up, because its bits/sigcontext.h does not include asm/sigcontext.h, which it does on arm64, causing the conflicting __s64 definition to be pulled in through linux/types.h.
I think it would be good to change the fuse private header file copy to undefine all the __u64 and related types at the end, which will make new fuse version work with the existing glibc and kernel header files on all architectures.
We might also want to look into the situation in arm64 glibc: if this is the only architecture that uses asm/sigcontext.h directly, we could change glibc to have a copy of that rather than including the kernel version, just in case some other user space tool has the same dependency, and to make existing fuse versions build. It's a bit of a hack though.
Arnd
On 27 December 2012 23:15, Arnd Bergmann arnd@arndb.de wrote:
On x86, this never showed up, because its bits/sigcontext.h does not include asm/sigcontext.h, which it does on arm64, causing the conflicting __s64 definition to be pulled in through linux/types.h.
Ok, that explains.
I think it would be good to change the fuse private header file copy to undefine all the __u64 and related types at the end, which will make new fuse version work with the existing glibc and kernel header files on all architectures.
It's not good enough - the __u64 and friends are used elsewhere in the fuse code. However just pulling in linux/types.h as done in out OE overlay is good enough:
http://git.linaro.org/gitweb?p=openembedded/meta-aarch64.git%3Ba=blob%3Bf=re...
To not break non-linux platforms, I sent to fuse-devel a slightly different patch that keeps the defines when not on linux:
http://sourceforge.net/mailarchive/forum.php?thread_name=CAAqcGH%3D-xM_a%3DR...
No response back yet,
Riku
On Monday 31 December 2012, Riku Voipio wrote:
It's not good enough - the __u64 and friends are used elsewhere in the fuse code. However just pulling in linux/types.h as done in out OE overlay is good enough:
http://git.linaro.org/gitweb?p=openembedded/meta-aarch64.git%3Ba=blob%3Bf=re...
To not break non-linux platforms, I sent to fuse-devel a slightly different patch that keeps the defines when not on linux:
http://sourceforge.net/mailarchive/forum.php?thread_name=CAAqcGH%3D-xM_a%3DR...
No response back yet,
The patch basically reverts back to the previous state from a few years ago. I think that is fine, but you seem to be missing the #include statement in the #else path.
Arnd
On 1 January 2013 16:55, Arnd Bergmann arnd@arndb.de wrote:
On Monday 31 December 2012, Riku Voipio wrote:
http://sourceforge.net/mailarchive/forum.php?thread_name=CAAqcGH%3D-xM_a%3DR...
No response back yet,
The patch basically reverts back to the previous state from a few years ago. I think that is fine, but you seem to be missing the #include statement in the #else path.
There is nothing sys/types.h that the header file needs, that's why I didn't include it in the patch. I verified that #else path still compiles by compiling fuse on freebsd.
Riku