Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!

Bug 577194

Summary: sys-libs/uclibc incorrectly defines bwsap_64(x) to take a long long, causes sys-fs/f2fs-1.6.0 fails to build on big endian systems
Product: Gentoo Linux Reporter: Anthony Basile <blueness>
Component: [OLD] Core systemAssignee: Embedded Gentoo Team <embedded>
Status: RESOLVED FIXED    
Severity: normal    
Priority: Normal    
Version: unspecified   
Hardware: All   
OS: Linux   
See Also: https://bugs.gentoo.org/show_bug.cgi?id=577186
Whiteboard:
Package list:
Runtime testing required: ---
Bug Depends on:    
Bug Blocks: 570544    

Description Anthony Basile gentoo-dev 2016-03-12 18:19:33 UTC
version 1.6.0 defines a bunch of macros in include/f2fs_fs.h to be bswap_64(x) on big endian systems.  This causes a type mismatch because uclibc defines bswap_64(x) to take a type double while f2fs-tools supplies a long long.  This is a bug in uclibc and should be fixed there.
Comment 1 Anthony Basile gentoo-dev 2016-03-12 18:27:46 UTC
Here's a little piece of code to show what fails


#include <byteswap.h>
int main() {
        long long x = 42.0;     // works on both glibc and uclibc
        //double x = 42.0;      // fails on uclibc, works on glibc
        bswap_64(x);
}


Note: this only affects f2fs-tools on big endian systems because the same marcos are define in terms of __u32 and __u64 on little endian systems.
Comment 2 Anthony Basile gentoo-dev 2016-03-12 19:13:49 UTC
If we replace the marco defined in uclibc's /usr/include/bits/byteswap-common.h with the macro from glibc using the definition of __uint64_t from <bits/types.> it fixes the issue.  Here's an inline patch just to explain the issue:

--- /usr/include/bits/byteswap-common.h.bak     2016-03-12 18:56:39.812000000 +0000
+++ /usr/include/bits/byteswap-common.h 2016-03-12 19:00:11.512000000 +0000
@@ -85,24 +85,12 @@
       | (((x) & 0x000000000000ff00ull) << 40)                                \
       | (((x) & 0x00000000000000ffull) << 56))
 
-# ifndef __bswap_non_constant_64
-#  define __bswap_non_constant_64(x) \
-     (__extension__                                                          \
-      ({ union { __extension__ unsigned long long int __ll;                  \
-                unsigned int __l[2]; } __w, __r;                             \
-        __w.__ll = (x);                                                      \
-        __r.__l[0] = __bswap_non_constant_32 (__w.__l[1]);                   \
-        __r.__l[1] = __bswap_non_constant_32 (__w.__l[0]);                   \
-        __r.__ll; }))
-# endif
-# define __bswap_64(x) \
-     (__extension__                                                          \
-      ({ __extension__ unsigned long long int __ll;                          \
-         if (__builtin_constant_p (x))                                       \
-          __ll = __bswap_constant_64 (x);                                    \
-        else                                                                 \
-          __ll = __bswap_non_constant_64 (x);                                \
-        __ll; }))
+#include <bits/types.h>
+static __inline __uint64_t
+__bswap_64 (__uint64_t __bsx)
+{
+  return __bswap_constant_64 (__bsx);
+}
 #endif
 
 #endif /* _BITS_BYTESWAP_H */
Comment 3 Anthony Basile gentoo-dev 2016-03-12 19:40:37 UTC
Looks like we should just reimport byteswap.h + byteswap-16.h from glibc.